Zenel Shabani Zenel Shabani - 3 months ago 14
Javascript Question

Control multiple canvas animations

Is it possible to hook into a Canvas animation that has already been drawn?
I'm trying to create 3 seperate tracks that must be controlled by a "Start" and "Stop" button, but when pressing the Start button of the first canvas , it makes the last canvas run.

See current codepen progress

This is what I have so far.

class Animation{
constructor(){
this.options = {
left : 0,
animate : false
}
let tracks = $('.line');
let self = this;
tracks.each(function(){
self.startbtn = $(this).find('button.start');
self.stopbtn = $(this).find('button.stop');
self.canvas = $(this).find('canvas').get(0);
self.canvas.width = 1000;
self.canvas.height = 30;
self.ctx = self.canvas.getContext('2d');
self.draw(self.canvas,self.ctx);
self.startbtn.bind('click',() => {
self.options.animate = true;
self.draw(self.canvas,self.ctx);
})
});
}
draw(c,ctx){
ctx.clearRect(0,0,c.height,c.width);
ctx.fillRect(this.options.left,0,1,30);
if(this.options.animate){
requestAnimationFrame(() => {
console.log('done');
this.options.left += 1;
console.log(this.options.left)
this.draw(c,ctx);
});
}
}
}

new Animation();

Answer

Your code has scope issues and you had to insure that each track is operating separate from its constructor.

This is where i'd made sure information is entirely independent for the given track/parent element.

this.options = *set*;//left and animate separate for own process 
this.node = *set*;//nodes for each track
this.ctx = *set*;//draw command context set at the parent
this.draw = *set*;//draw function moved to track

Here is complete edit to your code:

class Animation{
  constructor(){
    var tracks = $('.line');
    var self = this;
    tracks.each(function () {
      this.options = {//options seperate to parent track node
        left: 0,
        animate: false
      };
      this.node = {//store child nodes for access
        startbtn: $(this).find('button.start'),
        stopbtn: $(this).find('button.stop'),
        canvas: $(this).find('canvas').get(0)
      };
      this.node.canvas.width = 1000;
      this.node.canvas.height = 30;
      this.ctx = this.node.canvas.getContext('2d');
      this.node.startbtn.bind('click',() => {// () => parentNode instantiation
        this.options.animate = true;
        this.draw(this.node.canvas, this.ctx);
      });
      this.draw = self.draw;
    });
  }
  draw(c,ctx){
    parent = c.parentNode;
    ctx.clearRect(0,0,c.height,c.width);
    ctx.fillRect(parent.options.left,0,1,30);
    if(parent.options.animate){
        requestAnimationFrame(() => {
          console.log('done');
          parent.options.left += 1;
          console.log(parent.options.left)
          parent.draw(c,ctx);
      });
    }
  }
}

new Animation();

Scope and object handling needed to be done, I'll explain later.

http://codepen.io/anon/pen/JKzBLK

Comments