bind(this) and requestAnimationFrame - javascript

After reading some solutions, I came up with this:
class Car{
constructor(carTag, throttle, yPosition){
this.carTag = carTag
this.carTag = new Image()
this.throttle = throttle
this.yPosition = yPosition
}
//Animate method that will animate cars across the screen
animate(){
const ref = this;
requestAnimationFrame(function(){
ref.animate();
});
const canvas = document.getElementById("gameboard");
const ctx = canvas.getContext("2d");
let xPosition = canvas.width;
setTimeout (function(){
ctx.clearRect(0, 0, xPosition, ref.yPosition);
ctx.drawImage(ref.carTag, xPosition, ref.yPosition);
xPosition -= 4;
console.log(xPosition);
}, 1000/ref.throttle);
}
}
const cars = new Car;
cars.carTag.src = "http://i.stack.imgur.com/Rk0DW.png";
cars.throttle = 2000;
cars.yPosition = 0;
cars.animate();
The problem I am still stumped on is why my car image is stuck in one position and not animating. Why is bind(this) interfering with requestAnimationFrame?
update: The latest version of this method doesn't produce error messages. But for some reason, the xPosition isn't updated which moves the car image left. I tried putting requestAnimationFrame to the bottom of the method, same result.

I found the solution. Thanks everyone!
class Car{
constructor(carTag, throttle, yPosition, xPosition, canvas, ctx){
//carTag property
this.carTag = carTag
this.carTag = new Image()
//throttle property
this.throttle = throttle
//yPosition property
this.yPosition = yPosition
//canvas, ctx property connecting with DOM
this.canvas = canvas
this.canvas = document.getElementById("gameboard");
this.ctx = ctx;
this.ctx = this.canvas.getContext("2d");
//xPosition property
this.xPosition = xPosition
this.xPosition = this.canvas.width;
}
//Animate method that will animate cars across the screen
animate(){
const ref = this;
setTimeout (function(){
ref.canvas.width = ref.canvas.width;
ref.ctx.drawImage(ref.carTag, ref.xPosition, ref.yPosition);
ref.xPosition -= 4;
requestAnimationFrame(function(){
ref.animate();
});
}, 1000/ref.throttle);
}
}
const cars = new Car;
cars.carTag.src = "http://i.stack.imgur.com/Rk0DW.png";
cars.throttle = 2000;
cars.yPosition = 0;
cars.animate();

Related

Images not rendering randomly on canvas

Image of the bug is appearing only at one place i.e. x = 0,y = 0.
var canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext('2d');
var bugSmashed = 0;
//rendering background image
function renderImage()
{
var backImage = new Image();
backImage.src = "jungle.jpg"
backImage.onload = function(){
c.drawImage(backImage,0,0,canvas.width,canvas.height)}
}
renderImage();
//Making a bug
class Bug {
constructor(x,y){
this.x = x;
this.y = y;
}
renderBug(){
var bugImage = new Image();
bugImage.src = "bug.png";
bugImage.onload = function(){
c.drawImage(bugImage,this.x,this.y,65,65)}}
}
Trying to make the bug appear randomly on the canvas
var interval = setInterval(function(){
var x = 32+Math.random()*(canvas.width-64);
var y = 32+Math.random()*(canvas.height-64);
var aBug = new Bug(x,y);
aBug.renderBug();}, 2000);
I am sure I am missing something. Any help is appreciated. Thanks
I found your problem: this changes its meaning inside a function. So when you use:
function(){c.drawImage(bugImage,this.x,this.y,65,65)}
this no longer refers to aBug! (It will instead refer to the global Window object.) You can use fat-arrow syntax instead (which preserves this):
() => c.drawImage(bugImage,this.x,this.y,65,65)
Another really ugly way which I discourage you from using is by creating a new reference to this, and then using that reference in your function:
let that = this;
function(){ c.drawImage(bugImage, that.x, that.y, 65, 65); };
Or you can simplify your code to have it gloss over onload logic, allowing you to avoid wrapping c.drawImage in a function in the first place (note the square which appears is a publicly addressable image):
var canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext('2d');
//Making a bug
let bugImg = new Image();
bugImg.src = "https://th.bing.com/th/id/OIP.pXD0MAw4LeAcVrt3qRiEfwAAAA?pid=ImgDet&rs=1";
class Bug {
constructor(x,y){
this.x = x;
this.y = y;
}
renderBug(){
c.drawImage(bugImg, this.x, this.y, 65, 65);
}
}
var interval = setInterval(function(){
var x = 32 + Math.random()* (canvas.width - 64);
var y = 32 + Math.random()* (canvas.height - 64);
var aBug = new Bug(x, y);
aBug.renderBug();
}, 500);
<canvas id="canvas" width="100" height="100"></canvas>

