Cannot draw on canvas - javascript

I have been trying to insert a canvas on top of some pages, but for some pages it doesn't work. It seems to be me that there is something clearing all canvases on the page, but I couldn't find any calls to .clearRect anywhere in the code on the page.
canvas = document.createElement('canvas');
canvas.width = document.width;
canvas.height = document.height;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
A page with the problem is: http://www.nrk.no/sognogfjordane/helse-forde-har-ikkje-full-oversikt-1.11166801
If you run the same code on this page it should work. Expected result is a huge black square on the page.
I don't understand how a script can block the use of an inserted canvas on the page.
I am using Chrome.
* EDIT *
The problem is not that I use the deprecated document.width/heightcalls, but that I wasn't aware that canvas has a maximum size: Maximum size of a <canvas> element

Because document.width and document.height are undefined, so your canvas width and height are 0 and 0.
Instead try something like:
canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
And you'll see it just fine.
See notes on the MDN. Specifically:
Starting in Gecko 6.0, document.width is no longer supported. Instead, use document.body.clientWidth.

Please look into the demo.
canvas = document.createElement('canvas');
canvas.width = document.width;
canvas.height = document.height;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
I think this is what you needed. If you need something else then please exaplin or put your code in jsfiddle. Here in this demo it is creating canvas element.

I first thought Simon Sarris was correct, but in the end that didn't do what I wanted. What I want is a that covers the entire page.
I discovered through Maximum size of a <canvas> element that I was exceeding the limits of canvas.

Related

How can I crop an area of an image using JavaScript?

How can I crop an area of an image using JavaScript? As I have read, I must use a canvas to project the image on it.
With the following code I am cutting an area of an image, but the size of the cut area is not the indicated one.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// draw cropped image
var sourceX = 0;
var sourceY = 0;
var sourceWidth = 500;
var sourceHeight = 150;
var destWidth = sourceWidth;
var destHeight = sourceHeight;
var destX = canvas.width / 2 - destWidth / 2;
var destY = canvas.height / 2 - destHeight / 2;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
<canvas id="myCanvas" style="border:1px solid red"></canvas>
I am trying to represent in this image what I want to do.
my main problem is that the canvas does not adapt to the size of the cropped image and the final height (sourceHeight ) and width (sourceWidth ) They are not the ones I specified
How can i fix it?
The problem
Your source "width" is the same width as the image.
The solution
When using ctx.drawImage with 9 arguments, think of it like a cut and paste.
You want to "cut" the outline in red, and "paste" it to your new - centered - location.
You want to "cut" all the way up to the half way point of the source. So you need to select all the way up to the half way point of the image.
I also suggest maybe changing the variable name from "source" to "crop" (cropX, cropWidth, etc) to better reflect its purpose, as it is not really the width of the "source" anymore.
If you want the image to fill the entire canvas, "paste" it with the canvas' width and height at (0,0)
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, canvas.width, canvas.height);
The code
...
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// crop from 0,0, to 250,150
var cropX = 0;
var cropY = 0;
var cropWidth = 250;
var cropHeight = 150;
//resize our canvas to match the size of the cropped area
canvas.style.width = cropWidth;
canvas.style.height = cropHeight;
//fill canvas with cropped image
context.drawImage(imageObj, cropX, cropY, cropWidth, cropHeight, 0, 0, canvas.width, canvas.height);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
...
You'll need to tell the canvas the size of the image you're trying to display to ensure the canvas has the desiredWith size;
However, the size of your example image is 438 × 300, which makes it hard to crop to 500px.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = 'https://placehold.it/700x700';
imageObj.onload = function() {
const desiredWidth = 500;
const desiredHeight = 150;
canvas.width = desiredWidth;
canvas.height = desiredHeight;
context.drawImage(imageObj, 0, 0, desiredWidth, desiredHeight, 0, 0, desiredWidth, desiredHeight);
console.log(canvas.width, canvas.height);
};
<canvas id="myCanvas" style="border:1px solid red"></canvas>

