class does not draw on Canvas - javascript

I've been trying to draw on a canvas using the new Ecma6 class system, however after alot of research it just doesn't want to work. I'm passing the context as a paramater of the draw function, even when I log context it doesn't say it's empty or undefined.
Can any of you nice people help me?
This is my code:
class Canvas {
constructor() {
this.canvas = document.getElementById('canvas');
this.context = this.canvas.getContext('2d');
this.width = this.canvas.width;
this.height = this.canvas.height;
this.components = [];
}
draw() {
this.context.clearRect(0, 0, this.width, this.height);
this.context.globalCompositeOperation = 'hard-light';
this.components.map(e => e.draw(this.context));
window.requestAnimationFrame(this.draw.bind(this));
}
add(e) {
this.components.push(e);
this.components.sort(function (a, b) {
return a.layer - b.layer;
});
}
listeners() {
window.addEventListener('resize', () => {
this.width = this.canvas.width;
this.height = this.canvas.height;
}, false);
}
init() {
this.listeners();
this.draw();
}
}
class CanvasElement {
constructor(x, y, height, width, layer) {
this.position = {
x: x,
y: y
}
this.height = height;
this.width = width;
this.layer = layer;
this.color = "grey";
}
draw(context) {
context.fillStyle = this.color;
context.fillRect(this.x, this.y, this.width, this.height);
}
}
class CanvasImage extends CanvasElement {
constructor(x, y, image, context) {
super(x, y, image.width, image.height, 0);
let self = this;
this.image = new Image();
this.image.onload = function () {
self.imageReadyToUse = true;
self.width = this.width;
self.height = this.height;
}
this.image.src = image;
this.imageReadyToUse = false;
}
draw(context) {
if (this.imageReadyToUse) {
context.drawImage(this.image, this.x, this.y);
}
}
}

Your error lies on the position in the drawImage method.
Your this.x and this.y values are undefined.
Here is a working example:
var imageURL = "data:image/gif;base64,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";
class Canvas {
constructor() {
this.canvas = document.getElementById('canvas');
this.context = this.canvas.getContext('2d');
this.width = this.canvas.width;
this.height = this.canvas.height;
this.components = [];
}
draw() {
this.context.clearRect(0, 0, this.width, this.height);
this.context.globalCompositeOperation = 'hard-light';
this.components.map(e => e.draw(this.context));
window.requestAnimationFrame(this.draw.bind(this));
}
add(e) {
this.components.push(e);
this.components.sort(function (a, b) {
return a.layer - b.layer;
});
}
listeners() {
window.addEventListener('resize', () => {
this.width = this.canvas.width;
this.height = this.canvas.height;
}, false);
}
init() {
this.listeners();
this.draw();
}
}
class CanvasElement {
constructor(x, y, height, width, layer) {
this.position = {
x: x,
y: y
}
this.height = height;
this.width = width;
this.layer = layer;
this.color = "grey";
}
draw(context) {
context.fillStyle = this.color;
context.fillRect(this.x, this.y, this.width, this.height);
}
}
class CanvasImage extends CanvasElement {
constructor(x, y, size, context) {
super(x, y, size.width, size.height, 0);
let self = this;
this.context = context;
this.image = new Image();
this.image.onload = function () {
self.imageReadyToUse = true;
self.width = this.width;
self.height = this.height;
self.draw();
}
this.image.src = imageURL;
this.imageReadyToUse = false;
}
draw() {
if (this.imageReadyToUse) {
console.log("YOU ARE UNDEFINED:", this.x, this.y);
this.context.drawImage(this.image, 0, 0, 61, 68);
}
}
}
var canvas = new Canvas();
var canvasImage = new CanvasImage(0, 0, {width:61, height:68}, canvas.context);
canvasImage.draw();
<canvas style="border:1px solid grey" id="canvas" width="400" height="400"></canvas>
sdsdc

So I found out what the problem was. Instead of using this.x and this.y, I had to use this.position.x and this.position.y.
Thank you for your help!

Related

Javascript canvas drawimage() doesn't work after using clearrect() [duplicate]

