如何在画布中为线条设置动画

时间:2015-03-20 18:28:27

标签: javascript animation canvas greensock

我正在尝试使用画布为线条设置动画。我想使用TimelineLite来处理动画。我该怎么做?我知道在TimelineLite中,时间轴看起来像这样:

var timeline = new TimelineLite();
timeline.to(target, duration, vars, position);

这些点存在于JSON文件中,并且正确地使用AJAX引入了该文件。我希望这条线从x1点开始。 y1,将x2保持为相同的值,并将其设置为y2位置的动画。所以我基本上希望它从x1-y1增长到x2-y2。

JS

function animateLines(name, stroke, width, x1, y1, x2, y2){
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineWidth = width;
    ctx.strokeStyle = stroke;
    ctx.stroke;
    console.log(x2);
}

for(var i = 0; i < animated_lines.length; i++){
    animateLines(animated_lines[i].name, animated_lines[i].stroke, animated_lines[i].width, animated_lines[i].x1, animated_lines[i].y1, animated_lines[i].x2, animated_lines[i].y2);
}

JSON

"animated_lines": [
    {
        "name": "Test",
        "stroke": "red",
        "width": 3,
        "x1": 0,
        "y1": 0,
        "x2": 0,
        "y2": 50
    }
]

所以我的问题实际上是多方面的问题。如何使用画布动画线条?如何根据name函数中的animateLine()为该行添加动画效果?

2 个答案:

答案 0 :(得分:0)

TimelineLite 使用element转换该元素的目标值。

您可以随着时间的推移使用onUpdate观看转换的更新进度,并根据该值为您的线设置动画。

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

这是一个工作示例代码段

我正在时间轴中过渡画布不透明度并为画布设置动画。

var timeline = new TimelineLite();
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
}];

function createLine(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);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<canvas id="ctx" />

答案 1 :(得分:0)

this是您想要产生的效果还是类似的东西?

JS如下:

var width,height,centerX,centerY,canvas,context;
var delayFactor=.06,duration=1.2,ease=Elastic.easeOut,destIncrement=200,strokeWidth=2;
var timeline=new TimelineMax({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}
];
function init(){
    initCanvas();
    initLines();
    populateTimeline();
    timeline.play();
    TweenLite.ticker.addEventListener('tick',render);
}
function populateTimeline(){
    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);
    }
}
function initLines(){
    var length=animatedLines.length,currentLine;
    for(var i=0; i<length; i+=1){
        currentLine=animatedLines[i];
        currentLine.destX=currentLine.x1;
        currentLine.destY=currentLine.y1;
    }
}
function initCanvas(){
    canvas=document.querySelector('canvas');
    context=canvas.getContext('2d');
    width=canvas.width=window.innerWidth;
    height=canvas.height=window.innerHeight;
    centerX=width*.5;
    centerY=height*.5;
}
function drawLine(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();
}
function render(){
    var length=animatedLines.length;
    context.clearRect(0,0,width,height);
    for(var i=0; i<length; i+=1){ drawLine(animatedLines[i]); }
}
init();

诀窍是在animatedLines的每个 Line 中引入两个新变量,即destXdestY,并将其初始值设置为分别在x1函数下定义的y1initLines();。然后使用在x2函数中发生的y2使其增加到TimelineMaxpopulateTimeline();值。

继续,看一下jsFiddle,让它更进一步。

希望这对你有所帮助。