Resizing canvas to full browser window width and height - javascript

I'm playing around with a node/socket.io Pictionary game. I apologize in advance, I am a designer and not too keen with js.
I'm just trying to re-size the canvas so it will be the entire width and height of a browser window without scaling up the stroke path? Right now, the Javascript sets the canvas to 500px.
Here is the relevant code:
// ================================================
// canvas drawing section
// ================================================
var canvas = $('#canvas'),
context = canvas[0].getContext('2d');
socket.on('drawCanvas', function(canvasToDraw) {
if(canvasToDraw) {
canvas.width(500);
context.lineJoin = 'round';
context.lineWidth = 2;
// ...
}
});

canvas[0].width = $(window).width();
canvas[0].height = $(window).height();
worked great.

You're using jQuery to change the dimensions, and that won't work well with canvas (it will scale the canvas contents too). Set the dimensions directly on the canvas element:
canvas[0].width = 500;
// Or:
canvas.get(0).width = 500;
To set the canvas to the full window dimensions, try this:
canvas[0].width = $(window).width();
canvas[0].height = $(window).height();

Use clientWidth and clientHeight property of canvas
if (canvas[0].width != canvas[0].clientWidth || canvas[0].height != canvas[0].clientHeight) {
canvas[0].width = canvas[0].clientWidth;
canvas[0].height = canvas[0].clientHeight;
}
and set the css for canvas width and height to 100%;

Related

Resize canvas to whole screen after it was drawn

