我制作了一个窗口大小的画布元素并用随机值填充它(以便我可以很容易地看到它更新)。当窗口使用<body onresize="updateCanvas();">
时它会调整大小并且速度非常慢。是这样的,或者有更好的方法吗?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window Sized Canvas</title>
<!-- <link href="style.css" rel="stylesheet" type="text/css"/>
Relevant style below: -->
<style type="text/css">
body {margin:0; padding:0;}
canvas {display:block;}
</style>
</head>
<body onresize="updateCanvas();">
<canvas id="hCanvas">Your browser does not support the canvas tag</canvas>
<script type="text/javascript">
var jCanvas = document.getElementById("hCanvas");
var jc2D = jCanvas.getContext("2d");
updateCanvas();
function updateCanvas() {
jCanvas.width = window.innerWidth;
jCanvas.height = window.innerHeight;
var jcW = jCanvas.width;
var jcH = jCanvas.height;
var jcWH4 = (jcW*jcH)<<2;
var jcImageData = jc2D.createImageData(jcW, jcH);
for (i = 0; i < jcWH4; i += 4) {
jcImageData.data[i] = (Math.random()*255)|0;
jcImageData.data[i+1] = (Math.random()*255)|0;
jcImageData.data[i+2] = (Math.random()*255)|0;
jcImageData.data[i+3] = 255;
}
jc2D.putImageData(jcImageData, 0, 0);
}
</script>
</body>
</html>
修改:我找到了一些很好的代码来限制onresize()
。我将发布与上述不同的内容:
...
<body onresize="resizeTimer();">
...
var resizeDelay;
function resizeTimer() {
clearTimeout(resizeDelay);
resizeDelay = setTimeout("updateCanvas()", 200);
}
...
答案 0 :(得分:2)
此方法比您当前的方法更快!
不是每次调整大小都重新创建随机模式:
启动时,将随机模式保存一次保存在隐藏的画布(缓冲区)上。
然后onresize可以将缓冲区绘制到调整大小的窗口上。
以下是代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window Sized Canvas</title>
<!-- <link href="style.css" rel="stylesheet" type="text/css"/>
Relevant style below: -->
<style type="text/css">
body {margin:0; padding:0;}
canvas {display:block;}
</style>
</head>
<body onresize="updateCanvas();">
<canvas id="canvas">Your browser does not support the canvas tag</canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var jCanvas;
BufferCanvas();
updateCanvas();
function updateCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.drawImage(jCanvas,0,0,jCanvas.width,jCanvas.height,0,0,canvas.width,canvas.height);
}
function BufferCanvas() {
jCanvas = document.createElement("canvas");
var jc2D = jCanvas.getContext("2d");
jCanvas.width = window.innerWidth;
jCanvas.height = window.innerHeight;
var jcW = 1920; // or your max window size
var jcH = 1080;
var jcWH4 = (jcW*jcH)<<2;
var jcImageData = jc2D.createImageData(jcW, jcH);
for (i = 0; i < jcWH4; i += 4) {
jcImageData.data[i] = (Math.random()*255)|0;
jcImageData.data[i+1] = (Math.random()*255)|0;
jcImageData.data[i+2] = (Math.random()*255)|0;
jcImageData.data[i+3] = 255;
}
jc2D.putImageData(jcImageData, 0, 0);
}
</script>
</body>
</html>
答案 1 :(得分:0)
使用精确确定的像素值重绘画布将很慢,几乎无论如何。一个体面的大小屏幕有很多像素,它需要时间来盯着每个像素,并决定如何在JavaScript中绘制它。
可能最简单的事情就是使用CSS来上下缩放画布。这是非常快的,因为它依赖于计算机上强大的内置图像缩放功能。你不会每次都重新计算,但只要不重要,它就会很快。 Here's an implementation of this。画布上的属性“height”和“width”会影响渲染区域的大小(以像素为单位),而 style 属性“height”和“width”会影响画布占用的区域而不会修改你必须用的像素数。
详细说明:如果在不重绘任何内容的情况下增加画布的基于属性的大小,您会注意到前一个图像将保持不变;所有发生的事情是你在画布上添加了一些空白区域。但是,如果你只改变了样式,画布将变成你告诉它变成的大小,但它看起来可能看起来有颗粒感,即使画布上的所有内容理论上都可以达到那么大的高分辨率。
这会在您正在操作的图像中创建一些奇怪的工件,但这并不是简单的方法。你可以做的一件事是默认情况下,只要画布的大小发生变化就会使用CSS,但是在调整大小之后,重新绘制一个新的更高res模式。如果你决定走这条路并需要任何帮助,请告诉我。