How do I create and draw an array of images on a canvas using Javascript?

I am trying the following code to allow me to create an image, allow custom values attached to it and draw in on an HTML canvas. It doesn't seem to be working though.
var canvas = document.getElementById('mainCanvas');
var context = canvas.getContext('2d');
function CreateObject(objectImage){
lastIndex++;
PlanObjects[lastIndex] = new PlanObject(lastIndex,currentSlide,24,24,24,24,objectImage);
context.drawImage(PlanObjects[lastIndex].img,PlanObjects[lastIndex].posX,PlanObjects[lastIndex].posY);
}
var PlanObjects = [];
var lastIndex = -1;
var currentSlide = 0;
function PlanObject(id, slide, width, height, posX, posY, img){
this.id = id;
this.slide = slide;
this.width = width;
this.height = height;
this.posX = posX;
this.posY = posY;
this.img = new Image(img);
}
CreateObject("imgs/icons_star.png");
HTML:
<div id="mainCanvasDiv"><canvas width="800" height="600" id="mainCanvas"></canvas>
I expect to create the object, store it in the array of PlanObjects (with it's customer values) and draw it onto the canvas but it doesn't seem to do that.
1) The input parameters for the image constructor are width and height. And you must separately set the source:
var myImage = new Image(100, 200);
myImage.src = 'picture.jpg';
document.body.appendChild(myImage);
[ https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image ]
2) Loading an image is asynchronous, so you need to handle the load event:
PlanObjects[lastIndex].img.addEventListener('load', function() {
context.drawImage(PlanObjects[lastIndex].img, PlanObjects[lastIndex].posX, PlanObjects[lastIndex].posY)
});
[ https://developer.mozilla.org/en-US/docs/Web/Events/load ]
[ https://jsfiddle.net/bvupyroc/ ]
I had to modify the new Image line to fix the problem
var canvas = document.getElementById('mainCanvas');
canvas.width = canvas.scrollWidth;
canvas.height = canvas.scrollHeight;
var context = canvas.getContext('2d');
function CreateObject(objectImage){
lastIndex++;
PlanObjects[lastIndex] = new PlanObject(lastIndex,currentSlide,24,24,24,24,objectImage);
context.drawImage(PlanObjects[lastIndex].img,PlanObjects[lastIndex].posX,PlanObjects[lastIndex].posY);
}
var PlanObjects = [];
var lastIndex = -1;
var currentSlide = 0;
function PlanObject(id, slide, width, height, posX, posY, img){
this.id = id;
this.slide = slide;
this.width = width;
this.height = height;
this.posX = posX;
this.posY = posY;
this.img = new Image();
this.img.src = img;
}
CreateObject("./imgs/icons_star.png");

Javascript error in rails

i start to learn javascript with easy game tutorial http://www.youtube.com/watch?v=U7anheKJSaIand on RoR got error in index.html.erb:
<script>
var ctx, canvas;
var data;
window.onload = function main(){
canvas = document.createElement("canvas");
canvas.width = canvas.height = 200;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
init();
tick();
}
function init(){
data = new Tile(20,20);
}
function tick(){
window.requestAnimationFrame(tick);
update();
render();
}
function update(){}
function render(){
data.draw(ctx);
}
function Tile(x,y){
var x = x, y = y;
var tile = Tile.BlANK;
if(tile == null){
var _c = document.createElement("canvas");
_c.width = _c.height = 100;
_ctx = _c.getContext("2d");
_ctx.fillStyle = "skyblue";
//blank
_ctx.fillRect(0,0,100,100);
Tile.BlANK = new Image();
Tile.BLANK.src = _c.toDataURL();
tile = Tile.BLANK;
}
this.update = function(){}
this.draw = function(ctx){
ctx.drawImage(tile, x, y);
}
}
</script>
and this is error:
Tile.BLANK.src = _c.toDataURL();
Uncaught TypeError: Cannot set property src of undefined
Your error is here
Tile.BlANK = new Image();
It should be:
Tile.BLANK = new Image();
The error comes from .BlANK and it's because there is a typo. The l (L) is lowecase, and therefore later when you are trying to access the .src in you can't, because the real .BLANK is still undefined.
This is in function Tile(x,y){...}, but you also have the typo some other places. Just check your code for lowercase letters in .BLANK.

How do I inherit a variable with prototype?

I'm just setting up a little framework for my canvas, I haven't used Prototype a lot, but it seems to be pretty damn awesome, just having one little problem, the create function is not inheriting the width and height from the new function, how might I do this? Code:
function CtxCanvas() {
this.fps = undefined;
this.width = undefined;
this.height = undefined;
}
CtxCanvas.prototype = {
constructor: CtxCanvas,
new: function(fps, width, height) {
this.fps = fps;
this.width = width;
this.height = height;
},
create: function() {
var df = document.createDocumentFragment()
, canvasElement = document.createElement('canvas');
canvasElement.width = this.width;
canvasElement.height = this.height;
df.appendChild(canvasElement);
document.getElementsByTagName('body')[0].appendChild(df);
return canvasElement.getContext('2d');
}
}
var ctx = new CtxCanvas(30, 1000, 1000).create();
Your constructor function is what initializes the object, your new function never gets called:
function CtxCanvas(f, w, h) {
this.fps = f;
this.width = w;
this.height = h;
}
It is sufficient to format your code like this, unless there's a special reason not to.
You can simply assign the prototype create, to a function, and allow the 'class' to do the initialization (which is the better approach).
Makes your code simpler and more readable.
function CtxCanvas(f, w, h) {
this.fps = f;
this.width = w;
this.height = h;
}
CtxCanvas.prototype.create = function() {
var df = document.createDocumentFragment()
var canvasElement = document.createElement('canvas');
canvasElement.width = this.width;
canvasElement.height = this.height;
df.appendChild(canvasElement);
document.getElementsByTagName('body')[0].appendChild(df);
return canvasElement.getContext('2d');
};
var ctx = new CtxCanvas(30, 1000, 1000).create();
alert(ctx);

Javascript array and object/classes

i am trying to display three playing cards on the screen and for some reason everytime i run the code a type error appears and i have tried everything to try to fix it but nothing has worked. I think that the problem is in the array/object constructor but i think that everything is right inside of those.
"use strict";
function main(){
var cvs = document.getElementById("foo");
var ctx = foo.getContext("2d");
function Card(posX, posY, imgX, imgY){
this.posX = posX;
this.posY = posY;
this.imgX = imgX;
this.imgY = imgY;
this.width = 97;
this.height = 129;
}
Card.img = new Image();
Card.img.src = "allcards.png";
var cards = [new Card(0,0,0,0), new Card(400,400,194,258), new Card(200,200,291,387)];
var greaterX = false;
var lessX = false;
var greaterY = false;
var lessY = false;
var offsetX;
var offsetY;
setInterval(draw, 10);
function draw(){
ctx.fillStyle="rgb(0,255,255)";
ctx.clearRect(0,0,600,600);
ctx.drawImage(Card.img,cards[1].imgX,cards[1].imgY,Card.width,Card.height,cards[1].posX, cards[1].posY);
ctx.drawImage(Card.img,cards[2].imgX,cards[2].imgY,Card.width,Card.height,cards[2].posX, cards[2].posY);
}
}
var ctx = foo.getContext("2d");
should this not be
var ctx = cvs.getContext("2d");
You seem to have confused the static properties of the Card function object with those of the Card instances - the width and height properties are instance properties.
var cvs = document.getElementById("foo");
var ctx = cvs.getContext("2d");
function Card(posX, posY, imgX, imgY){
this.posX = posX;
this.posY = posY;
this.imgX = imgX;
this.imgY = imgY;
}
// default values/methods, accessible and overwritable on all instances:
Card.prototype.width = 97;
Card.prototype.height = 129;
Card.prototype.draw = function() {
ctx.drawImage(Card.img, this.imgX, this.imgY, this.width, this.height, this.posX, this.posY);
};
// static property:
Card.img = new Image();
Card.img.src = "allcards.png";
Card.img.onload = draw;
var cards = [new Card(0,0,0,0), new Card(400,400,194,258), new Card(200,200,291,387)];
function draw(){
ctx.fillStyle="rgb(0,255,255)";
ctx.clearRect(0,0,600,600);
for (var i=0; i<2; i++)
cards[i].draw();
};

Categories

Resources