This question already has answers here:
Flickering images in canvas animation
(2 answers)
Closed 1 year ago.
I try to make an animation using the following code:
var obst = new Obstacle(x, y)
obst.build()
function animate() {
ctx.clearRect(0, 0, innerWidth, innerHeight);
requestAnimationFrame(animate);
obst.update(-1, 0)
player1.build();
}
but obst var doesn't appear (but player1 appears)
class for obst:
class Obstacle {
constructor(x, y) {
this.x = x;
this.y = y;
}
build() {
var img = new Image();
img.src = 'assests/obst.png';
img.onload = () => {
ctx.drawImage(img, this.x, this.y, 60, 60);
}
}
update(x, y) {
this.x += x;
this.y += y;
this.build()
}
}
When I run the code without clearrect() syntax it shows as it should be.
Full code:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, innerWidth, innerHeight);
obst.update(-1, 0)
player1.build();
}
class Player {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
build() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
ctx.fillStyle = this.color;
ctx.fill();
}
update(x, y) {
this.x += x
this.y += y
this.build()
}
}
class Obstacle {
constructor(x, y) {
this.x = x;
this.y = y;
}
build() {
var img = new Image();
img.src = 'assests/obst.png';
img.onload = () => {
ctx.drawImage(img, this.x, this.y, 60, 60);
}
}
update(x, y) {
this.x += x;
this.y += y;
this.build()
}
}
var obst = new Obstacle(canvas.width, canvas.height / 2 - 30)
obst.build()
var player1 = new Player(canvas.width / 2, canvas.height / 2, 30, 'blue');
player1.build();
animate();
The async task of loading the image should be removed from the update loop. Have the objects follow a pattern where building and updating / drawing are independent, and where building is async and happens once...
class Obstacle {
constructor(x, y) {
this.x = x;
this.y = y;
}
// don't use the object until this promise resolves
async build() {
var img = new Image();
img.src = 'assests/obst.png';
return new Promise(resolve => img.onload = resolve)
}
// call the method that draws current state "draw"
draw() {
ctx.drawImage(img, this.x, this.y, 60, 60);
}
// call the method that updates current state and draws "update"
update(x, y) {
this.x += x;
this.y += y;
this.draw()
}
}
class Player {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
}
// for symmetry, and maybe someday player will need to do async work here
async build() {
return Promise.resolve();
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
ctx.fillStyle = this.color;
ctx.fill();
}
update(x, y) {
this.x += x
this.y += y
this.draw()
}
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, innerWidth, innerHeight);
obst.update(-1, 0)
player1.update(0, 1);
}
async function play() {
const obst = new Obstacle(canvas.width, canvas.height / 2 - 30)
await obst.build();
const player1 = new Player(canvas.width / 2, canvas.height / 2, 30, 'blue');
await player1.build();
animate();
}
play()

Javascript Game: How to generate enemies (images) from an array