Can I specify canvas dimensions using vh and vw?

My code is:
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.canvas.width = 40vw;
ctx.canvas.height = 40vh;
and it doesn't work. Is it possible to use vw and vh when setting canvas dimensions in JavaScript? If so, how?
I realised I could use document.documentElement.clientWidth and document.documentElement.clientHeight to work out the vw and vh respectively.
HTML:
<canvas class="canvas_hangman"></canvas>
JS:
function setUpCanvas() {
canvas = document.getElementsByClassName("canvas_hangman")[0];
ctx = canvas.getContext('2d');
ctx.translate(0.5, 0.5);
// Set display size (vw/vh).
var sizeWidth = 80 * window.innerWidth / 100,
sizeHeight = 100 * window.innerHeight / 100 || 766;
//Setting the canvas site and width to be responsive
canvas.width = sizeWidth;
canvas.height = sizeHeight;
canvas.style.width = sizeWidth;
canvas.style.height = sizeHeight;
}
window.onload = setUpCanvas();
This perfectly sets up your HTML canvas to draw on, in a responsive manner too.

High CPU usage with canvas and requestAnimationFrame

I am facing high CPU usage (30 to 40%) when calling recursively requestAnimationFrame, does anyone has good strategies to lower it down?
Simple example:
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvasContext.clearRect(0, 0, 100, 20);
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
I cannot get this example to do anything to my CPU worth mentioning, but I did manage to get it down by employing these two methods. My CPU was running at about 4-5% running your snippet, by running save / restore on the context that shaved off 2%.Unsure why - because we haven't made any transformations. The latter example just uses the old hacker way of doing this by resetting the canvas.width - this wipes the entire canvas context each time - and should be more expensive - however it got this example down to 1.4%
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvasContext.save();
canvasContext.clearRect(0, 0, 100, 20);
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
canvasContext.restore();
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvas.width = canvas.width;
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
Now I would need to go into more performance exploration to find out why, or if it actually does anything at all.
However you could employ a different drawing technique, such as just moving a sprite or a mask back and forth over some bitmap data, that will make this much less hard for the renderer to handle. I will not post that here as it goes beyond the scope of this question.

Random sized javascript canvas rectangles

I'm trying to randomly size rectangles, drawn in the canvas, using javascript.
But it doesn't show anything on the screen.
var canvas = document.getElementById("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
var contx = canv.getContext("2d");
contx.beginPath();
contx.lineWidth = "100";
contx.strokeStyle = "#DEDEDE";
contx.rect(910, 400, Math.floor((Math.random()*150)+150), Math.floor((Math.random()*150)+150));
contx.stroke();
Thanks in advance! ^_^
You have a typo: canv.getContext("2d") should be canvas.getContext("2d")

text is grainy/blurry when drawing text on a canvas via onload

If I try to draw text to my canvas at the onload event, the text shows up blurry. I draw to the same canvas later via a button click from another function and it's fine. But if I call this function from the button, it's still blurry. Can anybody see something wrong in this code?
window.onload = initCanvasRender;
function initCanvasRender() {
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'black';
ctx.font = '20px Times New Roman';
ctx.fillText('hello...', c.width/2, c.height/2);
}
There may be some problem with the
ctx.fillText('hello...', c.width/2, c.height/2);
Because if you for example set width of the canvas with css then c.width and c.height will be the default size for the canvas which is, 300x150 and not the size defined in css. Try to set two variables for the width and height that are global for your application. E.g
var canvasWidth = 400;
var canvasHeight = 200;
c.width = canvasWidth;
c.height = canvasHeight;
/* ... */
and then later in your code you can use canvasWidth and canvasWeight:
ctx.fillText('hello...', canvasWidth/2, canvasHeight/2);
Take a look at this test: http://jsfiddle.net/EsQfb/7/ it's important to use use the canvas.width and not canvas.style.width in your case.
Take a look at this for more information about this: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas-width

Categories