Skip to content Skip to sidebar Skip to footer

How To Animate A Line In Canvas

I am trying to animate a line using canvas. I want to use TimelineLite to handle the animation. How would I do this? I know that in TimelineLite, the Timelines look like this: va

Solution 1:

TimelineLite uses the element to transform the targeted values of that element.

You can watch the update progress of the transform using onUpdate over time and animate your line based on that value.

timeline.eventCallback('onUpdate',function(data){
    var progress = this.progress();
    // Do animation calls here!
});

Here is a working example code snippet

I am transitioning the canvas opacity during the timeline and animating the canvas.

var timeline = newTimelineLite();
var mainCanvas = document.getElementById("ctx");
var ctx = mainCanvas.getContext("2d");
var temp = document.createElement('div');

var animated_lines = [{
  "name": "Red",
  "stroke": "#ff0000",
  "width": 3,
  "x1": 50,
  "y1": 50,
  "x2": 100,
  "y2": 100
},{
  "name": "Green",
  "stroke": "#00ff00",
  "width": 2,
  "x1": 50,
  "y1": 20,
  "x2": 100,
  "y2": 100
}];

functioncreateLine(line, progress) {
  ctx.lineWidth = line.width;
  ctx.strokeStyle = line.stroke;
  ctx.beginPath();
  ctx.moveTo(line.x1, line.y1);
  ctx.lineTo(line.x2, line.y2*progress);
  ctx.stroke();
}
 
console.log('ctx', ctx);
timeline.from('#ctx', 10, { opacity: 0 });

timeline.eventCallback('onUpdate',function(){
  var progress = this.progress();
  //console.log(progress);
  ctx.clearRect ( 0 , 0 , mainCanvas.width, mainCanvas.height );
  for (var i = 0; i < animated_lines.length; i++) {
    createLine(animated_lines[i], progress);
  }
});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script><scriptsrc="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script><canvasid="ctx" />

Solution 2:

Is this the kind of effect you were looking to produce or something similar?

JS of which is as belows:

var width,height,centerX,centerY,canvas,context;
var delayFactor=.06,duration=1.2,ease=Elastic.easeOut,destIncrement=200,strokeWidth=2;
var timeline=newTimelineMax({paused:true,repeat:-1,yoyo:true,repeatDelay:duration*.5});
var animatedLines=[
    {name:'Test',stroke:'red',width:strokeWidth,x1:0,y1:0,x2:0,y2:destIncrement},
    {name:'Test',stroke:'green',width:strokeWidth,x1:0,y1:0,x2:destIncrement*.5,y2:destIncrement*.5},
    {name:'Test',stroke:'blue',width:strokeWidth,x1:0,y1:0,x2:destIncrement,y2:0},
    {name:'Test',stroke:'red',width:strokeWidth,x1:0,y1:0,x2:destIncrement*.5,y2:-destIncrement*.5},
    {name:'Test',stroke:'green',width:strokeWidth,x1:0,y1:0,x2:0,y2:-destIncrement},
    {name:'Test',stroke:'blue',width:strokeWidth,x1:0,y1:0,x2:-destIncrement*.5,y2:-destIncrement*.5},
    {name:'Test',stroke:'red',width:strokeWidth,x1:0,y1:0,x2:-destIncrement,y2:0},
    {name:'Test',stroke:'green',width:strokeWidth,x1:0,y1:0,x2:-destIncrement*.5,y2:destIncrement*.5}
];
functioninit(){
    initCanvas();
    initLines();
    populateTimeline();
    timeline.play();
    TweenLite.ticker.addEventListener('tick',render);
}
functionpopulateTimeline(){
    var length=animatedLines.length,currentLine;
    for(var i=0; i<length; i+=1){
        currentLine=animatedLines[i];
        timeline.to(currentLine,duration,{destX:currentLine.x2,destY:currentLine.y2,ease:ease},i*delayFactor);
    }
}
functioninitLines(){
    var length=animatedLines.length,currentLine;
    for(var i=0; i<length; i+=1){
        currentLine=animatedLines[i];
        currentLine.destX=currentLine.x1;
        currentLine.destY=currentLine.y1;
    }
}
functioninitCanvas(){
    canvas=document.querySelector('canvas');
    context=canvas.getContext('2d');
    width=canvas.width=window.innerWidth;
    height=canvas.height=window.innerHeight;
    centerX=width*.5;
    centerY=height*.5;
}
functiondrawLine(currentLine){
    context.lineWidth=currentLine.width;
    context.strokeStyle=currentLine.stroke;
    context.beginPath();
    context.moveTo(centerX+currentLine.x1,centerY+currentLine.y1);
    context.lineTo(centerX+currentLine.destX,centerY+currentLine.destY);
    context.stroke();
}
functionrender(){
    var length=animatedLines.length;
    context.clearRect(0,0,width,height);
    for(var i=0; i<length; i+=1){ drawLine(animatedLines[i]); }
}
init();

The trick is to introduce two new variables into each Line of your animatedLines, namely destX and destY, and set their initial values to that of your x1 and y1 respectively, defined under the initLines(); function. And then make them increment towards your x2 and y2 values using TimelineMax which happens in the populateTimeline(); function.

Go ahead and take a look at the jsFiddle to take it further.

Hope this is helpful to you in some way.

Post a Comment for "How To Animate A Line In Canvas"