Load Image in only one canvas - javascript

UPDATED
I have an HTML code below:
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
I have a function below:
var Context;
function onSign(canvas){
var ctx = document.getElementById(canvas).getContext('2d');
SigWebSetDisplayTarget(ctx);
tmr = setInterval(SigWebRefresh, 50);
}
function SigWebSetDisplayTarget( obj ){
Context = obj;
}
I called the function OnSign twice with different canvas id parameters.
OnSign('canvas1');
OnSign('canvas2');
Below is the SigWebRefresh function that is repeatedly called for a reason.
function SigWebRefresh(){
xhr2 = new XMLHttpRequest();
requests.push(xhr2);
xhr2.open("GET", baseUri + "SigImage/0", true );
xhr2.responseType = "blob"
xhr2.onload = function (){
var img = new Image();
img.src = 'image.jpg';
img.onload = function (){
Ctx.drawImage(img, 0, 0);
revokeBlobURL( img.src );
img = null;
}
}
xhr2.send(null);
}
After that, I noticed that the two canvas was being updated and the image is loaded to the 2 canvas. Why is it? I have to load the image, only to the last canvas I supplied with the function OnSign. Where am I missing?

var Context; is declared in global scope
OnSign('canvas1');
OnSign('canvas2');
Doing so you are assigning value of canvas number two.
Update: http://jsfiddle.net/bmynvtLd/2/
This is what you desired to update both contexts? if yes this is how you pass the parameter to setInterval function: setInterval(function() {SigWebRefresh(ctx)}, 300);
running example:
var images = ['http://img09.deviantart.net/6d02/i/2015/284/0/b/beginning_autumn_by_weissglut-d9cssxw.jpg', 'http://orig06.deviantart.net/063c/f/2013/105/3/6/free_crystal_icons_by_aha_soft_icons-d61tfi1.png', 'http://img15.deviantart.net/b126/i/2015/118/c/1/this_small_tree_by_weissglut-d8re8q7.jpg', 'http://img00.deviantart.net/84f8/i/2015/284/d/f/nuclear_light_by_noro8-d9cs4u6.jpg'];
function OnSign(canvas){
var ctx = document.getElementById(canvas).getContext('2d');
tmr = setInterval(function() {SigWebRefresh(ctx)}, 300);
}
OnSign('canvas1');
OnSign('canvas2');
var index = 0;
function MyIndex()
{
// console.log(index);
index = images.length == index ? 0 : index+1;
return images[index];
}
function SigWebRefresh(Context){
var img = new Image();
img.src = MyIndex();
img.onload = function (){
Context.drawImage(img, 0, 0);
img = null;
}
}

Related

onload function being skipped

