Dynamically resize canvas window with javascript/jquery? - javascript

How can I resize a canvas with javascript/jquery?
Resizing using the css function and applying it to the canvas element just stretches the content as if you were stretching an image.
How would I go about doing this without the stretching?
http://jsfiddle.net/re8KU/4/

Make a function that does the drawing, then re-draw whenever something changes that requires it (like a page resize, etc). Try it out
Make sure you set the context.canvas.width/height, not CSS width/height. Also note that setting the size clears the canvas.
How I would write it:
(function(){
var c = $("#canvas"),
ctx = c[0].getContext('2d');
var draw = function(){
ctx.fillStyle = "#000";
ctx.fillRect(10,10,50,50);
};
$(function(){
// set width and height
ctx.canvas.height = 600;
ctx.canvas.width = 600;
// draw
draw();
// wait 2 seconds, repeate same process
setTimeout(function(){
ctx.canvas.height = 400;
ctx.canvas.width = 400;
draw();
}, 2000)
});
})();
​

(function($) {
$.fn.extend({
//Let the user resize the canvas to the size he/she wants
resizeCanvas: function(w, h) {
var c = $(this)[0]
c.width = w;
c.height = h
}
})
})(jQuery)
Use this little function I created to take care of resizing on the go. Use it this way --
$("the canvas element id/class").resizeCanvas(desired width, desired height)

Whenever the browser is resized, the following solution resizes the dimensions of the canvas based on the dimensions of the window by creating an initial ratio.
Jsfiddle: http://jsfiddle.net/h6c3rxxf/9/
Note: The canvas needs to be re-drawn, when it is resized.
HTML:
<canvas id="myCanvas" width="300" height="300" >
CSS:
canvas {
border: 1px dotted black;
background: blue;
}
JavaScript:
(function() {
// get the precentage of height and width of the cavas based on the height and width of the window
getPercentageOfWindow = function() {
var viewportSize = getViewportSize();
var canvasSize = getCanvastSize();
return {
x: canvasSize.width / (viewportSize.width - 10),
y: canvasSize.height / (viewportSize.height - 10)
};
};
//get the context of the canvas
getCanvasContext = function() {
return $("#myCanvas")[0].getContext('2d');
};
// get viewport size
getViewportSize = function() {
return {
height: window.innerHeight,
width: window.innerWidth
};
};
// get canvas size
getCanvastSize = function() {
var ctx = getCanvasContext();
return {
height: ctx.canvas.height,
width: ctx.canvas.width
};
};
// update canvas size
updateSizes = function() {
var viewportSize = getViewportSize();
var ctx = getCanvasContext();
ctx.canvas.height = viewportSize.height * percentage.y;
ctx.canvas.width = viewportSize.width * percentage.x;
};
var percentage = getPercentageOfWindow();
$(window).on('resize', function() {
updateSizes();
});
}());

Related

Is there a way to find the center of a browser?

I want my text to be in the middle of the browser window, is there any way I can find (in pixels) the middle of the browser? This isn't just HTML text, so I can't use CSS or anything. Here's part of my code in case you don't understand my confusing explanation:
<canvas id = "my-canvas" width = "screen.width" height = "screen.height"></canvas>
<script src = "https://cdn.jsdelivr.net/processing.js/1.4.8/processing.min.js"></script>
<script type = "application/javascript">
// program code {
var sketchProc = function(processingInstance) {
with (processingInstance) {
background(255);
fill(0);
text("Hi", 300, 300);
}
};
// }
// store canvas {
var canvas = document.getElementById("my-canvas");
// }
// run Processing.js {
var processingInstance = new Processing(canvas, sketchProc);
// }
</script>
This might work for ya
const width = window.innerWidth / 2;
const height = window.innerHeight / 2;
text("Hi", width, height);

html5 canvas resize with javascript (not achieving desired result)

