Canvas 元素溢出其容器 div
Canvas element spilling out past its container div
我正在尝试使用 Javascript 而不是 CSS 使 canvas 元素适合其容器 div,因为这样它不会拉伸绘制的任何内容在 canvas.
里面
目前,如果我刷新页面,有时 canvas 元素完全适合内部。其他时候,当我刷新时,它的宽度大于容器,而它的高度小于容器。我不知道为什么我在刷新页面时会出现这种不同的行为,即使没有调整 window.
的大小
以下是我设置 canvas 尺寸的方法:
const ctxX = canvasParent.offsetWidth - 4;
const ctxY = canvasParent.offsetHeight - 4;
canvasEl.width = ctxX;
canvasEl.height = ctxY;
const ctx = canvasEl.getContext("2d");
我读到这样的设置大小仅在容器相对定位时才有效,所以这是容器的 CSS:
display: block;
position: relative;
height: 60%;
margin-top: 2%;
border: 2px solid v.$border;
根本原因是 offsetHeight
和 offsetWidth
值被四舍五入,并且为它们设置 canvas 尺寸通常会导致不精确拟合,导致不足或 over-flow 的宽度或高度。由于布局引擎执行的计算,我不排除其他原因,但这个原因至关重要。
一种解决方案是使用 element.getBoundingClientRect
准确获取 parent (div
) 元素的尺寸,取低于高度和宽度值的整数并使用它们设置 canvas 及其 parent 元素的维度。这可能导致 div
元素最多 1px
小于 CSS 像素宽度和高度的百分比值转换,但鉴于 canvas 尺寸属性采用整数值,这是不可避免的。
下面是一个演示此特定技术并带有警告的示例:由于调整大小而更改 canvas 尺寸将破坏现有的 canvas 内容,并且调整大小处理程序需要删除 style
设置canvas parent 上的宽度和高度,以了解调整后的尺寸。
注意:相对定位不是必需的,不包括在下面。
"use strict";
let rect = canvasParent.getBoundingClientRect();
const ctxX = Math.floor(rect.width -4);
const ctxY = Math.floor(rect.height -4);
canvasEl.width = ctxX;
canvasEl.height = ctxY;
canvasParent.style.width = ctxX + 'px';
canvasParent.style.height = ctxY + 'px';
const ctx = canvasEl.getContext("2d");
#canvasParent {
height: 60%;
margin-top: 2%;
border: 2px solid orange;
box-sizing: content-box;
}
canvas {
background-color: forestgreen;
}
/* to see margins: */
body { background-color: grey; }
.outer { height: 80vh; background-color: #ddd; }
<div class="outer"> <!-- outer div -->
<div id="canvasParent"><canvas id="canvasEl"></canvas></div>
</div>
更新
在代码片段中,canvas 容器的外部容器需要具有固有高度,从中计算 #canvasParent
的百分比 height
值。
百分比 垂直 margin
值在 CSS 中很奇怪,因为它们指的是 水平 包含块的宽度百分比(参考 MDN and this question)。更糟糕的是,如果容器中的 child 个元素以百分比为单位有上边距,并且 而不是 前面是其容器块中的内容,则生成的容器宽度当遇到 child 元素时被视为零 - 导致 child.
上没有上边距
这就是 运行 代码段未显示应用于 #containerEl
的任何上边距的原因。如果您在 .outer
的开头放置一些文本,#containerEl
突然获得相对于插入的文本(未在代码段中显示)的上边距。
我的结论:虽然这可能不会影响您的项目,但不要在没有充分理由的情况下对垂直边距使用百分比单位:-)
我正在尝试使用 Javascript 而不是 CSS 使 canvas 元素适合其容器 div,因为这样它不会拉伸绘制的任何内容在 canvas.
里面目前,如果我刷新页面,有时 canvas 元素完全适合内部。其他时候,当我刷新时,它的宽度大于容器,而它的高度小于容器。我不知道为什么我在刷新页面时会出现这种不同的行为,即使没有调整 window.
的大小以下是我设置 canvas 尺寸的方法:
const ctxX = canvasParent.offsetWidth - 4;
const ctxY = canvasParent.offsetHeight - 4;
canvasEl.width = ctxX;
canvasEl.height = ctxY;
const ctx = canvasEl.getContext("2d");
我读到这样的设置大小仅在容器相对定位时才有效,所以这是容器的 CSS:
display: block;
position: relative;
height: 60%;
margin-top: 2%;
border: 2px solid v.$border;
根本原因是 offsetHeight
和 offsetWidth
值被四舍五入,并且为它们设置 canvas 尺寸通常会导致不精确拟合,导致不足或 over-flow 的宽度或高度。由于布局引擎执行的计算,我不排除其他原因,但这个原因至关重要。
一种解决方案是使用 element.getBoundingClientRect
准确获取 parent (div
) 元素的尺寸,取低于高度和宽度值的整数并使用它们设置 canvas 及其 parent 元素的维度。这可能导致 div
元素最多 1px
小于 CSS 像素宽度和高度的百分比值转换,但鉴于 canvas 尺寸属性采用整数值,这是不可避免的。
下面是一个演示此特定技术并带有警告的示例:由于调整大小而更改 canvas 尺寸将破坏现有的 canvas 内容,并且调整大小处理程序需要删除 style
设置canvas parent 上的宽度和高度,以了解调整后的尺寸。
注意:相对定位不是必需的,不包括在下面。
"use strict";
let rect = canvasParent.getBoundingClientRect();
const ctxX = Math.floor(rect.width -4);
const ctxY = Math.floor(rect.height -4);
canvasEl.width = ctxX;
canvasEl.height = ctxY;
canvasParent.style.width = ctxX + 'px';
canvasParent.style.height = ctxY + 'px';
const ctx = canvasEl.getContext("2d");
#canvasParent {
height: 60%;
margin-top: 2%;
border: 2px solid orange;
box-sizing: content-box;
}
canvas {
background-color: forestgreen;
}
/* to see margins: */
body { background-color: grey; }
.outer { height: 80vh; background-color: #ddd; }
<div class="outer"> <!-- outer div -->
<div id="canvasParent"><canvas id="canvasEl"></canvas></div>
</div>
更新
在代码片段中,canvas 容器的外部容器需要具有固有高度,从中计算
#canvasParent
的百分比height
值。百分比 垂直
上没有上边距margin
值在 CSS 中很奇怪,因为它们指的是 水平 包含块的宽度百分比(参考 MDN and this question)。更糟糕的是,如果容器中的 child 个元素以百分比为单位有上边距,并且 而不是 前面是其容器块中的内容,则生成的容器宽度当遇到 child 元素时被视为零 - 导致 child.这就是 运行 代码段未显示应用于
#containerEl
的任何上边距的原因。如果您在.outer
的开头放置一些文本,#containerEl
突然获得相对于插入的文本(未在代码段中显示)的上边距。我的结论:虽然这可能不会影响您的项目,但不要在没有充分理由的情况下对垂直边距使用百分比单位:-)