How to determine if Image is already drawn in HTML Canvas - html

supposed i have an image /site/image1.jpg upon drawing this to the canvas it would be something like this.
var image = new Image();
image.src = "/site/image1.jpg";
image.onload = function(){
context.drawImage(image,x,y);
}
Assuming my internet connection is so slow how would i know that the image was already drawn on the canvas?
Thanks.

To workout if the image has been draw keep a flag or mark the image.
var image = new Image();
image.src = "blah.foo";
image.drawn = false; // Add a property to indicate if the image has been drawn
image.onload = function(){
ctx.drawImage(image,0,0);
image.drawn = true; // flag it as drawn
}
// then later you if you want to know if its been drawn
if(image.drawn){
console.log("Yes its been drawn.");
}

Related

HTML5 canvas apply color to image where shape overlays

I have this image drawn to a HTML5 canvas:
What I want to do is apply color to just a part of it.
The part where I want to apply color is defined by the following overlay image:
So, basically, I would like to guide my coloring by the overlay. So where the overlay pixels meets the main image pixels I should apply a color on the main image. At least that's how I see it working.
Notice that the overlay matches the whole image except for the lacing.
The catch is that I would like to retain the main image texture while applying the color. You can see that it has a leather texture and a "real" feel which I want to keep.
Can you please show me some methods of achieving this or share some thoughts?
Thank you!
globalCompositeOperation is your friend here.
Basically, you draw your overlay, then you set the gCO to 'source-atop' composite mode, which will make all your future drawings to only stay where there were already opaque pixels drawn, so it is important that your overlay has transparent parts.
So then you just fill a rectangle of your desired command, and finally you draw your original image, either behind, or blended to the new shape we just created.
var ctx = canvas.getContext('2d');
var loaded = 0;
function onload(){
if(++loaded === 2){
canvas.width = this.width;
canvas.height = this.height;
ctx.font = "40px sans-serif";
draw();
}
}
var original = new Image();
var overlay = new Image();
original.onload = overlay.onload = onload;
original.src = 'https://i.stack.imgur.com/vIKpI.png';
overlay.src = 'https://i.stack.imgur.com/10Tre.png';
// list of blending modes.
// Note that destination-over is a composite mode,
// which place the new drawings behind the already-there ones
var currentMode = 0;
var modes = ['destination-over', 'lighter', 'multiply', 'screen', 'overlay', 'darken',
'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
'exclusion', 'hue', 'saturation', 'color', 'luminosity' ];
function draw(){
// switch between different Blending modes
var mode = modes[currentMode];
currentMode = (currentMode+1)%(modes.length);
// clear previous
ctx.clearRect(0,0,canvas.width, canvas.height);
// draw our overlay
ctx.drawImage(overlay, 0,0);
// this will keep new drawings only where we already have existing pixels
ctx.globalCompositeOperation = 'source-atop';
ctx.fillStyle = 'red';
ctx.fillRect(0,0,canvas.width, canvas.height);
// now choose between the list of blending modes
ctx.globalCompositeOperation = mode;
// draw our original image
ctx.drawImage(original, 0,0);
// go back to default
ctx.globalCompositeOperation = 'source-over';
// just so we can know which one is shown
ctx.fillStyle = 'black';
ctx.fillText(mode, 40,40)
// do it again
setTimeout(draw, 1000)
}
canvas{
width: 100%;
}
<canvas id="canvas"></canvas>

Pass an image to a canvas with dataurl

I am trying to make an image being passed to a canvas from a weburl.
The code has been taken from this [question][1] which is accepted but for some reason it does not work on me on firefox or chrome.
Any ideas?
EDIT:
Here you are:
var myCanvas = document.getElementById('my_canvas_id');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
ctx.drawImage(img,0,0); // Or at whatever offset you like
};
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAxUlEQVR4nO3BMQEAAADCoPVPbQhfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOA1v9QAATX68/0AAAAASUVORK5CYII=';
The reason nothing shows is that the provided Data-URI contains no data, that is, it is 300x150 fully transparent:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAxUlEQVR4nO3BMQEAAADCoPVPbQhfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOA1v9QAATX68/0AAAAASUVORK5CYII=
My guess is that you along the way saved an empty canvas as Data-URI using toDataURL() and is now using that for loading an image.
Try this URL instead and you will see it works (red image of 300x150):
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAACBUlEQVR4nO3UoQ0AIADEwN9/aVgBR5qcOF/Vne0AFOx3AMArwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CAjAsWoUTzPRjavAAAAABJRU5ErkJggg==
var myCanvas = document.getElementById('my_canvas_id');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
ctx.drawImage(img,0,0); // Or at whatever offset you like
};
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAACBUlEQVR4nO3UoQ0AIADEwN9/aVgBR5qcOF/Vne0AFOx3AMArwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CADMMCMgwLyDAsIMOwgAzDAjIMC8gwLCDDsIAMwwIyDAvIMCwgw7CAjAsWoUTzPRjavAAAAABJRU5ErkJggg==";
<canvas id="my_canvas_id"></canvas>
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(0,0,300,150);
document.write(c.toDataURL());
<canvas id="c"></canvas>

html5 canvas background image blur and resize

