How to render custom Class objects in HTML canvas - javascript

Solved Had to render the images globally outside of the draw method. Here's a link to the github if you find this question and are wondering what the solution looks like in the full code. Its a bit too long to post here as an update. github canvas orbs
back to the original question:
I'm trying to render custom Class objects inside an HTML canvas. Doesn't work with class, but the the same data works without class.
Here's the code:
import './styles/index.css';
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
var window_height = window.innerHeight;
var window_width = window.innerWidth;
canvas.width = 500;
canvas.height = 400;
canvas.style.background = "#232a2e"
const convertSVG = (svgid) => {
const svg = document.getElementById(svgid);
const xml = new XMLSerializer().serializeToString(svg);
const svg64 = btoa(xml);
const b64Start = 'data:image/svg+xml;base64, ';
return b64Start + svg64;
}
class Orb {
constructor(xpos, ypos, radius, speed, image) {
this.xpos = xpos;
this.ypos = ypos;
this.radius = radius;
this.speed = speed;
this.image = convertSVG(image);
}
draw(context) {
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
context.restore();
}
img.src = this.image;
}
}
const myOrb = new Orb(150, 150, 30, 1, 'javascript-icon');
myOrb.draw(context);
console.log(myOrb);
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(300, 300, 30, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (300-32), (300-32), 64, 64);
context.restore();
}
img.src = convertSVG('javascript-icon');
Currently it's only displaying the object I draw explicitly at the bottom of the code, and not the object of class Orb.
Here's a screen cap of the canvas:
current canvas render
EDIT: Additionally, I can generate a class object and draw the orb based on that. Like so:
const myOrb = new Orb(300, 300, 30, 1, 'javascript-icon');
const myOrb2 = new Orb(150, 150, 30, 1, 'java-icon');
const img = new Image();
img.onload = function() {
context.save();
context.beginPath();
context.arc(myOrb.xpos, myOrb.ypos, myOrb.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, (myOrb.xpos-myOrb.radius-2), (myOrb.ypos-myOrb.radius-2), 64, 64);
context.restore();
}
img.src = myOrb.imageSRC;
console.log(myOrb);
console.log(myOrb2);
myOrb2.draw(context);
myOrb renders, but myOrb2 which is drawn with the method of the class is not rendered.

