对象适合如何与画布元素一起使用?

2022-01-17 00:00:00 html css html5-canvas object-fit

我一直找不到任何文件来告诉我一种或另一种方式.

我可以在画布元素上使用适合对象的封面吗?我进行了一些实验,但它的行为与预期不符.

谁能给我一个明确的答案?

解决方案

object-fit1只有有比率变化(失真)并且仅适用于 replaced 元素(canvas 是被替换元素)

这是一个基本的例子:

var canvas = document.querySelectorAll("canvas");for (var i = 0; i < canvas.length; i++) {ctx = canvas[i].getContext("2d");ctx.fillRect(50, 50, 100, 100);}

canvas {宽度:100px;高度:250px;边框:1px 纯红色;显示:块;}.盒子 {显示:内联块;边框:2px 纯绿色}

<div class="box"><canvas width="200" height="200"></canvas></div><div 类="盒子"><canvas width="200" height="200" style="object-fit:contain;"></canvas></div><div 类="盒子"><canvas width="200" height="200" style="object-fit:cover;"></canvas></div>

如您所见,我将画布的高度/宽度定义为 200x200(1:1 比例)然后我使用 CSS 更改它,因此我打破了比例(我们不再有正方形) 然后 object-fit 将更正此问题.

了解使用属性设置宽度/高度和使用 CSS 之间的区别的相关问题:Why box-sizing is not working with width画布元素上的/height 属性?


1来自规范 我们可以清楚地看到所有的值(除了默认的一个fill)都将尝试保持比率:

<块引用>

包含

替换内容的大小保持其纵横比,同时适合元素的内容框:其具体对象大小被解析为对元素使用的宽度和高度的包含约束.

封面

被替换的内容的大小保持其纵横比,同时填充元素的整个内容框:它的具体对象大小被解析为对元素使用的宽度和高度的覆盖约束.

没有

被替换的内容没有调整大小以适应元素的内容框:使用没有指定大小的默认大小算法确定对象的具体对象大小,默认对象大小等于被替换元素的使用宽度和高度.

none 值有点棘手,但它基本上意味着保持固有的默认图像大小而不像 containcover

var canvas = document.querySelectorAll("canvas");for (var i = 0; i < canvas.length; i++) {ctx = canvas[i].getContext("2d");ctx.fillRect(50, 50, 100, 100);}

.box canvas {边框:1px 纯红色;显示:块;对象拟合:无;}.盒子 {显示:内联块;边框:2px 纯绿色}

<canvas width="200" height="200"></canvas><div 类="盒子"><canvas width="200" height="200" style="width:100px;height:200px;"></canvas></div><div 类="盒子"><canvas width="200" height="200" style="height:50px;width:200px;"></canvas></div>

相关:CSS object-fit: contains;在布局中保持原始图像宽度

I have been unable to find any documentation to tell me one way or another.

Am I able to use object-fit cover on a canvas elements? I have done some experimenting and it is not behaving as expected.

Can somebody give me a definitive answer?

解决方案

object-fit1 will only have an effect when there is a ratio change (a distortion) and applies to only replaced element (canvas is a replaced element)

Here is a basic example:

var canvas = document.querySelectorAll("canvas");
for (var i = 0; i < canvas.length; i++) {
  ctx = canvas[i].getContext("2d");
  ctx.fillRect(50, 50, 100, 100);
}

canvas {
  width: 100px;
  height: 250px;
  border: 1px solid red;
  display: block;
}

.box {
  display: inline-block;
  border: 2px solid green
}

<div class="box">
  <canvas width="200" height="200"></canvas>
</div>
<div class="box">
  <canvas width="200" height="200" style="object-fit:contain;"></canvas>
</div>
<div class="box">
  <canvas width="200" height="200" style="object-fit:cover;"></canvas>
</div>

As you can see I defined a height/width for the canvas to be 200x200 (1:1 ratio) then I change this using CSS thus I break the ratio (we no more have a square) then object-fit will correct this.

A related question to understand the difference between setting width/height using attribute and using CSS: Why box-sizing is not working with width/height attribute on canvas element?


1From the specification we can clearly read that all the values (expect the default one fill) will try to maintain the ratio:

contain

The replaced content is sized to maintain its aspect ratio while fitting within the element’s content box: its concrete object size is resolved as a contain constraint against the element’s used width and height.

cover

The replaced content is sized to maintain its aspect ratio while filling the element’s entire content box: its concrete object size is resolved as a cover constraint against the element’s used width and height.

none

The replaced content is not resized to fit inside the element’s content box: determine the object’s concrete object size using the default sizing algorithm with no specified size, and a default object size equal to the replaced element’s used width and height.

The none value is a bit tricky but it basically mean keep the intrinsic default image size without scaling like contain or cover

var canvas = document.querySelectorAll("canvas");
for (var i = 0; i < canvas.length; i++) {
  ctx = canvas[i].getContext("2d");
  ctx.fillRect(50, 50, 100, 100);
}

.box canvas {
  border: 1px solid red;
  display: block;
  object-fit:none;
}

.box {
  display: inline-block;
  border: 2px solid green
}

<canvas width="200" height="200"></canvas>
<div class="box">
  <canvas width="200" height="200" style="width:100px;height:200px;"></canvas>
</div>
<div class="box">
  <canvas width="200" height="200" style="height:50px;width:200px;"></canvas>
</div>

Related: CSS object-fit: contain; is keeping original image width in layout

相关文章