I was successful in generating enemies (out of one image) with an array, however, I'm stuck in trying to generate enemies out of more than one image (e. g. 5 different images, thus 5 different enemies)
Here is my code that works:
Enemies (enemyImg - one image) are generated
/** #type {HTMLCanvasElement} */
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const backgroundImg = document.getElementById("background");
const playerImg = document.getElementById("player");
const enemyImg = document.getElementById("enemy");
canvas.width = 800;
canvas.height = 500;
const enemies = [];
class Enemy {
constructor(x, y, w, h, speed) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.speed = speed;
}
draw() {
ctx.drawImage(enemyImg, this.x, this.y, this.w, this.h);
}
update() {
this.x = this.x - this.speed;
}
}
function spawnEnemies() {
setInterval(() => {
let w = 100;
let h = 40;
let x = canvas.width;
let y = Math.random() * Math.abs(canvas.height - h);
let speed = 5;
enemies.push(new Enemy(x, y, w, h, speed));
}, 1000);
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
enemies.forEach((enemy) => {
enemy.draw();
enemy.update();
});
}
animate();
spawnEnemies();
Here is the code, that does not work. I do not get any error message at all:
I have 6 images in one folder, named enemy_1.png to enemy_6.png) and I want them to be generated;
/** #type {HTMLCanvasElement} */
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const backgroundImg = document.getElementById("background");
const playerImg = document.getElementById("player");
const enemyImg = document.getElementById("enemy");
canvas.width = 800;
canvas.height = 500;
let enemies = [];
class Enemy {
constructor(img, x, y, w, h, speed) {
this.img = img;
(this.x = x),
(this.y = y),
(this.w = w),
(this.h = h),
(this.speed = speed);
}
draw() {
ctx.drawImage(img, this.x, this.y, this.w, this.h);
}
move() {
this.x = this.x - this.speed;
}
}
function createEnemies() {
setInterval(() => {
let w = 40;
let h = 72;
let x = 300;
let y = Math.random() * Math.abs(canvas.height - h);
let speed = 5;
enemies.length = 6;
for (let i = 1; i < enemies.length; i++) {
enemies[i] = new Image();
enemies[i].src = "./images/enemy_" + i + ".png";
enemies.push(new Enemy(enemies[i], x, y, w, h, speed));
}
}, 2000);
}
function createGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
enemies.forEach((enemy) => {
enemy.draw();
enemy.move();
});
requestAnimationFrame(createGame);
}
createGame();
createEnemies();
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const backgroundImg = document.createElement('img');
const playerImg = document.createElement('img');
canvas.width = 500;
canvas.height = 200;
// load your images:
const imagesCount = 0; // I have not this images, so its zero for me
const enemyImages = [];
for (let i = 1; i < imagesCount; i++) {
const img = new Image();
img.src = "./images/enemy_" + i + ".png";
enemyImages.push(img);
}
// I have not your images so i take some random pictures:
const enemyImage1 = new Image();
enemyImage1.src = 'https://pngimg.com/uploads/birds/birds_PNG106.png';
const enemyImage2 = new Image();
enemyImage2.src = 'https://purepng.com/public/uploads/large/purepng.com-magpie-birdbirdsflyanimals-631522936729bqeju.png';
const enemyImage3 = new Image();
enemyImage3.src = 'https://www.nsbpictures.com/wp-content/uploads/2018/10/birds-png.png';
enemyImages.push(
enemyImage1,
enemyImage2,
enemyImage3,
);
const enemies = [];
class Enemy {
constructor(x, y, w, h, speed, img) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.speed = speed;
// Self image:
this.img = img;
}
draw() {
// Draw self image:
ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
}
update() {
this.x = this.x - this.speed;
}
}
function spawnEnemies() {
setInterval(() => {
let w = 60;
let h = 50;
let x = canvas.width;
let y = Math.random() * Math.abs(canvas.height - h);
let speed = 5;
enemies.push(new Enemy(x, y, w, h, speed,
// Pick random image from array:
enemyImages[Math.floor(Math.random()*enemyImages.length)]
));
}, 1000);
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
enemies.forEach((enemy) => {
enemy.draw();
enemy.update();
});
}
animate();
spawnEnemies();
<canvas id=canvas></canvas>

onload not firing and image failing to be drawn

