如何自动缩放HTML5 <canvas>元素以适应页面?
例如,我可以得到一个<div>通过设置高度和宽度属性为100%缩放,但一个<canvas>不会缩放,会吗?
如何自动缩放HTML5 <canvas>元素以适应页面?
例如,我可以得到一个<div>通过设置高度和宽度属性为100%缩放,但一个<canvas>不会缩放,会吗?
当前回答
设置初始大小。
const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
更新窗口大小调整。
function windowResize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
window.addEventListener('resize', windowResize);
其他回答
如果你的div完全填满了网页,那么你可以填充这个div,这样就有一个画布来填充这个div。
你可能会发现这很有趣,因为你可能需要使用css来使用百分比,但是,这取决于你使用的浏览器,以及它在多大程度上符合规范: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#the-canvas-element
画布的内在尺寸 元素的大小相等 用数字来坐标空间 用CSS像素解释。然而, 元素的大小可以任意设置 通过样式表。在呈现期间, 图像按比例缩放以适应此布局 大小。
您可能需要获取div的offsetWidth和height,或者获取窗口的高度/宽度并将其设置为像素值。
2022的答案
在2022年,检查元素是否调整大小的推荐方法是使用ResizeObserver
const observer = new ResizeObserver(myResizeTheCanvasFn);
observer.observe(someCanvasElement);
它比窗户好。addEventListener('resize', myResizeTheCanvasFn)或onresize = myResizeTheCanvasFn,因为它处理画布调整大小的每一种情况,即使它与窗口调整大小无关。
同样,使用window也没有意义。innerWidth window.innerHeight。你想要画布本身的大小,而不是窗口的大小。这样,无论你把画布放在哪里,你都会得到正确的大小,而不必重写你的尺寸代码。
至于用画布填满窗户
html, body {
height: 100%;
}
canvas {
width: 100%;
height: 100%;
display: block; /* this is IMPORTANT! */
}
你需要display: block的原因是因为默认情况下画布是内联的,这意味着它在结尾包含额外的空间。没有显示:块你将得到一个滚动条。许多人通过在文档正文中添加overflow: hidden来修复滚动条问题,但这只是隐藏了画布的CSS设置不正确的事实。最好是修复bug(将canvas设置为display: block而不是使用overflow: hidden隐藏bug)
完整的示例
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const observer = new ResizeObserver((entries) => { canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; }); observer.observe(canvas) // not import but draw something just to showcase const hsla = (h, s, l, a) => `hsla(${h * 360}, ${s * 100}%, ${l * 100}%, ${a})`; function render(time) { const {width, height} = canvas; ctx.clearRect(0, 0, width, height); ctx.save(); ctx.translate(width / 2, height / 2); ctx.rotate(time * 0.0001); const range = Math.max(width, height) * 0.8; const size = 64 + Math.sin(time * 0.001) * 50; for (let i = 0; i < range; i += size) { ctx.fillStyle = hsla(i / range * 0.3 + time * 0.0001, 1, 0.5, 1); ctx.fillRect( i, -range, size, range * 2); ctx.fillRect(-i, -range, size, range * 2); } ctx.restore(); requestAnimationFrame(render) } requestAnimationFrame(render) html, body { height: 100%; margin: 0; } canvas { width: 100%; height: 100%; display: block; } <canvas></canvas>
注意:还有其他与调整画布大小相关的问题。特别是如果你想处理不同的devicePixelRatio设置。请参阅本文了解更多信息。
除非你想让画布自动提升你的图像数据(这就是James Black的答案,但它看起来不漂亮),你必须自己调整它的大小并重新绘制图像。画布居中
我使用的是sketch.js,所以在我为画布运行init命令后,我用jquery改变宽度和高度。它将维度基于父元素。
$ (' # DrawCanvas ') .sketch () .attr(“高度”,$ (' # DrawCanvas ') .parent () .height ()) .attr(“宽度”,$ (' # DrawCanvas ') .parent () .width ());
一个纯CSS的方法添加到解决方案@jerseyboy上面。 适用于Firefox (v29测试),Chrome (v34测试)和Internet Explorer (v11测试)。
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
canvas {
background-color: #ccc;
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
}
</script>
</body>
</html>
链接到示例:http://temporaer.net/open/so/140502_canvas-fit-to-window.html
但要小心,正如@jerseyboy在他的评论中所说:
用CSS重新缩放画布是很麻烦的。至少在Chrome和 Safari中,鼠标/触摸事件的位置不会1:1对应 Canvas像素位置,你需要变换坐标 系统。