i was testing some code with javascript, about resizing the html5 canvas. i've asked similar question before, when i was testing the same thing with jquery. and i've got the desired solution that time, reference (eg_1). in this (eg_1), the result was, canvas element was resizing in every frame because of requestAnimationFrame($.fn.animate); is taking place in a recursive form.the visual result for that is here the width attribute updates when i resize the console window. and if i close the console the canvas resizes automatically, i don't need to reload the window, to update the attribute values. means canvas is full screen, all time. but i am having problem with the same thing, in javascript. if i close the console, the width of the console cuts (or resizes) the canvas with a white space. here is the visual result the white space is my problem. i've to reload the window, to make the canvas full screen again. in short i'm not having the same effect as (eg_1). here i tried so far, reference (eg_2).
(eg_1)
html : <canvas></canvas>
css :
* {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
background-color: turquoise;
}
jquery :
$(document).ready(function() {
var view = $(window),
canvas = $("canvas"),
ctx = canvas[0].getContext("2d"),
width = view.width(),
height = view.height();
$.fn.windowResize = function() {
var width = view.width();
height = view.height();
canvas.attr("width", width);
canvas.attr("height", height);
};
view.on("resize", $.fn.windowResize);
canvas.attr("width", width);
canvas.attr("height", height);
$.fn.animate = function() {
requestAnimationFrame($.fn.animate);
ctx.clearRect(0, 0, width, height);
// start here
};
$.fn.animate();
});
(eg_2)
var canvas = document.querySelectorAll("canvas")[0];
var context = canvas.getContext("2d");
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
function resize() {
setInterval(resize, 5);
clearInterval(resize);
canvas.width = windowWidth;
canvas.height = windowHeight;
}
resize();
Answer:
Your initial issue:
You need to get the updated values of window.innerWidth and window.innerHeight.
To do this you can turn the variables into functions that request the current values.
Example:
var canvas = document.querySelectorAll("canvas")[0];
var context = canvas.getContext("2d");
var windowWidth = () => window.innerWidth;
var windowHeight = () => window.innerHeight;
function resize() {
setInterval(resize, 5);
clearInterval(resize);
canvas.width = windowWidth();
canvas.height = windowHeight();
}
resize();
* {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
background-color: turquoise;
}
<canvas></canvas>
Other issues:
Your use of Timers is incorrect. clearInterval(resize) isn't going to clear anything, because resize is not a timer itself.
Secondly you shouldn't be using any timers when rendering to Canvas. It can often lead to things like the above( multiple timers ) or issues with constant, unnecessary, re-processing.
Instead of resizing perpetually you may want to just do so when the resize event is dispatched. Even if you were using requestAnimationFrame - which would effectively stop the render if anything else takes precedence or if you switch tabs, it's an unnecessary process in that you're constantly re-rendering the same thing without cause. Canvas Apps tend to get big real quick when you add in multiple rendering functions, so you'll want to mitigate unnecessary steps.
You can do this by attaching to appropriate events and creating requestAnimationFrame helpers like in the following example:
var canvas = document.querySelectorAll("canvas")[0];
var context = canvas.getContext("2d");
var windowWidth = () => window.innerWidth;
var windowHeight = () => window.innerHeight;
var request = fn => requestAnimationFrame(fn),
requestHandler = fn => () => request(fn);
function resize() {
canvas.width = windowWidth();
canvas.height = windowHeight();
}
request(resize);
window.addEventListener("resize", requestHandler(resize) );
* {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
background-color: turquoise;
}
<canvas></canvas>

Image gets distorted when using css to set canvas height/width 100%

