Loading Images from a Canvas - javascript

I'm trying to make a game in HTML5 and I'm having trouble loading image assets. My issue is that the onload event of the code isn't firing and so the boolean isn't changing.
var c = document.getElementById("gamearea");
var gs = c.getContext("2d");
var one_x = 0;
//Sprite Loading//
function sprite(src,x, y, width, height, frames, levels) {
this.sprite = Image();
this.sprite.src = src;
this.x = x;
this.y = y;
this.w = width;
this.h = height;
this.f = frames;
this.l = levels;
this.cf = 0;
this.cl = 0;
this.loaded = false;
this.src = src;
}
sprite.prototype.draw = function () {
if (this.loaded) {
document.getElementById("ass").innerHTML = "Ass";
gs.drawImage(this.src, this.x, this.y);
}
}
dog = new sprite("/images/sDog.png", 10, 10, 10, 10, 1, 1);
dog.sprite.onload = function () {
alex.loaded = true;
}
setInterval(alex.draw, 30);

I would suggest putting the onload event before the set event for your dog sprite image object. I see that you set everything in the constructor, but I would suggest against that.
In you current code you object is being loaded before the line that initializes the onload event.
I have seen this a lot with loading images, I would do something like this.
function sprite(src,x, y, width, height, frames, levels) {
var self = this;
self.sprite = new Image();
self.init = function(){
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
}
}
dog = new sprite();
dog.sprite.onload = function () {
alex.loaded = true;
}
dog.init("/images/sDog.png", 10, 10, 10, 10, 1, 1);
setInterval(alex.draw, 30);
or, to get a little fancier
function sprite(src,x, y, width, height, frames, levels, onLoad) {
var self = this;
self.sprite = new Image();
self.sprite.onload = function(){
onLoad();
}
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
}
dog = new Sprite("/images/sDog.png", 10, 10, 10, 10, 1, 1, function(){
alex.loaded = true;
});
setInterval(alex.draw, 30);
after looking at your fiddle
var c = document.getElementById("gamearea");
var gs = c.getContext("2d");
var one_x = 0;
//Sprite Loading//
function sprite(src, x, y, width, height, frames, levels, loaded) {
var self = this;
self.sprite = new Image();
self.sprite.onload = function(){
self.loaded = true;
}
self.sprite.src = src;
self.x = x;
self.y = y;
self.w = width;
self.h = height;
self.f = frames;
self.l = levels;
self.cf = 0;
self.cl = 0;
self.loaded = false;
self.src = src;
self.update = function () {
one_x += 1;
gs.fillStyle = "white";
gs.fillRect(0, 0, 1000, 10000);
gs.fillStyle = "black";
gs.fillRect(one_x, 20, 10, 10);
}
self.draw = function (){
if (self.loaded) {
document.getElementById("ass").innerHTML = "Ass";
gs.drawImage(self.sprite, self.x, self.y);
}
}
}
dog = new sprite("http://www.bit-101.com/blog/wp-content/uploads/2009/05/ball.png", 10, 10, 10, 10, 1, 1);
setInterval(dog.draw, 30);

You're missing new here:
this.sprite = Image();
Try:
this.sprite = new Image();
Also make sure that the image file actually exists in the given location.

Related

Add a counter of the number of objets clicked

