< canvas>的纵横比行为 - 内部尺寸和元件尺寸 [英] Aspect ratio behaviour of <canvas> - internal dimensions and element size

查看:220
本文介绍了< canvas>的纵横比行为 - 内部尺寸和元件尺寸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如你所知,HTML5中的< canvas> 元素具有内部大小,通过 elm.width elm.height 其中 elm 是DOM元素。



DOM本身中的元素可以有不同的框大小,通过CSS设置。



当两者不同时,浏览器会自动延伸< canvas> 以适合内容框大小。这个行为可以调整没有额外的元素?是否可以设置为 background-size:contains ,以便保持内部画布大小的高宽比?



据我所知,没有标准的方法来做到这一点,所以webkit特定的黑客也被接受。但是如果没有办法做什么,什么是最优雅的做一个包装元素(我们都知道,我们可以包装的元素,通过JS调整大小调整)?



我可以想到的一个解决方案是使用 background-size:contains background :element()但是这是Firefox特有的,我正在寻找一个WebKit解决方案。



箱和帆布内部尺寸影响性能?如果是,多少?

解决方案

是的,有一个, issue#2 问题#3



作为备用,大小可以手动计算。这可以与drawImage一起使用。如果drawImage不是一个选项,它将需要一个包含溢出设置为隐藏的包装器元素。



示例



下面的两个canvas都使用默认的位图大小为300x150。



通常这会使圆形成一个椭圆形。然而,右边的画布将使用新的 object-fit 规则集为 cover ,位图将被缩放考虑纵横比,所以我们仍然得到一个圆,但当然我们也会松动一些边缘(以及锐度)。



 

 #c1,#c2 {width:300px; height:300px; }#c2 {-o-object-fit:cover; / * for Opera Mini * / object-fit:cover; / * W3C版本(包括FF / webkit)* /}  

 < canvas id =c1>< / canvas>< canvas id =c2>< / canvas>  


As you know, the <canvas> element in HTML5 has an internal size, set via elm.width and elm.height where elm is the DOM element.

The element within the DOM itself can have a different box size, set via CSS.

When the two differ, the browser automatically stretches the contents of the <canvas> to fit the content box size. Can this behaviour be adjusted without an extra element? Can it be set to something like background-size: contain so that it keeps the aspect ratio of the inner canvas size?

As far as I know, there is no standard way to do this, so webkit-specific hacks are also accepted. But if there is no way to do it at all, what's the most elegant to do it with a wrapper element (we all know that we can wrap the element and adjust it via JS on resize)?

The one solution I can think of is actually using background-size: contain and background: element() but this is Firefox-specific, and I am looking for a WebKit solution.

Side question, can a difference in element box and canvas internal sizes impact performance? If so, how much?

解决方案

Yes, there is a new CSS property called object-fit. This allow you to set the content to for example cover which will then force aspect ratio to be kept at the same time as filling the DOM box.

Simply add this rule to the canvas element:

canvas {
  object-fit: cover;
  }

Support

(Updated) It is (partially) supported in Safari, but not in IE. Opera Mini needs a -o- prefix.

Does not seem to work with WebGL canvas (or video) in Chrome likely related to these issues: issue #1, issue #2, issue #3.

As a fallback the size can be calculated manually. This can be used with drawImage. If drawImage is not an option it will require a wrapper element with overflow set to hidden to work.

Example

Both canvas' below are using the default bitmap size of 300x150. They are then stretched by defining CSS size 300x300 pixels.

Normally this would make the circle an oval. However, the canvas on the right will use the new object-fit rule set to cover, the bitmap will be scaled considering aspect ratio so we still get a circle, but of course we'll also loose some of the edges (as well as sharpness).

var ctx1 = document.getElementById("c1").getContext("2d");
var ctx2 = document.getElementById("c2").getContext("2d");

drawCircle(ctx1, 150, 75, 70);   // draw circle to stretched canvas 1
drawCircle(ctx2, 150, 75, 70);   // draw circle to object-fit/cover canvas 2

function drawCircle(ctx, x, y, r) {
  ctx.moveTo(x + r, y);
  ctx.arc(x, y, 70, 0 , 6.28);
  ctx.closePath();
  ctx.stroke();
}

#c1, #c2 {
    width:300px;
    height:300px;
    }
#c2 {
    -o-object-fit: cover;  /* for Opera Mini */
    object-fit: cover;     /* W3C version (incl. FF/webkit) */
    }

<canvas id="c1"></canvas><canvas id="c2"></canvas>

这篇关于&lt; canvas&gt;的纵横比行为 - 内部尺寸和元件尺寸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