I am writing a simple game in javascript which draws on a HTML canvas. The canvas has a fixed size (1280 × 720) and that is also the "room" in which the objects are drawn.
Now I want the canvas to be stretched to be 100 % of the screen. I can't do that by just setting the width and height of the canvas because the javascript would only draw in the 1280 × 720 rectangle in the top left.
What I want instead is, that it is zoomed in so that it takes up the whole screen and if the javascript draws something at (1280, 720) it should be the bottom right corner.
Can I do this without using any external libraries?
If you wish to keep the rendering size at 1280x720 for the canvas, but stretch or expand it to the window size you can use the css width and height for that.
Using css will only cause the shape of the canvas to change, but the internal pixels/drawing frame are still set by the width and height attribute. (This will of course cause the image to be blurry if it is upscale to much)
With CSS:
* { margin: 0; padding: 0;}
body, html { height:100%; }
#canvasID {
position:absolute;
height:100%;
/*width:100%; /* uncomment if you don't care about aspect ratio*/
}
<canvas id="canvasID" width=128 height=72>
With a script:
$(document).ready(function() {
function resizeCanvas() {
var canvas = $("#canvasID");
// original width/height from the canvas attribute
var heightOriginal = canvas[0].height;
var widthOriginal = canvas[0].width;
// fill to window height while maintaining aspect ratio
var heightNew = window.innerHeight;
// replace with window.innerWidth if you don't care about aspect ratio
var widthNew = heightNew / heightOriginal * widthOriginal;
canvas.css("height", heightNew + "px");
canvas.css("width", widthNew + "px");
}
// keep size when window changes size
$(window).resize(resizeCanvas);
// initial resize of canvas on page load
resizeCanvas();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvasID" width=128 height=72>
Alternately if you wish for the internal canvas resolution/size to be able to change dynamically you can use scale to ensure that everything gets rendered to the right size.
$(document).ready(function() {
var canvas = $("#canvasID");
// original width/height from the canvas attribute
var heightOriginal = canvas[0].height;
var widthOriginal = canvas[0].width;
// current scale (original 1 to 1)
var verticalRatio = 1;
var horizontalRatio = 1;
// the canvas context
var ctx = canvas[0].getContext('2d');
function setScale() {
// remove previous scale
ctx.scale(1/horizontalRatio, 1/verticalRatio);
// fill to window height while maintaining aspect ratio
var heightNew = window.innerHeight;
// not needed if you don't care about aspect ratio
var widthNew = heightNew / heightOriginal * widthOriginal;
// these would be the same if maintaining aspect ratio
verticalRatio = heightNew / heightOriginal;
horizontalRatio = widthNew / widthOriginal;
// update drawing scale
ctx.scale(horizontalRatio, verticalRatio);
// update width and height of canvas
canvas[0].height = heightNew;
canvas[0].width = widthNew;
}
// keep size when window changes size
$(window).resize(setScale);
// initial resize of canvas on page load
setScale();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvasID" width=128 height=72>

HTML5 canvas, fit to (rest of) screen

I've made a little web game, I'm using this code below to scale the game to the page size.
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
// Attempt at auto-resize
function resize_canvas(){
if (canvas.width != window.innerWidth)
{
canvas.width = window.innerWidth;
}
if (canvas.height != window.innerHeight)
{
canvas.height = window.innerHeight;
}
}
window.addEventListener("resize", resize_canvas);
window.addEventListener("orientationchange", resize_canvas);
However, I'm now adding a menu in the top of the game using some CSS and I'm running into problems.
The game takes the size of the inner window, so anything displayed along with the game will cause the content not to fit into the browser.
How can I make the game "fill" the rest of the window?
(I've found questions on how to scale the game to the window, but I'd like the game to fill the window instead)
An image to demonstrate the problem below:
(Notice the scrollbars, which I'd like to eliminate)
Edit:
I'm quite new to web development, but I have the feeling CSS doesn't really work well on canvas.
And if you remove the nav height ?
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
var menu = document.getElementById('nav')
resize_canvas();
document.body.appendChild(canvas);
// Attempt at auto-resize
function resize_canvas(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight - menu.offsetHeight;
}
window.addEventListener("resize", resize_canvas);
window.addEventListener("orientationchange", resize_canvas);
and
canvas {
position:relative;
}

HTML Canvas fillRect fill 25% of window-height

I'm trying to learn how to use HTML's Canvas and it's properties.
Now I'm trying to draw a ground and a sky, and I want the sky to be 75% of screens height and ground to be 25%.
This was easy using a div, and style it with CSS or JavaScript CSS Query. Now that I'm on a Canvas, I can't figure out how to set the fillRect properties...
My code:
var windowHeight = $(window).height();
var windowWidth = $(window).width();
var skyHeight = windowHeight - (windowHeight * 0.25);
var groundHeight = windowHeight - (windowHeight * 0.75);
ctx = gameCanvas.getContext("2d");
ctx.fillStyle="green";
ctx.fillRect(0,0,windowWidth,windowHeight);
ctx.fillStyle="cyan";
ctx.fillRect(0,0,windowWidth,skyHeight);
Also: if I try using i.e.
ctx.fillStyle="cyan";
ctx.fillRect(0,0,30,30);
This draws a perfect square on top of the green "ground"-background, but if I change to i.e.
ctx.fillRect(0,0,200,200);
it will fill my entire height of the screen, and more than 50% of my screen-width.
According to http://www.w3schools.com/tags/canvas_fillstyle.asp canvas fillrect are using pixels, but 200 x 200 pixels should definitely NOT fill my entire screen height. :/
Where's the part where you tell canvas what its dimensions are? Just like any other HTML media element that you need to be of a specific size (video, image), you need to tell it what its width and height is if you want reliably sized content (if you don't, by convention the canvas will be sized 300 x 150px). And because we're setting the number of pixels we can draw on, this is not "purely cosmetic" like CSS, we have to do it properly:
var cvs = document.querySelector("canvas");
// if you didn't use <canvas width="..." height="...">, we need this:
cvs.width = 800;
cvs.height = 400;
And then you can do your drawing:
var ctx = cvs.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0,0.75*cvs.height, cvs.width,0.25*cvs.height);
ctx.fillStyle = "lightblue";
ctx.fillRect(0,0, cvs.width, 0.75*cvs.height);
See http://jsbin.com/tejiqixeji/edit?html,js,output

If I resize my canvas, my createJS text becames blurry

I'm using createJS to drawn inside the canvas. I have my canvas set to occupy the browser window maintaining aspect ratio using the resize() function.
This is the code:
mytext = new createjs.Text("Lorem ipsum dolor sit amet 2","19px Calibri","#073949");
mytext.x = 450
mytext.y = 300;
stage.addChild(mytext);
resize = function() {
var canvas = document.getElementById('canvas');
var canvasRatio = canvas.height / canvas.width;
var windowRatio = window.innerHeight / window.innerWidth;
var width;
var height;
if (windowRatio < canvasRatio) {
height = window.innerHeight - 35;
width = height / canvasRatio;
} else {
width = window.innerWidth;
height = width * canvasRatio;
}
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
}()
What happens is that the text gets blurry (decrease of quality) when the canvas resizes.
http://i.imgur.com/RQOSajs.png
vs
http://i.imgur.com/Xwhf5c5.png
How can I solve this issue?
Since you are using CreateJS, you can simply resize the canvas, and scale the entire stage to redraw everything at the new size:
// just showing width to simplify the example:
var newWidth = 800;
var scale = newWidth/myCanvas.width;
myCanvas.width = newWidth;
myStage.scaleX = myStage.scaleY = scale;
myStage.update(); // draw at the new size.
#Adam's answer is correct as far as scaling the canvas goes. You do NOT want to scale with CSS, as it will stretch your canvas instead of changing its pixel dimensions. Set the width and height of the canvas using JavaScript instead.
stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;
As you stated in your comment, this will only change the canvas size, and not reposition or scale your content. You will have to do this manually. This is fairly simple. Generally, I recommend putting your "resize" listener in the JavaScript in your HTML file, rather than on a frame script.
First, determine the scale, based on the size of the window and the size of your content. You can use the exportRoot.nominalBounds.width and exportRoot.nominalBounds.height which is the bounds of the first frame. If you want to scale something else, use its nominalBounds instead.
Note that nominalBounds is appended to all MovieClips exported from Flash/Animate. If you enable multi-frame bounds, and want to use those, you will have to modify your approach.
The main idea is to use the original, unscaled size of your contents.
var bounds = exportRoot.nominalBounds;
// Uses the larger of the width or height. This will "fill" the viewport.
// Change to Math.min to "fit" instead.
var scale = Math.max(window.innerWidth / bounds.width, window.innerHeight / bounds.height);
exportRoot.scaleX = exportRoot.scaleY = scale;
You can then center it if you want.
exportRoot.x = *window.innerWidth - bounds.width*scale)/2;
exportRoot.y = *window.innerHeight - bounds.height*scale)/2;
Here is a quick sample of a responsive canvas using a simple shape as the scaling contents:
http://jsfiddle.net/lannymcnie/4yy08pax/
Doing this with Flash/Animate CC export has come up a few times, so it is on my list of future EaselJS demos to include on createjs.com, and in the EaselJS GitHub.
I hope this helps.
Take a look at my jsfiddle : https://jsfiddle.net/CanvasCode/ecr7o551/1/
Basically you just store the original canvas size and then use that to work out new positions and sizes
html
<canvas id="canvas" width="400" height="400">
Canvas was unable to start up.
</canvas>
<button onclick="resize()">Click me</button>
javascript
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var originalWidth = canvas.width;
var originalHeight = canvas.height;
render = function()
{
context.fillStyle = "#DDD";
context.fillRect(0,0, originalWidth * (canvas.width / originalWidth), originalHeight * (canvas.height / originalHeight));
context.fillStyle = "#000";
var fontSize = 48 * (canvas.width / originalWidth);
context.font = fontSize+"px serif";
context.fillText("Hello world", 100 * (canvas.width / originalWidth), 200 * (canvas.height / originalHeight));
}
resize = function()
{
canvas.width = 800;
canvas.height = 600;
render();
}
render();
The HTML5 canvas element works with two different sizes
Visual size on screen, controlled via CSS, like you're setting with canvas.style.width/height
Size of pixel buffer for the drawing, controlled via numeric width and height pixel attributes on the canvas element.
The browser will stretch the buffer to fit the size on screen, so if the two values are not 1:1 ratio text will look blurry.
Try adding the following lines to your code
canvas.width = width;
canvas.height = height;
I created a function to resize all the elements on the screen after resizing the canvas. It saves the initial coordinates and scales for the elements with the original width of 900 px and then it changes them according to the current width ratio relative to the original width ratio. The text isn't blurry/bad quality anymore.
resize = function() {
var canvas = document.getElementById('canvas');
var canvasRatio = canvas.height / canvas.width;
var windowRatio = window.innerHeight / window.innerWidth;
var width;
var height;
if (windowRatio < canvasRatio) {
height = window.innerHeight;
width = height / canvasRatio;
} else {
width = window.innerWidth;
height = width * canvasRatio;
}
canvas.width = width;
canvas.height = height;
reziseElements();
};
reziseElements = function()
{
var canvrat = canvas.width / 900;
//Simplified
stage.scaleX = stage.scaleY = canvrat;
//Old Version
/*for (i=0; i<stage.numChildren ;i++)
{
currentChild = stage.getChildAt(i);
if (typeof currentChild.oscaleX == 'undefined')
{
currentChild.oscaleX = currentChild.scaleX;
currentChild.ox = currentChild.x;
currentChild.oy = currentChild.y;
}
}
for (i=0; i<stage.numChildren ;i++)
{
currentChild = stage.getChildAt(i);
currentChild.scaleX = currentChild.scaleY = currentChild.oscaleX * canvrat
currentChild.x = currentChild.ox * canvrat
currentChild.y = currentChild.oy * canvrat
} */
}

HTML canvas - drawing disappear on resizing

I have created a basic shape in HTML canvas element which works fine.
The problem occurs when I resize the canvas, all the drawing in the canvas disappears. Is this the normal behavior? or is there a function that can be used to stop this?
One way to fix this could be to call drawing function again on canvas resize however this may not be very efficient if there is huge content to be drawn.
What's the best way?
Here is the link to sample code https://gist.github.com/2983915
You need to redraw the scene when you resize.
setting the width or height of a canvas, even if you are setting it to the same value as before, not only clears the canvas but resets the entire canvas context. Any set properties (fillStyle, lineWidth, the clipping region, etc) will also be reset.
If you do not have the ability to redraw the scene from whatever data structures you might have representing the canvas, you can always save the entire canvas itself by drawing it to an in-memory canvas, setting the original width, and drawing the in-memory canvas back to the original canvas.
Here's a really quick example of saving the canvas bitmap and putting it back after a resize:
http://jsfiddle.net/simonsarris/weMbr/
Everytime you resize the canvas it will reset itself to transparant black, as defined in the spec.
You will either have to:
redraw when you resize the canvas, or,
don't resize the canvas
One another way is to use the debounce if you are concerned with the performance.
It doesnt resize or redraw every position you are dragging. But it will resize only when the it is resized.
// Assume canvas is in scope
addEventListener.("resize", debouncedResize );
// debounce timeout handle
var debounceTimeoutHandle;
// The debounce time in ms (1/1000th second)
const DEBOUNCE_TIME = 100;
// Resize function
function debouncedResize () {
clearTimeout(debounceTimeoutHandle); // Clears any pending debounce events
// Schedule a canvas resize
debounceTimeoutHandle = setTimeout(resizeCanvas, DEBOUNCE_TIME);
}
// canvas resize function
function resizeCanvas () { ... resize and redraw ... }
I had the same problem. Try following code
var wrapper = document.getElementById("signature-pad");
var canvas = wrapper.querySelector("canvas");
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
It keeps the drawing as it is
One thing that worked for me was to use requestAnimationFrame().
let height = window.innerHeight;
let width = window.innerWidth;
function handleWindowResize() {
height = window.innerHeight;
width = window.innerWidth;
}
function render() {
// Draw your fun shapes here
// ...
// Keep this on the bottom
requestAnimationFrame(render);
}
// Canvas being defined at the top of the file.
function init() {
ctx = canvas.getContext("2d");
render();
}
I had the same problem when I had to resize the canvas to adjust it to the screen.
But I solved it with this code:
var c = document.getElementById('canvas');
ctx = c.getContext('2d');
ctx.fillRect(0,0,20,20);
// Save canvas settings
ctx.save();
// Save canvas context
var dataURL = c.toDataURL('image/jpeg');
// Resize canvas
c.width = 50;
c.height = 50;
// Restore canvas context
var img = document.createElement('img');
img.src = dataURL;
img.onload=function(){
ctx.drawImage(img,20,20);
}
// Restote canvas settings
ctx.restore();
<canvas id=canvas width=40 height=40></canvas>
I also met this problem.but after a experiment, I found that Resizing the canvas element will automatically clear all drawings off the canvas!
just try the code below
<canvas id = 'canvas'></canvas>
<script>
var canvas1 = document.getElementById('canvas')
console.log('canvas size',canvas1.width, canvas1.height)
var ctx = canvas1.getContext('2d')
ctx.font = 'Bold 48px Arial'
var f = ctx.font
canvas1.width = 480
var f1 = ctx.font
alert(f === f1) //false
</script>

Categories

Resources