onload isn't firing in the 'draw()' method, and my image is not getting drawn on the canvas. I have confirmed that the path is correct and the image is there.
I can't find where the problem is. Thank you in advance for advice.
class Game {
constructor() {
this.gameWidth = 600;
this.gameHeight = 300;
this.gravity = 0.7;
this.canvasName = "gameBox";
this.canvas = document.getElementById(this.canvasName)
this.ctx = this.canvas.getContext('2d');
}
draw(image) {
let img = document.createElement('IMG');
this.ctx.fillStyle ='#F00';
this.ctx.fillRect(0, 0, this.gameWidth, this.gameHeight);
img.onload = function() {
this.ctx.drawImage(img, 0, 0, image.width, image.height, image.xPos, image.yPos, image.width, image.height);
}.call(this);
img.src = image.imageFile;
}
}
class Sprite {
constructor(width, height, imageFile, xPos, yPos) {
this.width = width;
this.height = height;
this.imageFile = imageFile;
this.xPos = xPos;
this.yPos = yPos;
this.xVel = 0;
this.yVel = 0;
}
}
let game = new Game()
let elephant = new Sprite(21, 13, "./images/elephant.png", game.gameWidth / 2, game.gameHeight - 13);
game.draw(elephant);
CORRECT VERSION:
I've rewritten it taking in advice from guest271314, thank you! Still seems overly complex for my liking, but it works.
class Game {
constructor() {
this.gameWidth = 600;
this.gameHeight = 300;
this.gravity = 0.7;
this.canvasName = "gameBox";
this.canvas = document.getElementById(this.canvasName)
this.ctx = this.canvas.getContext('2d');
}
drawSprite(image, img) {
this.ctx.drawImage(img, 0, 0, image.width, image.height, image.xPos, image.yPos, image.width, image.height);
}
draw(image) {
let img = document.createElement('IMG');
this.ctx.fillStyle ='#F00';
this.ctx.fillRect(0, 0, this.gameWidth, this.gameHeight);
img.onload = this.drawSprite.bind(this, image, img);
img.src = image.imageFile;
}
}
class Sprite {
constructor(width, height, imageFile, xPos, yPos) {
this.width = width;
this.height = height;
this.imageFile = imageFile;
this.xPos = xPos;
this.yPos = yPos;
this.xVel = 0;
this.yVel = 0;
}
}
let game = new Game()
let elephant = new Sprite(21, 13, "./images/elephant.png", game.gameWidth / 2, game.gameHeight - 13);
game.draw(elephant);
.call() chained to the function is a syntax error without parenthesis wrapping the function. load callback should not be called until the load handler dispatches. You can define the function with a name and use .bind()
function handleImgLoad() {
// do stuff
}
img.onload = handleImgLoad.bind(this);

Randomly Positioning Squares in JavaScript?

Code isn't working, I need to randomly position a square component. I tried running some code, but nothing happens. Here's my code:
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image"){
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "image"){
ctx.drawImage(this.image,this.x, this.y, this.width,this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
}
function startGame() {
random = Math.floor((Math.random()*100) + 1);
document.write(random);
random2 = Math.floor((Math.random()*100) + 1);
document.write(random2);
square = new component(random, random2, "green", random, random2);
myGameArea.start();
return square
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 450;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 1);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function updateGameArea() {
myGameArea.clear();
square.update();
}
For some reason, the function startGame doesn't work correctly. Nothing happens when I run the code. I opened the console log as well, and no syntax errors registered.
You can get the code to work by applying it like this, for example:
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image"){
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.color=color;
this.update = function() {
random = Math.floor((Math.random()*100) + 1);
random2 = Math.floor((Math.random()*100) + 1);
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
randcolor=getRandomColor();
ctx = myGameArea.context;
if (this.type == "image"){
ctx.drawImage(this.image, random, random2, random,random2);
} else {
ctx.fillStyle = randcolor;
ctx.fillRect(random, random2, random, random2);
}
this.x=random;
this.y=random2;
this.width=random;
this.height=random2;
this.color=randcolor;
}
}
function startGame() {
random = Math.floor((Math.random()*100) + 1);
random2 = Math.floor((Math.random()*100) + 1);
square = new component(random, random2, "green", random, random2);
myGameArea.start();
return square
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 450;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 1);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function updateGameArea() {
myGameArea.clear();
square.update();
}
document.getElementById("start").addEventListener('click', startGame)
<div id="start">press to start</div>
In here I did three things:
I added a text that you can click
I added an event listener on this text that invokes the startGame() function
I got rid of the document.write() statements. I built this is Jsfiddle, which doesn't allow it, and it's considered bad practice anyway.

How can I move an obj inside a canvas using touch event?