I have an idea of making a canvas the background with an image. The reason why I want the canvas element to be the background is because I would like to blur the image when the user is logged in. I think that would be a nice effect. And since I don't refresh the page I like it to animate a blurring effect. I am going to have multiple questions in here because they all rely on each other.
I have 2 ideas of how to make this. the first one will have a simple div tag with the background image set. then, when the user have logged in - a canvas element will be created by the script with the background image placed as in the div, then blur it and let it fade in over the div tag.
Another way would be to build the canvas element from the beginning and then let the image be set from the beginning.
This is how I make a background image.
var canvas = document.getElementById('bg_canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = '2.jpg';
Okay.. thats the easy part.. I need a way to make the height or width in the drawImage function set to auto. if the width is bigger than the height I want the height to be set to auto. I don't want the image to be stretched over the screen. How should I do that?
Now problem number 2. When the user resizes the screen, I would like to resize the image inside the canvas element as well. blurred or not blurred.
i assume it would be set to something like this:
$(document).ready(function() {
winResize();
$(window).resize(function() {
winResize());
}
});
function winResize() {
var canvas = document.getElementById('bg_canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0, canvas.height, canvas.width);
};
imageObj.src = '2.jpg';
}
Now I still need the auto mechanism for the height or width of the image.
I am not going to ask for the blur effect, since it should be able to find online somewhere, but what i would like to know is what you would recommend for me to do, when fading in the blurred version. I don't remember there should be a way to fade inside a canvas element, so perhaps I have to duplicate the already existing canvas and then blur and then fade in.
Load the plain image, use a canvas to create a blurred version of the image, then turn that into a real image again for use in an <img> or css background:
function blurImage(imgURL) {
var img = new Image();
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext("2d");
context.drawImage(img,0,0);
/*
code that actually blurs the image goes here
*/
var dataURI = canvas.toDataUrl("image/png");
setBlurredImage(dataURI);
};
img.src = imgURL;
}
with a set handler:
function setBlurredImage(dataURI) {
whateverElement.style.background = "url(" + dataURI + ")";
}
And now you have a background image that is blurred.

How to swap images on HTML without libraries (like z-index)

I have a question !
In a html5 canvas, I create an "x" number of images. The last image created is always above the other. Is it possible to swap the depths of the images without the need for libraries? (I do not intend to reverse the order of the variables)
I want somethin like this (without kinetic):
http://www.html5canvastutorials.com/kineticjs/html5-canvas-shape-layering-with-kineticjs/
so, here is the code I'm using:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 69, 50);
};
imageObj.src = "image1.png";
var imageObj2 = new Image();
imageObj2.onload = function() {
context.drawImage(imageObj2, 40, 30);
};
imageObj2.src = "image2.png";
/* I want to put "Image1.png" over "Image2.png" dynamically, for example, pressing a button, all this after render on the canvas */
Draw the furtherest images first. It might help to put the images in an array so you can just loop through them.
Otherwise, in the case of your example, this will fix it as you are drawing context.drawImage(imageObj, 69, 50); last. Think of it as if you would draw it on paper; what you draw last is above what you have already drawn.
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj2 = new Image();
imageObj2.onload = function() {
context.drawImage(imageObj2, 40, 30);
};
imageObj2.src = "image2.png";
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 69, 50);
};
imageObj.src = "image1.png";
The order you draw the images matters. You will need to draw the images in the back first, then draw the closer ones.
Why don't you create a canvas object for every image and either show / hide them or adjust the z-index?

Frame by frame animation in HTML5 with canvas

I have a flash animation I am trying to convert to HTML5. Now I have taken out all the images. For example in the hand animation, I have taken images of all hand images. I have made the canvas with the base drawing but I don't know how to replace those images frame by frame.
function draw(){
var canvas = document.getElementById('canvas');
if(canvas.getContext){
// canvas animation code here:
var ctx = canvas.getContext('2d');
var lhs = new Image();
lhs.src = "images/left_hnd_1.png";
lhs.onload = function(){
ctx.drawImage(lhs, 293, 137);
}
} else {
// canvas unsupported code here:
document.getElementById('girl').style.display = "block";
}
}
Now I have three more frame for this image. left_hnd_2.png, left_hnd_3.png & left_hnd_4.png. I would've used one image but the difference in frames is way too much for it to be done with one image. How can I animate this with the time differences I want.
Any ideas would be greatly appreciated. Thanks!
Try this:
var imgNumber = 1;
var lastImgNumber = 4;
var ctx = canvas.getContext('2d');
var img = new Image;
img.onload = function(){
ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
ctx.drawImage( img, 0, 0 );
};
var timer = setInterval( function(){
if (imgNumber>lastImgNumber){
clearInterval( timer );
}else{
img.src = "images/left_hnd_"+( imgNumber++ )+".png";
}
}, 1000/15 ); //Draw at 15 frames per second
An alternative, if you only have 4 images, would be to create a single huge image with all four in a 'texture atlas', and then use setTimeout or setInterval to call drawImage() with different parameters to draw different subsets of the image to the canvas.
This worked for me as well! For some reason, it didn't work when I had used the OP's opening code: function draw(){
However when I used: window.onload = function draw() { the animation plays on the canvas. I'm also using about 150 PNG images with an Alpha channel so this is a great way to bring 'video' or create composites to the iPad/iPhone. I confirm that it does work on iPad iOS 4.3.