I am currently trying to draw an image to canvas, I have this so far:
"use strict";
var debugging = true;
var canvas = document.getElementById('astoniaCanvas');
var ctx = canvas.getContext('2d');
function loadUI() {
var topOverlay = new Image();
topOverlay.src = "/images/00000999.png";
topOverlay.onload = function() {
ctx.drawImage(topOverlay, 0, 0, canvas.width, 10);
}
var bottomOverlay = new Image();
bottomOverlay.src = "/images/00000998.png";
if (debugging) {
console.log('Drawing');
}
}
loadUI();
That works fine, but the image loads and looks like this:
When it should look like this:
The dimensions of the good looking picture are 800x40.
If I remove the
canvas {
width: 100%;
height: 100%;
}
the image goes back to looking normal, how can I scale my canvas?
Any information would be great thanks.
You arent accounting for height. Canvas can be confusing when it comes to height/width vs clientHeight/clientWidth
When you create a canvas the css width and height has no bearing on the number of pixels the internal canvas contains. Unless specifically set a canvas comes with a width height of 300x150.
A trick I have used in the past is to use the clientWidth and a scale to set everything
"use strict";
var debugging = true;
var canvas = document.getElementById('astoniaCanvas');
var ctx = canvas.getContext('2d');
function loadUI() {
var topOverlay = new Image();
topOverlay.onload = function() {
// use a scale between the image width and the canvas clientWidth
var scale = topOverlay.width / canvas.clientWidth;
var newWidth = canvas.clientWidth;
var newHeight = topOverlay.height * scale;
// resize canvas based on clientWidth
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(topOverlay, 0, 0, newWidth, newHeight);
}
topOverlay.src = "http://i.stack.imgur.com/AJnjh.png";
// var bottomOverlay = new Image();
// bottomOverlay.src = "/images/00000998.png";
if (debugging) {
console.log('Drawing');
}
}
loadUI()
<canvas id="astoniaCanvas" style="width: 100%"></canvas>

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
} */
}

How to calculate shape height and width including its border width in canvas?

I am working on a project using HTML5 and javascript.I have a canvas on which document will be loaded.
canvas = document.getElementById('pdf');
ctx = canvas.getContext('2d');
In above canvas, document will be loaded.
I have to draw different shapes on it as an individual canvas at runtime.So that on drawing i have to create a new canvas for each and every Shape (required).
MouseDown
function mouse_Pressed(e) {
getMouse(e);//getting current X and Y position
x1=mx; y1=my;
var cords=getMousePos(canvas,e);
annCanvas=document.createElement('canvas'); //Creating
annCanvasContext=annCanvas.getContext('2d');
isDraw=true;isDrawAnn=true;
}
MouseMove
function mouse_Dragged(e)
{
if(isDraw)
{
getMouse(e);
x2=mx; y2=my;
calculatePoints(x1,y1,x2,y2);
var width=endX-startX;
var height=endY-startY;
annCanvas.style.position = "absolute";
annCanvas.width=4; //Width of square
annCanvas.style.left=""+startX+"px";
annCanvas.style.top=""+startY+"px";
annCanvas.height=height;
annCanvas.style.zIndex="100000";
document.getElementById("canvas").appendChild(annCanvas);
annCanvasContext.fillStyle='rgb(255,255,0)';
annCanvasContext.lineWidth=borderWidth;
annCanvasContext.strokeRect(0,0,width,height);
annCanvasContext.stroke();
}
}
MouseReleased
function mouse_Released(e)
{
isDrag = false;
isDraw=false;
isDrawAnn=false;
}
Main problem is that if i am drawing rectangle with border width 50 then its Canvas-outside part is going to cut because of less area of canvas(i.e. rect shape). So i want to calculate canvas height, width with its borderWidth.
This should take into account the border width as well as width etc.
function init() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var s = size(canvas);
alert(s[0]);
}
function size(el) {
var clientHeight = (el.offsetHeight > el.clientHeight) ? el.offsetHeight : el.clientHeight;
var clientWidth = (el.offsetWidth > el.clientWidth) ? el.offsetWidth : el.clientWidth;
return [clientWidth, clientHeight];
};
HTML:
<body onload="init();">
<canvas id="canvas" width="200" height="300" style="width: 500px; height: 400px; border: 10px solid brown;"></canvas>
</body>

Categories

Resources