简体   繁体   English

画布元素溢出其容器 div

[英]Canvas element spilling out past its container div

I am trying to make a canvas element fit to its container div using Javascript rather than CSS, because this way it doesn't stretch anything drawn inside the canvas.我正在尝试使用 Javascript 而不是 CSS 使画布元素适合其容器 div,因为这样它不会拉伸画布内绘制的任何内容。

Currently, if I refresh the page, sometimes the canvas element fits perfectly inside.目前,如果我刷新页面,有时画布元素完全适合里面。 Other times, when I refresh, its width is greater than the container, and its height is lesser than the container.其他时候,当我刷新时,它的宽度大于容器,高度小于容器。 I have no idea why I get this different behavior upon refreshing the page, even without resizing the window.我不知道为什么在刷新页面时会出现这种不同的行为,即使没有调整窗口大小也是如此。

Here's how I set up the canvas size:这是我设置画布大小的方法:

const ctxX = canvasParent.offsetWidth - 4;
const ctxY = canvasParent.offsetHeight - 4;
canvasEl.width = ctxX;
canvasEl.height = ctxY;
const ctx = canvasEl.getContext("2d");

I read that setting size like this only works if the container is positioned relative, so this is the CSS for the container:我读到这样的设置大小仅在容器相对定位时才有效,所以这是容器的 CSS:

display: block;
position: relative;
height: 60%;
margin-top: 2%;
border: 2px solid v.$border;

The root cause is that offsetHeight and offsetWidth values are rounded and setting canvas dimensions to them will usually result in an inexact fit, either resulting in under or over-flow of width or height.根本原因是offsetHeightoffsetWidth值是四舍五入的,并且为它们设置画布尺寸通常会导致不精确的拟合,导致宽度或高度的不足或溢出。 I am not ruling out other causes due to calculations performed by layout engines, but this cause is crucial.由于布局引擎执行的计算,我不排除其他原因,但这个原因至关重要。

One solution is to use element.getBoundingClientRect to get the dimensions of the parent ( div ) element exactly, take the integers below height and width values and use them to set the dimensions of both the canvas and its parent element.一个解决方案是使用element.getBoundingClientRect获取父(的尺寸div )元件完全相同,采取以下高度和宽度值的整数,并且使用它们来设置画布和它的父元素两者的尺寸。 This could result in the div element being up to 1px less than percentage value conversions to CSS pixel width and height, but that's inevitable given canvas dimension attributes take integer values.这可能导致div元素最多比转换为 CSS 像素宽度和高度的百分比值少1px ,但鉴于画布尺寸属性采用整数值,这是不可避免的。

Here's an example demonstrating this specific technique with warnings: changing canvas dimensions due to resize will destroy existing canvas content, and a resize handler would need to remove style settings for width and height on the canvas parent to find out what the resized dimensions would be.这是一个带有警告的示例,演示了此特定技术:由于调整大小而更改画布尺寸将破坏现有的画布内容,并且调整大小处理程序需要删除画布父级上宽度和高度的style设置,以找出调整后的尺寸。

Note: relative positioning is not required and not included below.注意:相对定位不是必需的,不包括在下面。

 "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; }
 <div id="canvasParent"><canvas id="canvasEl"></canvas></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM