Drawing an image from an array of "Sprites" in JavaScript - javascript

So I'm making a game in JavaScript and I'm trying to place "Sprites" I've defined inside an array.
This is what my Sprite object looks like
function Sprite(imgsrc)
{
this.x = 0;
this.y = 0;
this.velocity_xr = 0;
this.velocity_xl = 0;
this.velocity_yu = 0;
this.velocity_yd = 0;
this.velocity_x = 0;
this.velocity_y = 0;
this.IMG = new Image();
this.IMG.src = imgsrc;
this.visible = false;
}
So I've done this:
var buttons = [];
var b = new Sprite("https://i.imgur.com/qDH38qs.png");
buttons.push(b):
And then tried to draw it using this line, with no success.
ctx.drawImage(bullets[0].IMG,300,300);
However, this works:
ctx.drawImage(b.IMG,300,300);
What am I missing?

Related

GIF image position animation using JavaScript

I'm trying to change image position using JavaScript using my code but for some reason it doesn't work. Can someone explain the reason.
var walk, isWaveSpawned = true;
var walkers = [];
function start()
{
walk = document.getElementById("walk");
draw(); //Animation function
}
function draw()
{
if(isWaveSpawned) //Generate a wave of 5 "walkers"
{
isWaveSpawned = false;
for(var i = 0; i < 5; i++
walkers.push(new createWalker());
}
for(var o = 0; o < walkers.length; o++) //Add 1px to x position after each frame
{
walkers[o].x += walkers[o].speed;
walkers[o].image.style.left = walkers[o].x;
walkers[o].image.style.top = walkers[o].y;
}
requestAnimationFrame(draw);
}
function createWalker()
{
this.x = 0;
this.y = 100;
this.speed = 1;
this.image = walk.cloneNode(false); //Possible cause of issue
}
<!DOCTYPE html>
<html>
<body onload="start()">
<img id="walk" src="https://i.imgur.com/ArYIIjU.gif">
</body>
</html>
My GIF image is visible in top left corner but doesn't move.
P.S. Added a HTML/JS snippet but it outputs some errors while in my end these errors are not seen.
First let's modify the way you're cloning the gif - get rid of this line:
this.image = walk.cloneNode(false);
and insert this:
this.image = document.createElement("img");
This will create a fresh empty HTML image element.
Now assign it's .src property the source of your gif:
this.image.src=document.getElementById("walk").src;
and set the CSS position property to absolute:
this.image.style="position:absolute;";
finally add this new image element to the body using:
document.body.appendChild(this.image);
If you hit run you will still not see any movement because there's still a little fix to do!
Find this line:
walkers[o].image.style.left = walkers[o].x;
and change it to this:
walkers[o].image.style.left = walkers[o].x + "px";
var walk, isWaveSpawned = true;
var walkers = [];
function start() {
walk = document.getElementById("walk");
draw(); //Animation function
}
function draw() {
if (isWaveSpawned) //Generate a wave of 5 "walkers"
{
isWaveSpawned = false;
for (var i = 0; i < 5; i++)
walkers.push(new createWalker());
}
for (var o = 0; o < walkers.length; o++) //Add 1px to x position after each frame
{
walkers[o].x += walkers[o].speed;
walkers[o].image.style.left = walkers[o].x + "px";
walkers[o].image.style.top = walkers[o].y + "px";
}
requestAnimationFrame(draw);
}
function createWalker() {
this.x = 0;
this.y = 100;
this.speed = 1;
this.image = document.createElement("img");
this.image.src = document.getElementById("walk").src;
this.image.style = "position:absolute;";
document.body.appendChild(this.image);
}
start();
<body>
<img id="walk" src="https://i.imgur.com/ArYIIjU.gif">
</body>

Javascript - Creating an Array of Image Objects for canvas?

I was trying to create an array of image objects and load the images after the windows has loaded in canvas.
Here is my code:
var canvasObj = document.getElementById('myCanvas');
var ctx = canvasObj.getContext('2d');
var imgsrcs = ["1.png", "2.png", "3.png"];
var imgs = [];
for(var i=0; i<imgsrcs.length; i++){
imgs[i] = new Image();
imgs[i].onload = function () {
ctx.drawImage(imgs[i], xb,yb);
}
imgs[i].src = imgsrcs[i];
}
however, I am getting this error in console:
TypeError: Argument 1 of CanvasRenderingContext2D.drawImage could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.
ctx.drawImage(imgs[i], xb,yb);
What am I doing wrong?
Thanks in advance
By the time onload event is invoked, for-loop is iterated hence value of i is length+1, as there is no element at index length+1, undefined is passed as first argument for ctx.drawImage
Use this context in the drawImage method where this === Image-Object
var canvasObj = document.getElementById('myCanvas');
var ctx = canvasObj.getContext('2d');
var imgsrcs = ["http://i.imgur.com/gwlPu.jpg", "http://i.imgur.com/PWSOy.jpg", "http://i.imgur.com/6l6v2.png"];
var xb = 0,
yb = 0;
var imgs = [];
for (var i = 0; i < imgsrcs.length; i++) {
imgs[i] = new Image();
imgs[i].onload = function() {
console.log(imgs[i]); //Check this value
ctx.drawImage(this, xb, yb);
xb += 50;
yb += 50;
}
imgs[i].src = imgsrcs[i];
}
<canvas id="myCanvas"></canvas>

Counting pixels value in Canvas

I have a question about count pixels of an image in Canvas, please see code below:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pixel Counting</title>
<script type="text/javascript">
window.onload = function() {
var img = new Image();
img.src="lena.jpg";
img.onload = function() {
countPixel(img)
};
}
function countPixel(img) {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// Draw the image to canvas.
context.drawImage(img, 0, 0);
// Now we can get the image data from the canvas.
var imageData = context.getImageData(0, 0, img.width, img.height);
var data = imageData.data;
// Do the pixel counting.
var redCount = new Array(256);
var greenCount = new Array(256);
var blueCount = new Array(256);
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
for (var i = 0; i < data.length; i += 4) {
redCount[data[i]]++; // red
greenCount[data[i + 1]]++; // green
blueCount[data[i + 2]]++; // blue
}
// Write the result to table.
var pixelTable = document.getElementById('pixel_table');
for (var i = 0; i < 256; i++) {
var row = pixelTable.insertRow(-1);
row.insertCell(-1).innerHTML = i;
row.insertCell(-1).innerHTML = redCount[i];
row.insertCell(-1).innerHTML = greenCount[i];
row.insertCell(-1).innerHTML = blueCount[i];
}
}
</script>
</head>
<body>
<div>
<canvas id="canvas" width="500" height="500">
</canvas>
</div>
<div>
<table id="pixel_table" border="1">
<caption style="font-size:25px;font-weight:bold;">Pixel Count</caption>
<tr id="header"><th>Intensity</th><th>Red</th><th>Green</th><th>Blue</th></tr>
</table>
</div>
</body>
</html>
I do not understand this for loop:
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
What does this loop here mean? This is the beginning part of the count, but why make all value to zero?
It's needed as none of the elements in the declared array are defined at that point. The loop starts at first element in the array, then goes through each single one to set an initial value to 0 (otherwise it would be undefined which would give you problems later when you try to add a number to it).
However, the better option in this case, is to replace this block:
var redCount = new Array(256);
var greenCount = new Array(256);
var blueCount = new Array(256);
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
with typed arrays, which do have all their values initialized to 0 as well as being faster than node-based arrays:
var redCount = new Uint32Array(256);
var greenCount = new Uint32Array(256);
var blueCount = new Uint32Array(256);
If you don't do that the array will be filled with undefined values.
new Array(5);
will result in:
[undefined, undefined, undefined, undefined, undefined]

how to make a variable of two variables

Before your read this, my first account was blocked because i asked bad questions.. So please dont vote negative but say what i am doing wrong
Sooo I have this script:
var img1 = new Image()
img1.src="image1.jpg"
var img2 = new Image()
img2.src="image2.jpg"
var img3 = new Image()
img3.src="image3.jpg"
function Canvas() {
var ctx = document.getElementById('slider').getContext('2d');
var pic=1
function slider() {
this.draw = function() {
if(pic<4){pic++}
else{
pic=1
}
var img = "img"+pic
ctx.drawImage(img,0,0,ctx.canvas.width,ctx.canvas.height)
}
}
var slider = new slider();
function draw() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.save();
//draw
slider.draw();
//draw
ctx.restore();
}
var animateInterval = setInterval(draw,100)
}
window.addEventListener('load', function(event) {
Canvas();
});
I am trying to draw the image 1 or 2 or 3 on my canvas. But I also have the var pic wich has the number. So i tried ctx.drawimage(img+pic,0,0) or var img = "img"+pic and draw it then. But it doesnt work for me.
I hope you accept my question and can answer it, THNX
Use an array instead
var img = [];
/* you should use a for loop here */
for (var i = 0; i < 3; i++) {
img[i] = new Image();
img[i].src = "image" + (i+1) ".jpg";
}
and later you refer the right image with img[pic]. Be only sure to use an index between 0 and img.length - 1
Don't use separate variables, use an array.
var images = [ new Image(), new Image(), new Image() ];
for (var i = 0; i < images.length; i++) {
images[i].src = "image" + (i+1) + ".jpg";
}
Then refer to the array in the Slider() function:
var pic = 0;
function slider() {
this.draw = function() {
pic = (pic + 1) % images.length;
var img = images[pic];
ctx.drawImage(img,0,0,ctx.canvas.width,ctx.canvas.height)
}
}
The error seems to be that you refer to the string "img1" and not the object img1. Try use an array instead.
Set the following:
...
var pic=0;
var img=[img1,img2,img3];
function slider() {
this.draw = function() {
if(pic<3){pic++}
else{
pic=0;
}
ctx.drawImage(img[pic],0,0,ctx.canvas.width,ctx.canvas.height)
}
}
...