Here's an approach to take. Load the images globally and call draw when image is loaded.
let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
var window_height = window.innerHeight;
var window_width = window.innerWidth;
canvas.width = 500;
canvas.height = 400;
canvas.style.background = "#232a2e"
const img1 = new Image();
img1.src = 'https://cdn.iconscout.com/icon/free/png-256/javascript-2752148-2284965.png';
const img2 = new Image();
img2.src = 'https://iconape.com/wp-content/png_logo_vector/cib-javascript.png'
class Orb {
constructor(xpos, ypos, radius, speed, image) {
this.xpos = xpos;
this.ypos = ypos;
this.radius = radius;
this.speed = speed;
this.image = image;
}
draw(context) {
context.save();
context.beginPath();
context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
context.clip();
context.drawImage(this.image, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
context.restore();
}
}
const myOrb = new Orb(150, 150, 30, 1, img1);
const myOrb2 = new Orb(350, 150, 30, 1, img2);
window.onload = function() {
myOrb.draw(context);
myOrb2.draw(context);
}
<canvas id="canvas"></canvas>

Related

Why won't my images appear on the canvas?

I want to draw many different sized circles with the same image on them using a prototype. The problem is, the circles don't appear with the images drawn on them.
The circles are still there because they're visible when stroke is used, but the images aren't drawn. I was able to have an arc be drawn with an image in it without the prototype but as soon as I use it, it doesn't work.
No bugs appear in the console, so it is not clear to me what I'm missing.
I've tried moving the event listener outside the prototype but the circle images still did not appear.
If anyone has any insight and perhaps a solution as to why this isn't working that they can share, that would be very much appreciated.
Here is the code:
const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
constructor(xPos, yPos, radius){
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
}
}
Balls.prototype.render = function(){
const img = document.createElement('img');
img.src = 'crystal.jpg';
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI*2)
ctx.stroke();
ctx.clip();
img.addEventListener('onload', function(e){
ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius,
this.radius*2, this.radius*2);
});
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
Here you go, i just changed 2 things here in order to make your code work.
load is used for eventlistener instead on onload.
use Arrow function in order to rely on the parent context instead of dynamic context(this).
const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
}
}
Balls.prototype.render = function() {
const img = document.createElement('img');
img.src = 'https://via.placeholder.com/150.png?text=vijay'
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
ctx.stroke();
ctx.clip();
img.addEventListener('load', (e) => {
ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius,
this.radius * 2, this.radius * 2);
});
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
You had two issues in your code. Firstly, the onload event should be load. Secondly, this is not known inside the event listener function, so this.radius etc. are all undefined and ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius,
this.radius*2, this.radius*2) doesn't work.
I used some variables for this.xPos, this.yPos, this.radius that can be used inside the event listener callback function.
Hope this helps!
const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
}
}
Balls.prototype.render = function() {
const img = new Image();
img.src = 'https://source.unsplash.com/random';
var xPos = this.xPos, yPos = this.yPos, radius = this.radius
ctx.arc(xPos, yPos, radius, 0, Math.PI * 2)
ctx.stroke();
ctx.clip();
img.addEventListener('load', function(e) {
console.log("load")
ctx.drawImage(img, xPos - radius, yPos - radius,
radius*2, radius*2);
});
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
This is an alternative way you can load images which is more modular, If you are making a game an Img class will come in handy.
Off-topic -
if you want to load multiple images then you can add atotalLoadedcounter to keep track of how many images has been loaded and if thetotalLoadedcount is equal tototalImagescount then you can call a callback which will fire the animationLoop and preloads all the images.
const ctx = document.getElementById('canvas').getContext('2d');
// Img class to provide modular code
class Img {
constructor(src, x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.src = src;
this.img = new Image();
this.img.src = this.src;
this.isLoaded = false;
this.img.addEventListener('load', (e) => {
this.isLoaded = true;
this.draw();
});
}
draw() {
if (this.isLoaded) {
ctx.drawImage(this.img, this.x, this.y, this.size, this.size);
}
}
}
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
}
}
Balls.prototype.render = function() {
let imgx = this.xPos - this.radius;
let imgy = this.yPos - this.radius;
let imgr = this.radius * 2;
let url = 'https://via.placeholder.com/150.png?text=Better';
const img = new Img(url, imgx, imgy, imgr);
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
ctx.stroke();
ctx.clip();
img.draw();
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>

THREE js best performance way to update texture generated Canvas

I have THREE.Points with THREE.PointsMaterial. As a map I use generated dynamic cavas image.
I need to re-render canvas on each frame.
my part of code:
function makeEnemyBaseLabel( n,d ) {
var canvas = document.createElement('canvas');
var context= canvas.getContext("2d");
var w = 5;
context.canvas.width = context.canvas.height = 128;
context.fillStyle = 'rgba(255,255,255,0.4)';
context.strokeStyle = 'rgba(255,255,255,0.5)';
context.beginPath();
context.moveTo(64-(w/2),64-w);
context.lineTo(64-w,64-w);
context.lineTo(64-w,64-(w/2));
context.stroke();
context.beginPath();
context.moveTo(64-w,64+(w/2));
context.lineTo(64-w,64+w);
context.lineTo(64-(w/2),64+w);
context.stroke();
context.beginPath();
context.moveTo(64+(w/2),64+w);
context.lineTo(64+w,64+w);
context.lineTo(64+w,64+(w/2));
context.stroke();
context.beginPath();
context.moveTo(64+w,64-(w/2));
context.lineTo(64+w,64-w);
context.lineTo(64+(w/2),64-w);
context.stroke();
context.textAlign="center";
context.font = "Normal 10px Sans-Serif";
context.fillText(formatDistance(d), 64, 85);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return new THREE.PointsMaterial( { visible: true, size: 128, color: 0xffffff, depthTest: false, depthWrite: false, opacity: 1, sizeAttenuation: false, transparent: true, map: texture } );
}
function updateEnemyBaseLabel( n,d,o ) {
var canvas = document.createElement('canvas');
var context= canvas.getContext("2d");
var w = 5;
context.canvas.width = context.canvas.height = 128;
if(d < 100) {
context.fillStyle = 'rgba(255,255,255,1)';
context.strokeStyle = 'rgba(255,255,255,1)';
} else
if(d < 1000) {
context.fillStyle = 'rgba(255,255,255,0.6)';
context.strokeStyle = 'rgba(255,255,255,0.7)';
} else {
context.fillStyle = 'rgba(255,255,255,0.4)';
context.strokeStyle = 'rgba(255,255,255,0.5)';
}
context.beginPath();
context.moveTo(64-(w/2),64-w);
context.lineTo(64-w,64-w);
context.lineTo(64-w,64-(w/2));
context.stroke();
context.beginPath();
context.moveTo(64-w,64+(w/2));
context.lineTo(64-w,64+w);
context.lineTo(64-(w/2),64+w);
context.stroke();
context.beginPath();
context.moveTo(64+(w/2),64+w);
context.lineTo(64+w,64+w);
context.lineTo(64+w,64+(w/2));
context.stroke();
context.beginPath();
context.moveTo(64+w,64-(w/2));
context.lineTo(64+w,64-w);
context.lineTo(64+(w/2),64-w);
context.stroke();
context.textAlign="center";
context.font = "Normal 10px Sans-Serif";
context.fillText(formatDistance(d), 64, 85);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
o.material.map = texture;
}
var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3() );
enemyShipMesh = new THREE.Points( geometry, makeEnemyBaseLabel( 1,1 ) );
scene.add(enemyShipMesh)
..
..
update() {
updateEnemyBaseLabel( 1,5,enemyShipMesh );
}
after some time i have a memory leak. I'm sure, that the reason is creating new and new textures in memory.
What is the best approach to update canvas in referenced object most optimal way?
I'm searching for something like :
var context = //new context without canvas creating?
context.fillText(formatDistance(d), 64, 85);
enemyShipMesh.material.map = context; // or most simple without creating a lot of new object each sec.
You're creating a canvas and all at every update, once you've created a canvas and the texture, you can go with just the canvas context in your update function and set texture.needsUpdate = true afterwards.

