0

我制作了一个窗口大小的画布元素并用随机值填充它(这样我可以很容易地看到它更新)。它会在窗口使用时调整大小,<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);
}
...
4

2 回答 2

2

这种方法比您当前的方法快得多!

而不是每次调整大小都重新创建随机模式:

  1. 启动时,在隐藏的画布(缓冲区)上保存一次随机模式。

  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>
于 2013-03-01T23:32:15.787 回答
0

无论如何,用精确确定的像素值重绘画布会很慢。一个大小合适的屏幕有很多像素,需要花时间盯着每个像素,然后决定如何用 JavaScript 绘制它。

可能最简单的做法就是使用 CSS 来放大和缩小画布。这是相当快的,因为它依赖于计算机上强大的内置图像缩放功能。你不会每次都得到新的重新计算,但只要这不重要,它就会很快。这是 this 的一个实现。画布上的“高度”和“宽度”属性会影响渲染区域的大小(以像素为单位),而样式属性“高度”和“宽度”会影响画布占用的区域,而不会修改您必须绘制的像素数和。

详细说明:如果您在不重绘任何内容的情况下增加画布的基于属性的大小,您会注意到之前的图像将保持不变;所发生的只是你在画布上添加了一些空白区域。但是,如果您只是更改样式,画布将变为您告诉它的大小,但它可能看起来有颗粒感,即使画布上的所有内容理论上都可以在该大小下保持高分辨率。

这确实会在您正在处理的图像中产生一些奇怪的伪影,但没有简单的方法可以解决这个问题。您可以做的一件事是默认情况下在画布大小发生变化时使用 CSS,但在调整大小完成后,使用新的更高分辨率模式重绘。如果您决定走这条路并需要任何帮助,请告诉我。

于 2013-03-01T22:53:12.363 回答