在我的应用程序中,我有一个div,其中包含一个显示图像的canvas元素。该应用程序还具有一个边栏,可以通过单击按钮将其隐藏,其他所有元素都应调整自身大小以占用剩余的空白空间。
这对于div和其他将宽度/高度设置为百分比的元素非常有效,但对于canvas元素则无效。
这是我的div:
<div id="background-img" class="image-div"></div>
.image-div {
height: inherit;
width: 100%;
margin-top: 25px;
position: absolute;
}
高度最初为305px,但在隐藏侧边栏时变为375px。
这是画布创建代码:
const imgDiv = document.getElementById('background-img');
if (imgDiv) {
const blob = new Blob([svg], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const canvas = document.createElement('canvas');
canvas.className = 'canvas-background';
canvas.id = 'canvas-id';
const ctx = canvas.getContext('2d');
canvas.width = imgDiv.clientWidth;
canvas.height = imgDiv.clientHeight;
const img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = url;
imgDiv.appendChild(canvas);
}
并且画布在任何地方都没有定义其他的CSS。
当父级更改画布的宽度和高度时,如何使画布自动调整大小(我尝试像在chrome中那样放大/缩小页面时也要使此调整大小有效例如,某些可与div或img元素一起使用的东西。
答案 0 :(得分:1)
问题是还没有一个好的方法来做到这一点。本能地在元素上寻找resize
事件。但这只能应用于explained here on MDN的window
。
在进行了一些研究并查看了其他线程之后,我发现了几个可供您考虑的选项。
连续循环
使用递归函数绘制图像,该函数还将在每次绘制imgDiv
时检查其宽度和高度。
CSS:
canvas {
width: 100%;
height: 100%;
}
JS:
function draw(ctx, imgDiv, img) {
ctx.canvas.width = imgDiv.offsetWidth;
ctx.canvas.height = imgDiv.offsetheight;
ctx.drawImage(img, 0, 0);
requestAnimationFrame(() => {
draw(ctx, imgDiv, img);
});
}
img.onload = function() {
draw(ctx, imgDiv, img);
};
此选项的好处是可以一直检查,但是我认为它在性能方面可能很繁琐。 requestAnimationFrame
仅在帧速率速度允许的情况下才通过触发功能来提高性能。所以平均每秒大约60次。
ResizeObserver
(警告:实验技术)
这是我还没有见过的那个。 ResizeObserver
是新的,属于IntersectionObserver
,PerformanceObserver
和MutationObserver
的家族。顾名思义,它可以观察到更改后的元素的大小,并在检测到更改时触发回调。
它是这样的:
const observer = new ResizeObserver(entries => {
entries.forEach(entry => {
// Update the canvas dimensions.
});
});
// Observer the image-div when it resizes.
observer.observe(imgDiv);
由于它是实验性的,因此我不建议您使用它,尽管它完全适合您的情况。 Caniuse上有更多关于浏览器对此API的支持,以及Alligator.io上有关如何使用它的文章。
在resize
上使用window
事件
这只会捕获更改窗口或文档的宽度的情况。而且,如果您打开和关闭侧边栏,则需要进行一些额外的修改。
window.addEventListener('resize', (event) => {
requestAnimationFrame(() => {
// Update the canvas dimensions.
});
});
建议在此处使用requestAnimationFrame
,因为resize
事件将在每个像素上调用,并且会降低性能。
编辑:
看来Artyomska已经解决了这个问题。而且,尽管该问题已解决,但我仍然想分享我的研究,以防将来对该线程进行查询。