I just made this animation using canvas. Shows a number of bubbles scrolling from top to bottom. Clicking on any bubble starts it moving top to bottom again.
I plan to add a counter of the number of bubbles clicked/picked with a localStorage but I have difficulties implementing it.
Here is how I implemented it.
Each bubble now has id property.
Every time you run the script, it puts empty array to localStorage.clickedBubbles.
When a bubble is clicked, the array is checked if it contains the id. If not, the id is pushed to local storage.
Also, each click the count is logged to console.
const INITIALIZATION = 100;
const STEP1 = 200;
const BUBBLES = 10;
const SPEED = 10;
let counter = 0;
localStorage.setItem("clickedBubbles", "[]");
function Bubble(x, y, radio) {
this.id = counter++;
this.x = x;
this.y = y;
this.radio = radio;
this.color = "blue";
this.speed = 5;
this.getId = function () {
return this.id;
};
this.getX = function () {
return this.x;
};
this.getY = function () {
return this.y;
};
this.getRadio = function () {
return this.radio;
};
this.getColor = function () {
return this.color;
};
this.getspeed = function () {
return this.speed;
};
this.setX = function (x) {
this.x = x;
};
this.setY = function (y) {
this.y = y;
};
this.setRadio = function (radio) {
this.radio = radio;
};
this.setColor = function (color) {
this.color = color;
};
this.setSpeed = function (speed) {
this.speed = speed;
};
this.draw = function (ctx) {
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radio, 0, Math.PI * 2, true);
ctx.fill();
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(
this.x + this.radio / 3,
this.y - this.radio / 3,
this.radio / 4,
0,
Math.PI * 2,
true
);
ctx.fill();
ctx.restore();
};
this.coordinates = function (x, y) {
var ax = this.getX() - this.getRadio();
var ay = this.getY() - this.getRadio();
return (
x >= ax &&
x <= ax + 2 * this.getRadio() &&
y >= ay &&
y <= ay + 2 * this.getRadio()
);
};
}
function animationBubbles() {
var bubbles = [];
var arrayColors;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var status = INITIALIZATION;
var app = this;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
this.click = function (e) {
var x = e.x || e.pageX || e.clientX;
var y = e.y || e.clientY || e.pageY;
const clickedArr = JSON.parse(localStorage.getItem("clickedBubbles"));
for (var i = 0; i < bubbles.length; i++) {
var aux = bubbles[i];
if (aux.coordinates(x, y)) {
if (!clickedArr.includes(aux.getId())) {
clickedArr.push(aux.getId());
localStorage.setItem("clickedBubbles", JSON.stringify(clickedArr));
}
aux.setY(0);
break;
}
}
console.log("Clicked count: " + clickedArr.length);
};
canvas.addEventListener("mousedown", this.click, false);
this.realizeAnimation = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < bubbles.length; i++) {
var aux = bubbles[i];
if (aux.getY() < canvas.height) {
aux.setY(aux.getY() + aux.getspeed());
} else {
aux.setY(0);
aux.setColor(arrayColors[Math.floor(Math.random() * 4)]);
}
aux.draw(ctx);
}
setTimeout(app.realizeAnimation, 100);
};
this.createBubbles = function () {
for (var i = 1; i <= BUBBLES; i++) {
var burbuja = new Bubble(
canvas.width * (i / BUBBLES),
0,
this.generateRandom(Math.floor(canvas.width / 20))
);
burbuja.setSpeed(SPEED);
burbuja.setColor(arrayColors[this.generateRandom(4)]);
bubbles.push(burbuja);
}
};
this.generateRandom = function (num) {
return Math.floor(Math.random() * num);
};
this.initColor = function () {
arrayColors[0] = "#C923C9";
arrayColors[1] = "#FAEF20";
arrayColors[2] = "#20ECFA";
arrayColors[3] = "#FA209C";
};
this.machineStates = function () {
if (status === INITIALIZATION) {
arrayColors = [];
this.initColor();
this.createBubbles();
status = STEP1;
setTimeout(app.machineStates, 100);
} else {
app.realizeAnimation();
}
};
this.machineStates();
}
new animationBubbles();

How to draw multiple array entities on canvas

I want to draw out all of the objects that I have in my zombielist. but I can't get it to work.
var FatZombieWikki = new Image();
FatZombieWikki.src = "FatZombieWikki.png";
var Zombie = function(x, y) {
this.x = x;
this.y = y;
this.Draw = function(ctx) {
ctx.drawImage(FatZombieWikki,200,ZombieY,50,50);
}
this.Update = function(){
if(ZombieY < 900) {
ZombieY += 0.5;
}
}
}
var z = new Zombie(100, 200,);
var zombieList = [];
for (var i = 0; i < 10; i++) {
zombieList.push(new Zombie(40 * i, 100));
}
call your draw function inside loop, after creating object.
DEMO
var ctx = document.getElementById('c').getContext('2d');
var FatZombieWikki = new Image();
FatZombieWikki.src = "//i.stack.imgur.com/ubK40.jpg";
FatZombieWikki.onload = function(){
var zombieList = [];
for (var i = 0; i < 10; i++) {
zombieList.push(new Zombie(40 * i, 30*i));
zombieList[i].draw(ctx);
}
}
var Zombie = function(x, y) {
this.x = x;
this.y = y;
this.draw = function(ctx) {
ctx.drawImage(FatZombieWikki,this.x,this.y,50,50);
}
}
canvas{
border:2px solid #000
}
<canvas id='c' width=500 height=400></canvas>
zombieList.forEach(zombie => zombie.Draw(ctx))