Javascript array of images move across canvas randomely

I am new to javascript and am trying to make an animation of snow for an assignment.
So far I have been able to create some small background snow (randomly sized circles) but I want to use some snowflake png files for more moving snow. This is what I have but I am pretty sure the image parts are pretty wrong.
Really not sure how to make this work so any tips would be greatly appreciated.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var colours = ["white", "azure", "floralwhite", "#EAEDED"];
var r = 3.5;
var snow = [];
for (var i=0;i<1000;i++){
var s = {
x : i*2,
y : 0,
colour : colours[Math.round(Math.random()*colours.length)],
dx : Math.random(),
dy : Math.random()*3,
}
snow.push(s);
}
var flakes = ["flak1", "flak2", "flak3"];
flak1 = new Image();
flak1.src = "snow1.png";
flak2 = new Image();
flak2.src = "snow2.png";
flak3 = new Image();
flak3.src = "snow3.png";
for (var e=0;e<10;e++){
var f = {
x: e*2,
y: 0,
image: flakes[Math.round(Math.random()*flakes.length)],
dx: Math.random(),
dy: 1,
}
flakes.push(f);
}
var grd = context.createLinearGradient(0,0,0,500);
grd.addColorStop(0, "#85C1E9");
grd.addColorStop(1, "#EBF5FB");
function itSnows(){
//draw background
context.fillStyle = grd;
context.fillRect(0,0,canvas.width,canvas.height);
context.fillStyle = "white";
context.fillRect(0,650,canvas.width,50);
house = new Image();
house.src = "house.png";
context.drawImage(house, 10, 490,200,200);
context.drawImage(house, 200, 490,300,200);
context.drawImage(house, 480, 490,250,200);
context.drawImage(house, 740, 490,200,200);
context.drawImage(house, 950, 490,250,200);
sun = new Image();
sun.src = "sun.png";
context.drawImage(sun,0,0,600,350);
//draw snow
for(var i=0;i<snow.length;i++){
context.fillStyle = snow[i].colour;
context.beginPath();
context.arc(snow[i].x,snow[i].y,r*Math.random(),0,2*Math.PI);
context.fill();
snow[i].y = (snow[i].y + snow[i].dy) % 700;
snow[i].x = (snow[i].x + snow[i].dx) % canvas.width;
//draw flakes
for (var e=0;e<flakes.length;e++){
context.drawImage(flakes[e], flakes[e].x, flakes[e].y, 30, 30);
flakes[e].y = (flakes[e].y + flakes[e].dy) % 700;
flakes[e].x = (flakes[e].x + flakes[e].dx) % canvas.width;
}
}
}
setInterval(itSnows, 25);

