Reputation: 5894
I made a window sized canvas element and filled it with random values (so that I can easily see it update). It resizes when the window does using <body onresize="updateCanvas();">
and it is pretty slow. Is that just how it is going to be or is there a better way to do this?
<!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>
Edit: I found some nice code for limiting onresize()
. I'll just post what is different from above:
...
<body onresize="resizeTimer();">
...
var resizeDelay;
function resizeTimer() {
clearTimeout(resizeDelay);
resizeDelay = setTimeout("updateCanvas()", 200);
}
...
Upvotes: 0
Views: 407
Reputation: 105015
This method is WAY faster than your current method!
Instead of recreating your random pattern every resize:
On startup, save your random pattern once on a hidden canvas (a buffer).
Then onresize can just draw that buffer onto your resized window.
Here is the code:
<!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>
Upvotes: 2
Reputation: 3815
Redrawing the canvas with precisely determined pixel values will be slow, pretty much no matter what. A decent sized screen has many pixels, and it takes time to stare at each one and decide how you want to draw it in JavaScript.
Probably the easiest thing to do would just use CSS to scale the canvas up and down. This is quite fast, since it relies on powerful built in image scaling abilities on the computer. You don't get fresh recalculations each time, but so long as that's not important it will be pretty speedy. Here's an implementation of this. The attributes "height" and "width" on a canvas effect the size of the rendering area in pixels, whereas the style properties "height" and "width" effect the area the canvas takes up without modifying the number of pixels you have to draw with.
To elaborate: if you increase the attribute-based size of a canvas without redrawing anything, you will notice the previous image will remain unchanged; all that's happened is you've added some white space to the canvas. If you just change the style, though, the canvas will become the size you tell it to become, but it may look grainy, even if everything on the canvas can in theory be in high res at that size.
This does create some odd artifacts in the image you're manipulating, but there's not simple way around that. One thing you could do is by default use the CSS whenever the size of the canvas is changing, but after the resize is done redraw with a new, higher res pattern. If you decide to go this route and need any help with it, just let me know.
Upvotes: 0