Hello everybody I've just trying to understands how this does it work
I have a basic canvas base just in javascript and I would like to move it using touch event
I'm not sure about this but Can I use the drag event ?
Do I need to use a loop function ?
How can I trigger that blue cube ?
I know there are lot of javascript engine in fact i'm using phaser but I would like to undertand this
Thank you
var canvas, cx, width, height;
var cube = {
x: 80,
y: 100,
update: function () {
},
draw: function (ctx) {
ctx.save();
ctx.fillStyle = "blue";
ctx.fillRect(100, 410, 50, 50);
ctx.restore();
}
};
function onpress(e) {
e.preventDefault();
var whichArt = e.target;
var touch = e.touches[0];
var moveOffsetX = whichArt.offsetLeft - touch.pageX;
var moveOffsetY = whichArt.offsetTop - touch.pageY;
whichArt.addEventListener('touchmove', function () {
var positionX = touch.pageX + moveOffsetX;
var positionY = touch.pageY + moveOffsetY;
cube.x = positionX;
cube.y = positionY;
console.log(cube.x);
}, false);
}
function main() {
canvas = document.createElement("canvas");
width = window.innerWidth;
height = window.innerHeight;
if (width >= 500) {
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
}
document.addEventListener("touchstart", onpress);
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
run();
}
function run() {
var loop = function () {
update();
render();
window.requestAnimationFrame(loop, canvas);
}
window.requestAnimationFrame(loop, canvas);
}
function update() {
}
function render() {
cube.draw(ctx);
}
main();
http://jsfiddle.net/marcogomesr/sxbo3r83/
The canvas is only a passive drawing surface : You have to handle the drag by yourself.
Below a short example :
draggables object have to implement isPointInside, and to be added to the list of draggables object.
I used a dragData object that stores the list of draggables object, the currently dragged object, maybe you'll want to store the start/current point of the drag, and handle a drag-offset so the user holds the object right on the point where he/she started dragging.
http://jsfiddle.net/3ksvn4y0/3/
var canvas, cx, width, height;
var canvasRect;
var cube1, cube2;
var dragData = {
draggables: [],
start: { x: 0, y: 0
},
current: { x: 0, y: 0
},
target: null
};
function Cube(x,y,w,h, color) {
this.x=x; this.y=y; this.w=w; this.h = h;
this.color = color;
}
Cube.prototype = {
update: function () {
},
draw: function (ctx) {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
},
isPointInside: function (x, y) {
return (x >= this.x) && (x < this.x + this.w) && (y > this.y) && (y < this.y + this.h);
}
};
var pointerCoords = {
x: 0,
y: 0,
update: function (e) {
var coords = e.touches ? e.touches[0] : e;
this.x = coords.pageX - canvasRect.left;
this.y = coords.pageY - canvasRect.top;
}
};
function onStart(e) {
e.preventDefault();
pointerCoords.update(e);
// look if we start the touch within a draggable object
var target = null;
for (var i = 0; i < dragData.draggables.length; i++) {
var draggable = dragData.draggables[i];
if (draggable.isPointInside(pointerCoords.x, pointerCoords.y)) {
target = draggable;
break;
}
}
dragData.target = target;
}
function onMove(e) {
pointerCoords.update(e);
var target = dragData.target;
if (!target) return;
target.x = pointerCoords.x;
target.y = pointerCoords.y;
}
function onStop(e) {
pointerCoords.update(e);
e.preventDefault();
if (!dragData.target) return;
onMove(e);
dragData.target = null;
}
function main() {
canvas = document.createElement("canvas");
width = window.innerWidth;
height = window.innerHeight;
if (width >= 500) {
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
}
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
canvasRect = canvas.getBoundingClientRect();
canvas.addEventListener("touchstart", onStart);
canvas.addEventListener('touchmove', onMove);
canvas.addEventListener("touchstop", onStop);
canvas.addEventListener("mousedown", onStart);
canvas.addEventListener('mousemove', onMove);
canvas.addEventListener("mouseup", onStop);
cube1 = new Cube(100, 80, 30, 30, 'blue');
cube2 = new Cube(150, 160, 20, 20, 'red');
dragData.draggables.push(cube1, cube2);
run();
}
function run() {
var loop = function () {
requestAnimationFrame(loop);
update();
render();
}
loop();
}
function update() {
}
function render() {
ctx.clearRect(0, 0, width, height);
cube1.draw(ctx);
cube2.draw(ctx);
}
main();

Categories

Resources