getImageData always returning 0

I have been trying to make a script that compares two images in HTML5 and Javascript. But for some odd reason, it always returns that the images are completely the same.
And when looking at what the problem could be, I found out that every data value of every pixel returned, for some odd reason, "0".
So, any idea of what I have done wrong? :)
For some reason I feel like it's something very simple, but I just learned about the canvas element, so yeah.
This is my code:
function compareImg() {
var c1 = document.getElementById("c");
var ctx1 = c1.getContext("2d");
var c2 = document.getElementById("c2");
var ctx2 = c2.getContext("2d");
var match = 0;
var img1 = new Image();
img1.src = "cat.jpg";
img1.onload = function() {
ctx1.drawImage(img1, 0, 0);
}
var img2 = new Image();
img2.src = "bird.jpg";
img2.onload = function() {
ctx2.drawImage(img2, 0, 0);
}
for(var x = 0; x<c1.width; x++) { // For each x value
for(var y = 0; y<c1.height; y++) { // For each y value
var data1 = ctx1.getImageData(x, y, 1, 1);
var data2 = ctx2.getImageData(x, y, 1, 1);
if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) {
match++;
}
}
}
var pixels = c1.width*c1.height;
match = match/pixels*100;
document.getElementById("match").innerHTML = match + "%";
}
You are not waiting until your images have loaded and drawn before performing your comparison. Try this:
var img = new Image;
img.onload = function(){
ctx1.drawImage(img,0,0);
var img = new Image;
img.onload = function(){
ctx2.drawImage(img,0,0);
// diff them here
};
img.src = 'cat.jpg';
};
img.src = 'cat.jpg';
As shown above, you should always set your src after your onload.
I suspect that the problem is that your image data is probably not ready at the point you try to use it for the canvas. If you defer that code to the onload handlers, that will (probably) help:
var img1 = new Image(), count = 2;
img1.src = "cat.jpg";
img1.onload = function() {
ctx1.drawImage(img1, 0, 0);
checkReadiness();
}
var img2 = new Image();
img2.src = "bird.jpg";
img2.onload = function() {
ctx2.drawImage(img2, 0, 0);
checkReadiness();
}
function checkReadiness() {
if (--count !== 0) return;
for(var x = 0; x<c1.width; x++) { // For each x value
for(var y = 0; y<c1.height; y++) { // For each y value
var data1 = ctx1.getImageData(x, y, 1, 1);
var data2 = ctx2.getImageData(x, y, 1, 1);
if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) {
match++;
}
}
}
var pixels = c1.width*c1.height;
match = match/pixels*100;
document.getElementById("match").innerHTML = match + "%";
}
All I did was add a function wrapper around your code. That function checks the image count variable I added, and only when it's zero (i.e., only after both images have loaded) will it do the work.
(This may be superstition, but I always assign the "onload" handler before I set the "src" attribute. I have this idea that, perhaps only in the past, browsers might fail to run the handler if the image is already in the cache.)
Now another thing: you probably should just get the image data once, and then iterate over the returned data. Calling "getImageData()" for every single pixel is going to be a lot of work for the browser to do.

Categories