Javascript 快速调整大型画布元素的大小

Javascript 快速调整大型画布元素的大小,javascript,html5-canvas,Javascript,Html5 Canvas,我制作了一个窗口大小的画布元素,并用随机值填充它(这样我就可以很容易地看到它的更新)。当窗口使用时,它会调整大小,而且速度相当慢。这就是事情的发展方向,还是有更好的方法 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Window Sized Canvas</title> <!-- <link hr

我制作了一个窗口大小的画布元素,并用随机值填充它(这样我就可以很容易地看到它的更新)。当窗口使用
时,它会调整大小,而且速度相当慢。这就是事情的发展方向,还是有更好的方法

<!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>

用精确确定的像素值重新绘制画布会很慢,几乎不管发生什么。一个大小合适的屏幕有很多像素,盯着每一个像素并决定如何用JavaScript绘制它需要时间

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

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


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

此方法比您当前的方法快得多

不要每次调整大小都重新创建随机图案:

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

  • 然后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>
    
    
    窗口大小的帆布
    正文{margin:0;padding:0;}
    画布{显示:块;}
    您的浏览器不支持画布标记
    var canvas=document.getElementById(“canvas”);
    var ctx=canvas.getContext(“2d”);
    var jCanvas;
    BufferCanvas();
    updateCanvas();
    函数updateCanvas(){
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    drawImage(jCanvas,0,0,jCanvas.width,jCanvas.height,0,0,canvas.width,canvas.height);
    }
    函数BufferCanvas(){
    jCanvas=document.createElement(“画布”);
    var jc2D=jCanvas.getContext(“2d”);
    jCanvas.width=window.innerWidth;
    jCanvas.height=window.innerHeight;
    var jcW=1920;//或您的最大窗口大小
    var jcH=1080;
    
    var jcWH4=(jcW*jcH)感谢您的建议,但如果是这样的话,我更喜欢慢一点。即使这意味着在填充像素时进行几次扫描(填充交替线,直到所有像素都被填充)。谢谢,这将适用于我想要制作的一些东西。其他的应该随窗口缩放,所以我想我会用交替的像素线填充这些东西(直到所有像素线都被填充)。
    <!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>