Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas 100% height and width

I'm trying to make this raindrop canvas script take up 100% width and height, but nothing I seem to do works. I tried changing the CSS, and height/width in the Canvas area, but it either doesn't change anything, or it makes it not work at all. The one time I tried something that actually made it full size, it seemed to have a weird effect on the raindrops, they became all blurry and much larger, so it must have actually stretched the canvas instead of making it larger. Here's the code for the default 800x800 pixel canvas.

Style

<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }
</style>

Script for canvas

<script type="text/javascript">
var canvas = null;
var context = null;
var bufferCanvas = null;
var bufferCanvasCtx = null;
var flakeArray = [];
var flakeTimer = null;
var maxFlakes = 200; // Here you may set max flackes to be created 

function init() {
    canvas = document.getElementById('canvasRain');
    context = canvas.getContext("2d");

    bufferCanvas = document.createElement("canvas");
    bufferCanvasCtx = bufferCanvas.getContext("2d");
    bufferCanvasCtx.canvas.width = context.canvas.width;
    bufferCanvasCtx.canvas.height = context.canvas.height;


    flakeTimer = setInterval(addFlake, 200);

    Draw();

    setInterval(animate, 30);

}
function animate() {

    Update();
    Draw();

}
function addFlake() {

    flakeArray[flakeArray.length] = new Flake();
    if (flakeArray.length == maxFlakes)
        clearInterval(flakeTimer);
}
function blank() {
    bufferCanvasCtx.fillStyle = "rgba(0,0,0,0.8)";
    bufferCanvasCtx.fillRect(0, 0, bufferCanvasCtx.canvas.width, bufferCanvasCtx.canvas.height);

}
function Update() {
    for (var i = 0; i < flakeArray.length; i++) {
        if (flakeArray[i].y < context.canvas.height) {
            flakeArray[i].y += flakeArray[i].speed;
            if (flakeArray[i].y > context.canvas.height)
                flakeArray[i].y = -5;
            flakeArray[i].x += flakeArray[i].drift;
            if (flakeArray[i].x > context.canvas.width)
                flakeArray[i].x = 0;
        }
    }

}
function Flake() {
    this.x = Math.round(Math.random() * context.canvas.width);
    this.y = -10;
    this.drift = Math.random();
    this.speed = Math.round(Math.random() * 5) + 1;
    this.width = (Math.random() * 3) + 2;
    this.height = this.width;
}
function Draw() {
    context.save();

    blank();

    for (var i = 0; i < flakeArray.length; i++) {
        bufferCanvasCtx.fillStyle = "white";
        bufferCanvasCtx.fillRect(flakeArray[i].x, flakeArray[i].y, flakeArray[i].width, flakeArray[i].height);
    }


    context.drawImage(bufferCanvas, 0, 0, bufferCanvas.width, bufferCanvas.height);
    context.restore();
}

</script>

And finally here's the body

<body onload="init()">
  <canvas  id="canvasRain" width="800px" height="800px">Canvas Not Supported</canvas>
</body>
like image 737
Steve Worth Avatar asked Oct 29 '13 18:10

Steve Worth


People also ask

How will you set a canvas size in HTML5?

Canvas has two sizes, the size of the element and the size of the drawing surface. The default size for both element and drawing surface is 300 x 150 screen pixels. To set the height and width canvas HTML5 has two attributes: Height: With the help of Height attribute we can set the height.

How do I make HTML canvas full screen?

Code to make canvas occupy full page : innerWidth; canvas. height = window. innerHeight; //Done! Enjoy full page canvas!

How can an HTML5 canvas size be changed so that it fits the entire window?

to set the canvas's width and height both to 100%. We also set the position to absolute and top , left , right , and bottom to 0 to make the canvas fill the screen. Also, we make the html and body elements fill the screen by setting the width and height to 100%.


2 Answers

body, #canvasRain {width:100%; height:100%; margin:0px;} will set your size properly but your problem is that your canvas height/width you're using to do your drawing doesn't pick up the proper px values when setting them with %'s. And that's where the scaling comes in with the fuzzy flakes. It takes some default canvas size and stretches to 100% of the view. Adding something like

bufferCanvas.width = canvas.width = window.innerWidth;
bufferCanvas.height = canvas.height = window.innerHeight;

seems to do the trick. And you might want/need to handle resize events to recalculate it. Here is a sample. I couldn't get jsFiddle to work for me, so it's just the whole thing.

like image 195
mafafu Avatar answered Oct 19 '22 23:10

mafafu


I've set up a fiddle that shows how to resize the canvas using some simple CSS.

http://jsfiddle.net/C7LfU/1/

$('#canvasRain').css({
   "height": window.innerHeight,
   "width": window.innerWidth
});

I've also went ahead and updated your animation to use requestAnimationFrame. This probably what caused your Flakes to be fuzzy: The animation lagged since setTimeout doesn't scale to when the browser is actually ready to draw another frame.

window.requestAnimFrame = (function () {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
        window.setTimeout(callback, 1000 / 60);
    };
})();

function animate() {
    requestAnimFrame(animate);
    Update();
    Draw();
}

Read a little more about why you should use requestAnimationFrame at: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

like image 25
Mataniko Avatar answered Oct 20 '22 00:10

Mataniko