I have my main function which calls my loadtexture function that loads two images and returns a base64 encode of the combined image but it keeps skipping my onload functions when it's trying to load the images.
$(document).ready(function () {
var modelPath = "models/testhiddenUV.obj";
var texture = loadTexture();
loadModel(texture, modelPath, "designCanvas");
});
function loadTexture() {
var frontImage = new Image();
var backImage = new Image();
var canvas = document.getElementById("designCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FFF";
ctx.fillRect(0,0,1024,1024);
//skips whole onload functions to the end
frontImage.onload = function() {
frontImage.src = "models/wine.jpg";
ctx.drawImage(frontImage,0,0);
backImage.onload = function() {
backImage.onload = "models.petro21.jpg";
ctx.drawImage(backimage, 804, 0);
return canvas.toDataUrl("image/png");
}
}
To me the code looks right and should execute, am I missing something with the onload function? Why does it skip those lines of code?
.onload
is an asynchronous call-back. And you have to call it in order for it to run.
So basically:
frontImage.onload = function() {
ctx.drawImage(frontImage,0,0);
}
frontImage.src = URL.createObjectURL("models/wine.jpg");
backImage.onload = function() {
ctx.drawImage(backimage, 804, 0);
}
backImage.src = URL.createObjectURL("whateverURIyouhave");

Canvas Clearing After Multiple DrawImage

I have been trying to draw a tile-like map to the canvas, although if i try to draw the same sprite twice, it will only render the final call of drawImage. Here is my code if it helps :
window.onload = function(){
function get(id){
return document.getElementById(id);
}
var canvas = get("canvas");
ctx = canvas.getContext("2d");
canvas.width = 160;
canvas.height = 160;
grass = new Image();
water = new Image();
grass.src = "res/Grass.png";
water.src = "res/Water.png";
path = {
draw: function(image,X,Y){
X = (X*32)-32;
Y = (Y*32)-32;
image.onload = function(){
ctx.drawImage(image,X,Y);
}
},
}
path.draw(water,2,2);
path.draw(grass,1,2);
path.draw(grass,1,1);
path.draw(water,2,1);
}
You're overwriting onload on the image next time you call it.
Think of it this way:
var image = {
onload: null
};
// Wait for the image to "load"
// Remember, onload is asynchronous so it won't be called until the rest of
// your code is done and the image is loaded
setTimeout(function() {
image.onload();
}, 500);
image.onload = function() {
console.log('I will never be called');
};
image.onload = function() {
console.log('I overwrite the previous one');
};
Instead, you might try waiting for your images to load then do the rest of your logic.
var numOfImagesLoading = 0;
var firstImage = new Image();
var secondImage = new Image();
// This is called when an image finishes loading
function onLoad() {
numOfImagesLoading -= 1;
if (numOfImagesLoading === 0) {
doStuff();
}
}
function doStuff() {
// This is where you can use your images
document.body.appendChild(firstImage);
document.body.appendChild(secondImage);
}
firstImage.src = 'http://placehold.it/100x100';
firstImage.onload = onLoad;
numOfImagesLoading += 1;
secondImage.src = 'http://placehold.it/200x200';
secondImage.onload = onLoad;
numOfImagesLoading += 1;

javascript drawImage() issues

Currently having some issues with drawImage();. Namely it wont actually draw. I tried it out with fillRect(); and it worked aswell as putting the drawImage(); inside the the onload function aswell (which worked).
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 640;
canvas.height = 400;
document.body.appendChild(canvas);
var tileArray = [
[0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,0,0,1,0,0,0],
[0,0,0,1,1,1,1,0,1,1,1,0,0],
[0,0,0,1,1,1,0,0,0,0,1,1,0],
[0,0,0,1,1,1,0,0,0,0,0,0,0],
[0,0,0,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,1,1,0,0,0,0,0]
];
var grassReady = false;
var grass = new Image();
grass.onload = function() {
grassReady = true;
};
grass.src = "images/grass.png";
var sandReady = false;
var sand = new Image();
sand.onload = function() {
sandReady = true;
};
sand.src = "images/sand.png";
var posX = 0;
var posY = 0;
if(grassReady) {
ctx.drawImage(grass, posX, posY);
}
Any pointers as to why this is would be greatly appreciated and I appologize in advance if messed up the code section in anyway. I went through other similar posts and coulden't find a solution that seemed to work.
As #Suman Bogati correctly says, you must wait for your images to load before using them in drawImage.
A Demo: http://jsfiddle.net/m1erickson/jGPGj/
Here's an image loader that preloads all images and then calls the start() function where you can use drawImage because all the images are fully loaded.
var imageURLs=[]; // put the paths to your images here
var imagesOK=0;
var imgs=[];
imageURLs.push("images/grass.png");
imageURLs.push("images/sand.png");
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
// grass.png is in imgs[0]
// sand.png is in imgs[1]
}
This statement ctx.drawImage(); should be inside the grass.onload = function() {} function, something like
grass.onload = function() {
ctx.drawImage(grass, posX, posY);
}
If you define drawImage() outside the grass.onload() function, then that statment would executed first, so at that point grassReady is false, So the condition is not satisfied.
Bascially it's related to asynchronous concept.
Your code is running into order
1) First
var grassReady = false;
if(grassReady) {
//grassReady is false, this condition is not satisfied
ctx.drawImage(grass, posX, posY);
}
2) Second
grass.onload = function() {
grassReady = true;
};

Canvas to data url not working properly

I have a function that takes an img-element and returns a data url. This works like 7/10 times and returns a blank image 3/10 times. I view the created data url through my browser(chrome) and use the same images so I know that this function is returning broken images. Can anyone spot why?
function imgToDataURL(img) {
var canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var c = canvas.getContext('2d');
c.drawImage(img, 0, 0);
dataurl = canvas.toDataURL();
return dataurl;
}
$(function() {
img = new Image();
img.crossOrigin = '';
img.onload = function() {
newimg = new Image();
newimg.onload = function() {
document.body.appendChild(newimg);
}
newimg.src = imgToDataURL(img);
}
img.src = 'https://somedomain.s3.amazonaws.com/someimg.png';
});
This example works most of the time but sometimes ends with a large white rectangle instead of the image.
You have to wait for images to load before drawing them using .drawImage function.
Only after the image is loaded by the browser you can call your imgToDataURL function.
Something like this:
var image_sources = ["img1.png", "img2.png", "..."];
for(var i=0; i<image_sources.length; i++) {
var new_img = document.createElement("img");
new_img.onload = function() {
imgToDataURL(this);
};
new_img.src = image_sources[i];
}

How do I get alerted in Javascript that an image's dimensions are available?

I need to be able to wait to start a function until the height and width of an image are available. When this code calls start(), it still says the height and width are zero:
var img = new Image();
init = function() {
img.onload = this.start();
img.src = "sky.jpg";
}
start = function() {
alert("Start called.\nwidth:"+img.width+"\nheight"+img.height);
}
init();
How can I make it wait until the dimensions are available before calling start()?
var img = new Image();
var start = function() {
alert("Start called.\nwidth:"+img.width+"\nheight"+img.height);
}
var init = function() {
img.onload = start;
img.src = "sky.jpg";
}
init();
Change this.start() to start.
I also scoped your functions.

Categories