How to curve image in differnt shape, just like 'm'

I want to give curve to image just as shirt collar.
Curve image
I have image.Main image
I use below code
<script type="text/javascript">
function allcurve(event){
topcolrcurve(event);
}
function topcolrcurve(event){
var getImagePath = URL.createObjectURL(event.target.files[0]);
console.log(getImagePath)
temp_can1 = document.getElementById('f6258182013');
temp_can1_ctx = temp_can1.getContext('2d');
topcolrrotator(getImagePath, '-100');
}
function topcolrrotator(var2, var3)
{
var mr_rotator_var = document.getElementById('colrtop_can');
var mr_rotator_var_ctx = mr_rotator_var.getContext("2d");
mr_rotator_var.width = mr_rotator_var.width;
var imageObj_rotator3 = new Image();
var hpp='';
imageObj_rotator3.onload = function () {
var pattern_rotator3 = mr_rotator_var_ctx.createPattern(imageObj_rotator3, "repeat");
mr_rotator_var_ctx.fillStyle = pattern_rotator3;
mr_rotator_var_ctx.rect(0, 0, mr_rotator_var.width, mr_rotator_var.height);
mr_rotator_var_ctx.rotate(var3 * Math.PI / 180);
mr_rotator_var_ctx.fill();
hpp = mr_rotator_var.toDataURL('image/png');
rightcufover(hpp);
};
imageObj_rotator3.src = var2;
}
function rightcufover(event)
{
var getImagePath = event;
var ctx = e.getContext("2d");
var img = new Image;
img.onload = slice;
img.src = getImagePath;
function slice() {
var w = e.width = this.width;
var h = e.height = this.height;
var step = Math.PI * 1 / w;
var scale = -100;
for(var x = 0; x < w; x++) {
ctx.drawImage(this,
x, 0, 1, h,
x, Math.sin(step*x)*scale, 1, h);
}
var hp=e.toDataURL('image/png');
$('#collrtop').attr("value", hp);
}
}
Please help how to curve image.
I try it in different way but it not show proper, also I have to maintain quality of image.

cannot read property of undefined javascript and OOP

