The question is best demonstrated with a jsFiddle. Here is is.
So according to this code:
var canvas = document.getElementById('canvas');
canvas.width = 200;
canvas.height = 150;
var context = canvas.getContext('2d');
context.rect(20,20,50,50);
context.stroke();
var image = new Image();
image.src = canvas.toDataURL("image/png");
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
you should see a rectangle drawn to the canvas every time you load the page. However, for some reason the first page load always shows nothing, a "blank"...
This point can be proven by opening the jsFiddle link in separate Chrome "Incognito" tabs. You won't ever see the rectangle load on the first time. Refreshing however it will appear.
And just to prove that you are indeed supposed to be seeing a rectangle on the initial load, try updating the jsFiddle to this:
var canvas = document.getElementById('canvas');
canvas.width = 200;
canvas.height = 150;
var context = canvas.getContext('2d');
context.rect(20,20,50,50);
context.stroke();
//var image = new Image();
//image.src = canvas.toDataURL("image/png");
//context.clearRect(0, 0, canvas.width, canvas.height);
//context.drawImage(image, 0, 0);
and you will see the rectangle on each first-load.
Why does the first load show nothing?
You have to wait for the image to load before you can dray it, and it works on the reload because it gets cached
image.onload = function(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
}
http://jsfiddle.net/hJ9WQ/1/
Related
I would like to create a background image pattern for a canvas in my svelte application. I am using the following code to create the pattern but it creates a black canvas.
let image = new Image();
image.src = 'images/background.png'
ctx.fillStyle = ctx.createPattern(image, 'repeat');
ctx.fillRect(0, 0, canvas.width, canvas.height)
The image path is public/images/background.png
You probably have to wait for the image to load, otherwise there is nothing to draw to the canvas. E.g.
const image = new Image();
image.src = 'images/background.png'
image.onload = () => {
ctx.fillStyle = ctx.createPattern(image, 'repeat');
ctx.fillRect(0, 0, canvas.width, canvas.height)
};
REPL example
Here is my code. I am uploading a image and using like this :
> var canvas = document.createElement('canvas');
> var context = canvas.getContext('2d');
> context.drawImage(image, 0, 0);
This works fine but if I copy the imagedata like below to another canvas. It loads image partially.
var canvas = document.getElementById('myCanvas');
var context1 = canvas.getContext('2d');
context1.putImageData(context.getImageData(0, 0, image.width, image.height), 0, 0);
I tried same approach by creating two canvas and this code which worked fine but without image.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 300, 300);
var d = document.getElementById("myCanvas1");
var btx = d.getContext('2d');
var imgData = ctx.getImageData(0, 0, 300, 300);
btx.putImageData(imgData, 0, 0);
If i create two canvas it works fine but not like the above where I am using in memory canvas.
My HTML file has this :
<canvas id="myCanvas" width="960" height="960"></canvas>
<canvas id="myCanvas1" width="960" height="960"></canvas>
When you create canvases, you need to set their width manually. Default canvas size is 300x150. From here HTMLCanvasElement.
Something like this:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
To copy one canvas to another use drawImage rather than getImageData, setImageData That way you will use the GPU to move the pixels rather than the CPU. You also have the option to resize, crop, and apply a variety of FXs.
// create a copy of canvasSource
// returns the newly created canvas.
function copyCanvas(canvasSource){
var canvasCopy = document.createElement("canvas");
canvasCopy.width = canvasSource.width;
canvasCopy.height = canvasSource.height;
canvasCopy.getContext("2d").drawImage(canvasSource, 0, 0);
return canvasCopy;
}
I am such a noob and I have no idea why nothing is appearing on my canvas. Can someone help me out? I wanted to have a black box on my canvas, that was the intention anyway.
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 1040;
canvas.height = 400;
canvas.style.display='block';
canvas.style.marginLeft="auto";
canvas.style.marginRight="auto";
var mainFunction= function(){
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.closePath();
ctx.fill();
requestAnimationFrame(mainFunction);
};
mainFunction();
You have created a <canvas> element but have not attached it anywhere in the DOM. Perhaps you want something like
document.body.appendChild(canvas);
or another suitable container.
Basically, you do not have an attached canvas to the DOM.
Create a html file with <canvas id="root"></canvas>;
var canvas = document.getElementById("root");
I'm trying to learn manipulate image and canvas in javascript. I'm wondering why we can not do :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
}
img.src =urlimg ;
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
$('#image1').attr('src', img.src);
And we have to do this :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src =urlimg ;
$('#image1').attr('src', img.src);
Is it due to time of image to load ?
Can I create a canvas from an existing object image ?
Thanks.
Is it due to time of image to load ?
Yes in part, but mostly because image loading is asynchronous so the next lines of code are executed right away while the image is loaded. To let you know an event is raised when it's done.
Can I create a canvas from an existing object image ?
No (not directly), but you can draw the image onto a canvas to initialize it (as you already do):
ctx.drawImage(imageElement, 0, 0, width, height);
I wrote a function that draws out a slice of a pizza based on how big you specify it to be (in degrees)
function drawProgress(degs){
var canvas = document.getElementById('progress');
var context = canvas.getContext('2d');
context.globalAlpha=1;
var img = new Image();
img.onload = function(){
context.beginPath();
context.arc(canvas.width/2,canvas.height/2, canvas.height/2, 0, degs * (-Math.PI/180), true);
context.lineTo(canvas.width/2, canvas.height/2);
context.clip();
context.drawImage(img, 0, 0, canvas.width,canvas.width);
}
img.src = 'pizza.png';
}
When I try to call this function every 250ms, the progress is not updated after the first draw.
function runsEvery250ms(percent){
drawProgress(3.6 * percent);
}
What changes do I need to make to the code to get the canvas to redraw each time drawProgress(degs) is called? Is it possible to perform redraws without causing the pizza to flicker?
Use context.clearRect(0, 0, canvas.width, canvas.height); and cache your image, don't reload each time you refresh
UPDATE: No idea if this will work, untested and been a while since I used canvas but try it
var canvas = document.getElementById('progress');
var context = canvas.getContext('2d');
var img = new Image();
var imgLoaded = false;
img.src = 'pizza.png';
img.onload = function(){
imgLoaded = true;
}
function drawProgress(degs){
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
context.globalAlpha=1;
context.beginPath();
context.arc(canvas.width/2,canvas.height/2, canvas.height/2, 0, degs * (-Math.PI/180), true);
context.lineTo(canvas.width/2, canvas.height/2);
context.clip();
if (imgLoaded) context.drawImage(img, 0, 0, canvas.width,canvas.width);
context.restore();
}