How would I fillRect with an image?

Normally you can fill a rectangle in a canvas withctx.fillStyle = "whatever color here" and then ctx.fillRect(cords and length and width here). Is there a syntax where I can say ctx.fillRect(someImagePathHere, xOfTopLeft, yofTopLeft)
If not, how else can I achieve this?
The question is ambiguous as there are many ways to "fillRect with an image".
First off images in the browser are downloaded asynchronously so you need to wait for an image to load before you can use it. For canvas situations the most common way to get an image is to create a new Image and set an onload listener
const img = new Image();
img.onload = someFunctionToCallWhenTheImageHasLoaded
img.src = 'http://url/to/image';
Then the question is what do mean by "fillRect"
Using this 256x256 image
For example to draw the image at the size it was downloaded you can use drawImage with 3 arguments
ctx.drawImage(img, x, y);
const img = new Image();
img.onload = draw;
img.src = 'https://i.imgur.com/ZKMnXce.png';
function draw() {
const ctx = document.querySelector('canvas').getContext('2d');
ctx.drawImage(img, 0, 0);
}
canvas { border: 1px solid black; }
<canvas></canvas>
To draw the image at a different size you can use
ctx.drawImage(img, x, y, width, height);
const img = new Image();
img.onload = draw;
img.src = 'https://i.imgur.com/ZKMnXce.png';
function draw() {
const ctx = document.querySelector('canvas').getContext('2d');
const destX = 10;
const destY = 20;
const destWidth = 30;
const destHeight = 40;
ctx.drawImage(img, destX, destY, destWidth, destHeight);
}
canvas { border: 1px solid black; }
<canvas></canvas>
To draw part of the image you can use
// part of image to draw
const srcX = 10;
const srcY = 20;
const srcWidth = 130;
const srcHeight = 140;
// where to draw it
const dstX = 60;
const dstY = 70;
const dstWidth = 160;
const dstHeight = 40;
ctx.drawImage(img, srcX, srcY, srcWidth, srcHeight,
dstX, dstY, dstWidth, dstHeight);
const img = new Image();
img.onload = draw;
img.src = 'https://i.imgur.com/ZKMnXce.png';
function draw() {
const ctx = document.querySelector('canvas').getContext('2d');
// part of image to draw
const srcX = 10;
const srcY = 20;
const srcWidth = 130;
const srcHeight = 140;
// where to draw it
const dstX = 60;
const dstY = 70;
const dstWidth = 160;
const dstHeight = 40;
ctx.drawImage(img, srcX, srcY, srcWidth, srcHeight,
dstX, dstY, dstWidth, dstHeight);
}
canvas { border: 1px solid black; }
<canvas></canvas>
That said, "fillRect" being ambiguous maybe you wanted to use the image as a pattern in which case you need to make a pattern out of it using createPattern
const pattern = ctx.createPatttern(img, 'repeat');
For these let's use this 16x16 pixel image
You can then use the pattern as your fillStyle as in
ctx.fillStyle = pattern;
ctx.fillRect(10, 20, 30, 40);
const img = new Image();
img.onload = draw;
img.src = 'https://i.imgur.com/fqgm8uh.png';
function draw() {
const ctx = document.querySelector('canvas').getContext('2d');
const pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(10, 20, 30, 40);
}
canvas { border: 1px solid black; }
<canvas></canvas>
Patterns are relative to the origin of the canvas which means if you just use ctx.fillRect (or any other fill) the pattern will match across fills.
ctx.fillRect(10, 20, 30, 40);
ctx.beginPath();
ctx.arc(50, 60, 25, 0, Math.PI * 2);
ctx.fill();
const img = new Image();
img.onload = draw;
img.src = 'https://i.imgur.com/fqgm8uh.png';
function draw() {
const ctx = document.querySelector('canvas').getContext('2d');
const pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(10, 20, 30, 40);
ctx.beginPath();
ctx.arc(50, 60, 25, 0, Math.PI * 2);
ctx.fill();
}
canvas { border: 1px solid black; }
<canvas></canvas>
Because patterns are anchored at the origin if you are animating without changing the origin you'll notice the pattern doesn't move
const img = new Image();
img.onload = start;
img.src = 'https://i.imgur.com/fqgm8uh.png';
function start() {
const ctx = document.querySelector('canvas').getContext('2d');
const pattern = ctx.createPattern(img, 'repeat');
function render(time) {
time *= 0.001; // seconds;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const x = Math.sin(time * 1.1) * 150 + 150;
const y = Math.sin(time * 1.2) * 50 + 50;
ctx.fillStyle = pattern;
ctx.fillRect(x, y, 30, 40);
ctx.beginPath();
ctx.arc(x, y, 25, 0, Math.PI * 2);
ctx.fill();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
canvas { border: 1px solid black; }
<canvas></canvas>
In order to move the pattern you need to move the origin of the canvas using ctx.translate (as well as ctx.rotate, ctx.scale, ctx.setTransform)
const img = new Image();
img.onload = start;
img.src = 'https://i.imgur.com/fqgm8uh.png';
function start() {
const ctx = document.querySelector('canvas').getContext('2d');
const pattern = ctx.createPattern(img, 'repeat');
function render(time) {
time *= 0.001; // seconds;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const x = Math.sin(time * 1.1) * 150 + 150;
const y = Math.sin(time * 1.2) * 50 + 50;
ctx.translate(x, y);
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 30, 40);
ctx.beginPath();
ctx.arc(0, 0, 25, 0, Math.PI * 2);
ctx.fill();
ctx.setTransform(1, 0, 0, 1, 0, 0); // set it back to the default
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
canvas { border: 1px solid black; }
<canvas></canvas>
Here's an illustration of some of the possibilities:
var im = new Image();
im.src = "https://upload.wikimedia.org/wikipedia/commons/7/79/Face-smile.svg";
im.onload = function () { /* first, wait until the image is loaded */
/* create five canvases, and draw something in each */
for (var i=1; i<=5; i++) {
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = canvas.height = 200;
var ctx=canvas.getContext("2d");
var x=50, y=50; /* where to plot */
var w=20, h=60; /* width and height of rectangle, if applicable */
switch (i) {
case 1:
/* first canvas: draw a rectangle */
ctx.fillRect(x, y, w, h);
break;
case 2:
/* second canvas: draw an image, actual size, no clipping */
/* coordinates are where the top left of the image is plotted */
ctx.drawImage(im, x, y);
break;
case 3:
/* third canvas: draw an image, scaled to rectangle */
ctx.drawImage(im, x, y, w, h);
break;
case 4:
/* fourth canvas: draw an image, actual size, clipped to rectangle */
ctx.save();
ctx.rect(x, y, w, h);
ctx.clip();
ctx.drawImage(im, x, y);
ctx.restore();
break;
case 5:
/* fifth canvas: draw shapes filled with a background image */
ctx.fillStyle = ctx.createPattern(im, 'repeat'); /* or 'no-repeat', or 'repeat-x', or 'repeat-y' */
/* note that the image is tiled from the top left of the canvas */
ctx.fillRect(x, y, w, h);
/* also draw a circle, why not */
ctx.beginPath();
ctx.arc(150, 150, 40, 0, Math.PI*2);
ctx.fill();
break;
}
}
}
im.onerror = function() { alert("failed to load image"); };
Jsfiddle: http://jsfiddle.net/efeqjjno/
Here is a quick example of how you can use drawImage to draw an image to a canvas. The element on the left is the image, the element on the right is the canvas with the image drawn on it.
JSFiddle: https://jsfiddle.net/gw8ncg7g/
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("image");
ctx.drawImage(img, 0, 0);
}
canvas {
border:1px solid #d3d3d3;
}
<img id="image" width="300" height="300" src="http://i.imgur.com/LDR6AWn.png?1">
<canvas id="myCanvas" width="300" height="300" >

HTML5 / JavaScript Canvas: Text on Image on Click

StackOverflow community, I'm fairly new to JavaScript programming and I'm having some issues with the HTML5/JavaScript Canvas Combo.
The idea is to, following the click of a button, to verify some lines and, then, show on the screen the image (pre-defined) with some text in specific coordinates, the text depends on the input value, as they are stored in an Array.
The thing is, I'm not being able to draw the text on the Image, only the Image appears. The code goes as follows:
Globally Defined:
...
canvas = document.getElementById("cvs"),
ctx = canvas.getContext('2d'),
...
The Draw() function:
function draw() {
if (img_is_loaded) {
img = document.getElementById("background-A");
var maxh = 600,
maxw = 900,
height = img.height,
width = img.width,
name_input = name[0],
note_input = note[0],
date_input = date[0],
sur_input = sur[0];
while (height > maxh || width > maxw) {
--height;
--width;
}
canvas.height = height;
canvas.width = width;
ctx.save();
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
ctx.font = "54px Times Roman";
ctx.fillStyle = "#000000";
ctx.fillText = (name_input, 35, 320);
ctx.font = "21px Times Roman";
ctx.fillStyle = "#000000";
ctx.fillText = (note_input, 61, 432);
ctx.fillText = (date_input, 254, 501);
ctx.fillText = (sur_input, 254, 528);
}
} else {
setTimeout(draw, 100);
}
}
I'm getting the Image, but no text. I'm aware that the issue, normally, is that I need to draw them "at the same time", so I tried:
function draw() {
if (img_is_loaded) {
var imageObj = new Image();
imageObj.onload = function(){
var maxh = 600,
maxw = 900,
height = imageObj.height,
width = imageObj.width,
name_input = name[0],
note_input = note[0],
date_input = date[0],
sur_input = sur[0];
while (height > maxh || width > maxw) {
--height;
--width;
}
canvas.height = height;
canvas.width = width;
ctx.save();
ctx.clearRect(0, 0, width, height);
$('#spinner-generate').hide();
ctx.drawImage(imageObj, 0, 0, width, height);
ctx.font = "54px Times Roman";
ctx.fillStyle = "#000000";
ctx.fillText = (name_input, 35, 320);
ctx.font = "21px Times Roman";
ctx.fillStyle = "#000000";
ctx.fillText = (note_input, 61, 432);
ctx.fillText = (date_input, 254, 501);
ctx.fillText = (sur_input, 254, 528);
ctx.restore();
}
imageObj.src = "IMAGEPATH";
} else {
setTimeout(draw, 100);
}
}
But, in this case, the "imageObj.onload" function gets skipped by the code, that automatically jumps to "else".
I'm really confused at this point, since every source I consulted says that it is "simple" and uses the imageObj.onload example, but with the "window.onload" combination.
Is there something I'm missing regarding the Canvas' "Order of things"?
I appreciate and thank in advance for any response or input.
You're using fillText as a property while it should have been used as a method - simply change the lines to this format:
ctx.fillText(name_input, 35, 320);
I did not check the rest of the code.

Categories