I have an object (a function) called 'Game' which has a prototype method called 'gameLoop.' I need this loop to be called in an interval, so I attempt to do this:
setInterval(game.gameLoop,setIntervalAmount);
but receive a "TypeError: Cannot read property 'clearRect' of undefined(…)"
Here is the prototype method:
Game.prototype.gameLoop = function()
{
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
I am still having difficulty understanding Object Oriented Programming in Javascript. I had a working version where the function was just a regular function and I passed in a game object. Any ideas?
By the way, here is some additional code that may be helpful.
function Sprite(imgg,w,h)
{
this.img = imgg;
this.x = 350;//Math.random()*700;
this.y = 350;//Math.random()*700;
this.vx = 0;//Math.random()*8-4;
this.vy = 0;//Math.random()*8-4;
this.width = w;
this.height = h;
this.rotatespeed = 0.01;
this.rotate = 40;
}
Sprite.prototype.drawSprite = function(ctx)
{
ctx.save();
ctx.translate(this.x,this.y);
ctx.rotate(this.rotate);
ctx.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height);
ctx.restore();
}
Sprite.prototype.updateSprite = function()
{
this.x += this.vx;
this.y += this.vy;
this.rotate += this.rotatespeed;
if(this.x > 700)
this.vx = -this.vx;
if(this.x < 0)
this.vx = -this.vy;
if(this.y > 700)
this.vy = -this.vy;
if(this.y < 0)
this.vy = -this.vy;
}
Sprite.prototype.mouseEventListener = function(evt, type)
{
console.log("Hello");
}
//------------------------------------------
//GLOBAL VARIALBES
var setIntervalAmount = 30;
var scrollAmount = 0.5;
var game;
function Game()
{
this.camera = new Object();
this.camera.x = -350;
this.camera.y = -350;
this.camera.scale = 1;
this.camera.rotate = 0;
this.canvas = document.createElement("canvas");
document.body.appendChild(this.canvas);
this.canvas.id="mycanvas";
this.canvas.width = 700;
this.canvas.height = 700;
this.context = this.canvas.getContext("2d");
var ctx = this.context;
ctx.canvas.addEventListener('mousemove', function(event){
var mouseX = event.clientX - ctx.canvas.offsetLeft;
var mouseY = event.clientY - ctx.canvas.offsetTop;
var canvasX = mouseX * ctx.canvas.width / ctx.canvas.clientWidth;
var canvasY = mouseY * ctx.canvas.height / ctx.canvas.clientHeight;
//console.log(canvasX+" | "+canvasY);
});
this.objects = new Array();
}
Game.prototype.handleMouse = function(evt,type)
{
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].mouseEventListener(evt,type);
}
};
Game.prototype.gameLoop = function()
{
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
/*Game.prototype.drawGame = function()
{
var gameLoop = setInterval(function(){
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
},setIntervalAmount);
}*/
function mouseWheelListener()
{
var evt = window.event;
console.log(evt.wheelDelta);
if(evt.wheelDelta < 0)
game.camera.scale /= (1+scrollAmount);
else
game.camera.scale *= (1+scrollAmount);
}
function mouseDownListener()
{
var evt = window.event;
var type = "down"
game.handleMouse(evt,type);
}
function mouseUpListener()
{
var evt = window.event;
var type = "up"
game.handleMouse(evt,type);
}
function mouseMoveListener()
{
var evt = window.event;
var type = "move"
game.handleMouse(evt,type);
}
//------------------
window.addEventListener('load',function(event){startgame();});
var dog = new Image();
dog.src = "grid.gif";
function startgame()
{
game = new Game();
for(var i=0;i<1;i++)
game.objects.push(new Sprite(dog,250,250));
setInterval(game.gameLoop,setIntervalAmount);
document.getElementById("mycanvas").addEventListener("wheel", mouseWheelListener);
document.getElementById("mycanvas").addEventListener("mousedown", mouseDownListener);
document.getElementById("mycanvas").addEventListener("mouseup", mouseUpListener);
document.getElementById("mycanvas").addEventListener("mousemove", mouseMoveListener);
}
Only issue, with your code is the context on which you are executing the gameloop method.
usually setInterval, setTimeout functions are executed under the global / window context. Hence, if you specify this inside the method, you are technically referring to global context, even though you are executing it on an object.
So, just to make sure you don't run into issues, always have a method as a first argument to setInterval, that would execute the necessary functions, instead of a method reference, something like
setInterval(function(){/*
game.gameLoop()
*/}, 1000);
This way you are executing the setInterval function in the global context but you are calling a method on game object explicitly.
function Sprite(imgg, w, h) {
this.img = imgg;
this.x = 350; //Math.random()*700;
this.y = 350; //Math.random()*700;
this.vx = 0; //Math.random()*8-4;
this.vy = 0; //Math.random()*8-4;
this.width = w;
this.height = h;
this.rotatespeed = 0.01;
this.rotate = 40;
}
Sprite.prototype.drawSprite = function(ctx) {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.rotate);
ctx.drawImage(this.img, 0, 0, this.img.width, this.img.height, -this.width / 2, -this.height / 2, this.width, this.height);
ctx.restore();
}
Sprite.prototype.updateSprite = function() {
this.x += this.vx;
this.y += this.vy;
this.rotate += this.rotatespeed;
if (this.x > 700)
this.vx = -this.vx;
if (this.x < 0)
this.vx = -this.vy;
if (this.y > 700)
this.vy = -this.vy;
if (this.y < 0)
this.vy = -this.vy;
}
Sprite.prototype.mouseEventListener = function(evt, type) {
//console.log("Hello");
}
//------------------------------------------
////GLOBAL VARIALBES
var setIntervalAmount = 200;
var scrollAmount = 0.5;
var game;
function Game() {
this.camera = new Object();
this.camera.x = -350;
this.camera.y = -350;
this.camera.scale = 1;
this.camera.rotate = 0;
this.canvas = document.createElement("canvas");
document.body.appendChild(this.canvas);
this.canvas.id = "mycanvas";
this.canvas.width = 700;
this.canvas.height = 700;
this.context = this.canvas.getContext("2d");
var ctx = this.context;
ctx.canvas.addEventListener('mousemove', function(event) {
var mouseX = event.clientX - ctx.canvas.offsetLeft;
var mouseY = event.clientY - ctx.canvas.offsetTop;
var canvasX = mouseX * ctx.canvas.width / ctx.canvas.clientWidth;
var canvasY = mouseY * ctx.canvas.height / ctx.canvas.clientHeight;
//console.log(canvasX+" | "+canvasY);
});
this.objects = new Array();
}
Game.prototype.handleMouse = function(evt, type) {
for (var i = 0; i < this.objects.length; i++) {
this.objects[i].mouseEventListener(evt, type);
}
};
Game.prototype.gameLoop = function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width / 2, this.canvas.height / 2);
this.context.scale(this.camera.scale, this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x, this.camera.y);
for (var i = 0; i < this.objects.length; i++) {
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
/*Game.prototype.drawGame = function()
{
var gameLoop = setInterval(function(){
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
},setIntervalAmount);
}*/
function mouseWheelListener() {
var evt = window.event;
console.log(evt.wheelDelta);
if (evt.wheelDelta < 0)
game.camera.scale /= (1 + scrollAmount);
else
game.camera.scale *= (1 + scrollAmount);
}
function mouseDownListener() {
var evt = window.event;
var type = "down"
game.handleMouse(evt, type);
}
function mouseUpListener() {
var evt = window.event;
var type = "up"
game.handleMouse(evt, type);
}
function mouseMoveListener() {
var evt = window.event;
var type = "move"
game.handleMouse(evt, type);
}
//------------------
window.addEventListener('load', function(event) {
startgame();
});
var dog = new Image();
dog.src = "https://i.stack.imgur.com/W0mIA.png";
function startgame() {
game = new Game();
for (var i = 0; i < 1; i++)
game.objects.push(new Sprite(dog, 250, 250));
setInterval(function() {
game.gameLoop();
}, setIntervalAmount);
document.getElementById("mycanvas").addEventListener("wheel", mouseWheelListener);
document.getElementById("mycanvas").addEventListener("mousedown", mouseDownListener);
document.getElementById("mycanvas").addEventListener("mouseup", mouseUpListener);
document.getElementById("mycanvas").addEventListener("mousemove", mouseMoveListener);
}
setInterval will call game.gameloop at the global scope which means the value of this inside the function is not what you expect it to be. This can be fixed by binding the function to the desired object.
E.g. change setInterval(game.gameLoop,setIntervalAmount); to setInterval(game.gameLoop.bind(game),setIntervalAmount);.
This example from MDN may provide some clarity for your code's current behaviour:
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// returns 9 - The function gets invoked at the global scope
// Create a new function with 'this' bound to module
// New programmers might confuse the
// global var x with module's property x
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81

A HTML5 canvas ERROR

I'am trying to write a puzzle game in canvas,so i need to give each part of puzzle block a background image.
but always a error "Uncaught TypeError: Cannot read property 'drawImage' of undefined "
any help will be appreciated!
(function(){
function Block(image, l, t, w, h){
this.image = image;
this.left = l;
this.top = t;
this.width = w;
this.height = h;
}
Block.prototype.draw = function(context){
context.drawImage(this.image, this.left, this.top, this.width, this.height, this.left, this.top, this.width, this.height);
}
window.Block = Block;
})();
var el = document.getElementById("puzzle_area");
var ctx = el.getContext("2d");
var image = new Image();
image.src = "background0.jpg";
image.onload = init;
var width = 100;
var height = width;
function init(){
for(var i = 0; i < 16; i++){
var x = (i % 4) * width;
var y = parseInt(i / 4) * height;
var block = new Block(image, x, y, width, height);
block.draw(ctx);
}
}
Your draw() function requires a context parameter which you're not passing to it when you're calling it from within your Block() function/object. Add a context parameter to that and use it when calling "this.draw()".
I haven't tested it, but here is what I changed your code to:
(function(){
function Block(context, image, l, t, w, h){
this.image = image;
this.left = l;
this.top = t;
this.width = w;
this.height = h;
this.context = context;
this.draw();
}
Block.prototype.draw = function(){
this.context.drawImage(this.image, -this.left, -this.top, this.width, this.height, this.left, this.top);
}
window.Block = Block;
})();
var el = document.getElementById("puzzle_area");
var ctx = el.getContext("2d");
var image = new Image();
image.src = "background0.jpg";
image.onload = init;
var block = null;
var width = 100;
var height = width;
function init(){
for(var i = 0; i < 9; i++){
var x = (i % 400) * width;
var y = parseInt(i / 400) * height;
block = new Block(ctx, image, x, y, width, height);
// block is drawn automatically, no need to draw it again
// block.draw();
}
}

Categories

Resources