Each new image should be with different src. Untill reloading all images have single src. It is can be add location.reload(); until adding new image, then scr will change. But reloading very seen. Does it exist way to reload only scr?
var cvs;
var ctx;
cvs = document.getElementById("canvas");
ctx = cvs.getContext("2d");
var width_path_near = 80,
width_path_far = 30;
var tree1 = new Image();
var tree2 = new Image();
var tree3 = new Image();
var tree4 = new Image();
tree1.src = "https://png.pngtree.com/element_origin_min_pic/00/02/61/6156839a2a633b7.jpg";
tree2.src = "http://s02.yapfiles.ru/files/457732/derevo_1.png";
tree3.src = "http://www.grafamania.net/uploads/posts/2014-06/1401644723_1-9.jpg";
tree4.src = "http://img11.txapela.ru/e/c/c/4/f/52e052f118c7b8ff9317385f581.jpg";
var masTree=[tree1, tree2, tree3, tree4];
var randTree=Math.floor(Math.random()*masTree.length);
var tree_size = 100;
var grow = 0.2;
var gap = 100;
var forest = [];
forest[0] = {
x : cvs.width/2-width_path_near-tree_size/2,
y : cvs.height/2-tree_size+10,
size : tree_size
}
function draw() {
ctx.fillStyle = "rgb(84,209,216)";
ctx.fillRect(0, 0, 1000, 600);
for (var i=0; i<forest.length; i++){
ctx.drawImage(masTree[randTree], forest[i].x, forest[i].y, forest[i].size, forest[i].size);
if(forest[i].y == 3*cvs.height/4){
forest.push({
y : cvs.height/2-tree_size+10,
x : cvs.width/2-width_path_near-tree_size/2,
size : tree_size
});
}
forest[i].y += 0.5;
forest[i].x -= 0.4;
forest[i].size += 0.4;
}
requestAnimationFrame(draw);
}
masTree[randTree].onload = draw;
http://jsfiddle.net/Nata_Hamster/ugyb1fd0/
I need to draw images in their own canvas. What am I doing wrong?
If I delete the "for loop" the code works just fine (e.g: set var i=0, then img[0] is drawn in canv[0]).
window.onload = function() {
var canv = [];
var ctx = [];
var img = [];
var info = [{"url":"1.jpg"},{"url":"2.jpg"},{"url":"3.jpg"}];
for(i=0; i< 3; i++){
canv[i] = document.createElement('canvas');
canv[i].width = 460;
canv[i].height = 620;
canv[i].style.border = "1px solid";
document.body.appendChild(canv[i]);
img[i] = new Image();
img[i].src = info[i].url;
ctx[i] = canv[i].getContext("2d");
img[i].onload = function(){
ctx[i].drawImage(img[i], 10, 70, 440,440);
}
}
}
Found the solution, just in case somebody has the same problem:
(function (_i) {
img[_i] = new Image();
img[_i].src = info[_i].url;
img[_i].onload = function () {
ctx[_i].drawImage(img[_i], 10, 70, 440,440);
};
})(i);
I have a little problem, sometimes work or not work drawimage, i tried to begin with draw background and if drawed then next draw 9 images(sometimes images is this same or not same).
var c = document.getElementById('myCanvas');
var ctx = c.getContext("2d");
$('button').on('click',function(){
var img = new Image();
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
var img4 = new Image();
var img5 = new Image();
var img6 = new Image();
var img7 = new Image();
var img8 = new Image();
var img9 = new Image();
img.src = $(location).attr('href')+'/img/frames/'+$('#frames option:selected').val();
img1.src = $(location).attr('href')+'/img/mercmain/'+$('#merc1 option:selected').val();
img2.src = $(location).attr('href')+'/img/mercmain/'+$('#merc2 option:selected').val();
img3.src = $(location).attr('href')+'/img/mercmain/'+$('#merc3 option:selected').val();
img4.src = $(location).attr('href')+'/img/mercmain/'+$('#merc4 option:selected').val();
img5.src = $(location).attr('href')+'/img/mercmain/'+$('#merc5 option:selected').val();
img6.src = $(location).attr('href')+'/img/mercmain/'+$('#merc6 option:selected').val();
img7.src = $(location).attr('href')+'/img/mercmain/'+$('#merc7 option:selected').val();
img8.src = $(location).attr('href')+'/img/mercmain/'+$('#merc8 option:selected').val();
img9.src = $(location).attr('href')+'/img/mercmain/'+$('#merc9 option:selected').val();
img.onload = function(){
ctx.clearRect(0, 0, c.width, c.height);
ctx.drawImage(img, 0, 0,307,382);
img1.onload = function(){
ctx.drawImage(img1,$xyframe[0][0],$xyframe[0][1],$xyframe[0][2],$xyframe[0][3]);
};
img2.onload = function(){
ctx.drawImage(img2,$xyframe[1][0],$xyframe[1][1],$xyframe[1][2],$xyframe[1][3]);
};
img3.onload = function(){
ctx.drawImage(img3,$xyframe[2][0],$xyframe[2][1],$xyframe[2][2],$xyframe[2][3]);
};
img4.onload = function(){
ctx.drawImage(img4,$xyframe[3][0],$xyframe[3][1],$xyframe[3][2],$xyframe[3][3]);
};
img5.onload = function(){
ctx.drawImage(img5,$xyframe[4][0],$xyframe[4][1],$xyframe[4][2],$xyframe[4][3]);
};
img6.onload = function(){
ctx.drawImage(img6,$xyframe[5][0],$xyframe[5][1],$xyframe[5][2],$xyframe[5][3]);
};
img7.onload = function(){
ctx.drawImage(img7,$xyframe[6][0],$xyframe[6][1],$xyframe[6][2],$xyframe[6][3]);
};
img8.onload = function(){
ctx.drawImage(img8,$xyframe[7][0],$xyframe[7][1],$xyframe[7][2],$xyframe[7][3]);
};
img9.onload = function(){
ctx.drawImage(img9,$xyframe[8][0],$xyframe[8][1],$xyframe[8][2],$xyframe[8][3]);
};
};
});
and link to test script https://tajkjs-olszam.c9users.io/genform/
and if i remove from img1-9.onload, leave ctx.drawimage(img1-9) and make settimeout from 3 to 5 sec then it's ok but i want without settimeout.
setTimeout(function(){
//img.onload = function(){
ctx.drawImage(img, 0, 0,307,382);
// };
ctx.drawImage(img1,$xyframe[0][0],$xyframe[0][1],$xyframe[0][2],$xyframe[0][3]);
ctx.drawImage(img2,$xyframe[1][0],$xyframe[1][1],$xyframe[1][2],$xyframe[1][3]);
ctx.drawImage(img3,$xyframe[2][0],$xyframe[2][1],$xyframe[2][2],$xyframe[2][3]);
ctx.drawImage(img4,$xyframe[3][0],$xyframe[3][1],$xyframe[3][2],$xyframe[3][3]);
ctx.drawImage(img5,$xyframe[4][0],$xyframe[4][1],$xyframe[4][2],$xyframe[4][3]);
ctx.drawImage(img6,$xyframe[5][0],$xyframe[5][1],$xyframe[5][2],$xyframe[5][3]);
ctx.drawImage(img7,$xyframe[6][0],$xyframe[6][1],$xyframe[6][2],$xyframe[6][3]);
ctx.drawImage(img8,$xyframe[7][0],$xyframe[7][1],$xyframe[7][2],$xyframe[7][3]);
ctx.drawImage(img9,$xyframe[8][0],$xyframe[8][1],$xyframe[8][2],$xyframe[8][3]);
},100);
this code is work but unfortunately I have use settimeout
Try not to draw on each image load. Use counter for loaded images and run draw function on last load. Also Pablo said right thing - set onload listener before set source. This code should run inside your click listener function
var img;
var counter = 0;
var imagesLength = 9;
var images = [];
var backgroundImage = new Image();
var imgFolder = location.href+'/img/mercmain/';
function drawImages(){
ctx.clearRect(0, 0, c.width, c.height);
ctx.drawImage(backgroundImage, 0, 0,307,382); //draw background
for ( var i=0; i<imagesLength ; i++ ){ //draw images
ctx.drawImage(images[i],$xyframe[i][0],$xyframe[i][1],$xyframe[i][2],$xyframe[i][3]);
}
}
function onLoad(){
counter++;
if( counter === imagesLength + 1 ){ // +1 - we must count also background image
drawImages(); // draw all the images at once
}
}
for ( var i=0; i<imagesLength ; i++ ){
img = new Image();
images.push( img ); // push in array before src,
// onload should not fire while image is not in array
img.onload = onLoad; // set onload before src,
// image should not load before onload listener is set
img.src = imgFolder + $('#merc'+ (i+1) +' option:selected').val();
}
// do not forget to set the same for background image
backgroundImage.onload = onLoad;
backgroundImage.src = location.href + '/img/frames/' + $('#frames option:selected').val();
You have a race condition: You are loading all the images at the same time, but if the background image is not the first one to be loaded, you are adding the onload listeners AFTER the images have been loaded, so the event has already happened and the drawing logic is never executed.
Solution? the imgN.onload=function() {...} assignments should be outside the img.onload function:
$('button').on('click',function(){
var img = new Image();
var imgArr=[];
for (var i=0;i<9;i++) {
imgArr[i]=new Image();
}
img.src = $(location).attr('href')+'/img/frames/'+$('#frames option:selected').val();
for (var i=0;i<9;i++) {
imgArr[i].src=$(location).attr('href')+'/img/mercmain/'+$('#merc'+i+' option:selected').val();
}
img.onload = function(){
ctx.clearRect(0, 0, c.width, c.height);
ctx.drawImage(img, 0, 0,307,382);
}
//Here, instead in the previous function
for (var i=0;i<9;i++) {
imgArr[i].onload = function(){
ctx.drawImage(img1,$xyframe[i][0],$xyframe[i][1],$xyframe[i][2],$xyframe[i][3]);
};
}
});
I have researched issues with the base64 conversion and jspdf function quite a bit. ( PS this is my first question on stackoverflow, please bare with any rookie mistakes ).
All seems to work fine with the below code except that the pdf is generated and saved before the loop where the images are converted to base64 and placed to the document is finished. I added a couple alerts to check timing. Would the solution be to check when the loop is finished, the images placed before continuing with the pdf function? if so, how? please help.
$(document).ready(function(){
$("a#getdoc").click(function(){
var doc = new jsPDF('landscape, in, legal');
var myimages = 'img1.jpg|img2.jpg|img3.png';
var myimgarray = myimages.split('|');
function convertImgToBase64(url, callback, outputFormat){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
return canvas.toDataURL("image/jpeg");
var dataURL = canvas.toDataURL("image/jpeg");
callback(dataURL);
canvas = null;
}
for(var i = 0; i < myimgarray.length; i++)
{
icount.count = i;
var img = new Image();
alert(checkoutimgarray);
img.src = '/Portals/0/repair-images/' + myimgarray[i];
img.onload = function(){
newData = convertImgToBase64(img);
alert(newData);
doc.addImage(newData, 'JPEG', (icount * 100), 10, 70, 15); // would doc be undefined here? out of scope?
};
}
doc.setFontSize(20);
doc.text(100, 20, "This is a test to see if images will show");
doc.save('My_file.pdf');
});
});
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
function convertImgToBase64(img, outputFormat){
// clear canvas
canvas.width = img.width;
canvas.height = img.height;
// draw image
ctx.drawImage(img, 0, 0);
// get data url of output format or defaults to jpeg if not set
return canvas.toDataURL("image/" + (outputFormat || "jpeg"));
}
var images = [];
for(var i = 0; i < myimgarray.length; i++) {
var img = new Image();
img.onload = function() {
images.push({
base64: convertImgToBase64(this),
width: this.width,
height: this.height
});
// all images loaded
if(images.length === myimgarray.length) {
for(var j = 0; j < images.length; j++) {
doc.addImage(images[j].base64, 'JPEG', (j * 100), 10, 70, 15);
}
doc.setFontSize(20);
doc.text(100, 20, "This is a test to see if images will show");
doc.save('My_file.pdf');
}
};
img.src = '/Portals/0/repair-images/' + myimgarray[i];
}
I am trying to draw an array of images to the canvas element, my data:image is returning an empty image.
var imgArray = ['images/image1.png','images/image2.png'];
for(i = 0; i < 2; i++){
var canvas = document.getElementById('textCanvas');
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.setAtX = i * 10;
imageObj.setAtY = i * 10;
imageObj.onload = function() {
context.drawImage(this, this.setAtX, this.setAtY);
};
}
img = canvas.toDataURL("image/png");
You never set the images' source:
var imageObj = new Image();
imageObj.src = imgArray[i]; // << addeed
imageObj.setAtX = i * 10;
imageObj.setAtY = i * 10;
imageObj.onload = function() {
context.drawImage(this, this.setAtX, this.setAtY);
};