使用HTML5画布在另一个动画之后动画一行

时间:2014-05-29 15:11:52

标签: javascript jquery html5 animation canvas

我遇到的问题是我的直线在页面加载开始时向圆圈开始动画。在完成第一个动画(圆圈)后,我无法弄清楚在另一个方向上设置动画线的逻辑。

总的来说,我想完成一个双动画,其中直线开始动画到左边,源于圆圈,只有在圆圈完成其完整动画之后。

HTML

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
       <canvas id="cas"></canvas>
    </body>
</html>

的Javascript

$(function () {
    //gloabl definitions
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    var canvas = document.getElementById('cas');
    var context = canvas.getContext('2d');

    canvas.width = 470;
    canvas.height = 400;

    //core plugin features & call
    var circleDefaults = {
        circlePos: {
            x: 338,
            y: 130
        },
        radius: 120,
        counterClockwise: false,
        startAngle: Math.PI / 2,
        endAngle: Math.PI * 2,
        currentPercent: 0,
        endPercent: 90
    }

    var lineDefaults = {
        movePos: {
            x: 0,
            y: 80
        },
        linePos: {
            x: 10,
            y: 80
        }
    }

    function AnimateCircle(current) {
        context.beginPath();
        context.arc(circleDefaults.circlePos.x, circleDefaults.circlePos.y, circleDefaults.radius, -(circleDefaults.startAngle), ((circleDefaults.endAngle) * current) - circleDefaults.startAngle, circleDefaults.counterClockwise);
        context.lineWidth = 0.5;

        context.strokeStyle = "#000"
        context.stroke();
        context.closePath();

        context.beginPath();
        context.moveTo(830, 80);
        context.lineTo(400, 80);
        context.stroke();
        context.closePath();

        circleDefaults.currentPercent++;
        if (circleDefaults.currentPercent < circleDefaults.endPercent) {
            requestAnimationFrame(function () {
                AnimateCircle(circleDefaults.currentPercent / 100);
            });
        }
    }

    function AnimateLine() {
        context.beginPath();
        context.moveTo(lineDefaults.movePos.x, lineDefaults.movePos.y);
        context.lineTo(lineDefaults.linePos.x, lineDefaults.linePos.y);
        context.stroke();
        context.closePath();

        lineDefaults.linePos.x++;

        if (circleDefaults.currentPercent < lineDefaults.linePos.x) {
            requestAnimationFrame(function () {
                AnimateLine();
            });
        }
    }

    AnimateCircle();
    AnimateLine();
});

以下是我的小提琴:

http://jsfiddle.net/coder101/fa28A/

谢谢!

4 个答案:

答案 0 :(得分:4)

你的意思是这种动画吗? http://jsfiddle.net/fa28A/1/

让我们继续,逐一解决您的每一个问题。

  

其中直线开始动画到左边,源自圆圈

你并不是很清楚所以我只是假设这条线在圆圈内开始直到左端点。

AnimateLine()功能中,当你想让它向左移动时,你正在做的就是慢慢向右移动你的线。

context.beginPath();
context.moveTo(lineDefaults.movePos.x, lineDefaults.movePos.y);
context.lineTo(lineDefaults.linePos.x, lineDefaults.linePos.y);
context.stroke();
context.closePath();

lineDefaults.linePos.x++; //here's what makes it go right

另一个问题是你继续/终止画线的条件。

//i don't understand this condition
if (circleDefaults.currentPercent < lineDefaults.linePos.x) {
    requestAnimationFrame(function () {
        AnimateLine();
    });
}

也许您正试图将这个条件用于&#34;同步&#34;绘图或其他什么,但重点是,它不起作用,它没有意义。

这是AnimateLine()函数应该发生的问题,以解决上述问题:

function AnimateLine() {
  context.beginPath();
  context.moveTo(lineDefaults.movePos.x, lineDefaults.movePos.y);
  context.lineTo(lineDefaults.linePos.x, lineDefaults.linePos.y);
  context.stroke();
  context.closePath();

  //see how i made this to decrements so that it will move to the left instead
  lineDefaults.linePos.x--; 

  //adjust this to where you want the line to end
  var end_of_line = 0; 
  if (lineDefaults.linePos.x > end_of_line) {
    requestAnimationFrame(function () {
      AnimateLine();
});
  }
}

下次关注:

  

仅在圆圈完成其完整动画

之后

如果您熟悉回调,我使用相同的概念。

if (circleDefaults.currentPercent < circleDefaults.endPercent) {
  requestAnimationFrame(function () {
    AnimateCircle(circleDefaults.currentPercent / 100);
  });
}
//I added this part, since the condition above is the "while drawing" state,
//    its negation, the else part, would be the "finished drawing" state
else{
  AnimateLine();
}

Protip:不是绘制线条,而是在其上面应用另一条线(但更长)来模拟动画,而是尝试绘制位线和位线。从理论上讲,它的运行速度会更快。虽然在这样的小动画中,它确实很重要。哈哈。

答案 1 :(得分:0)

为什么不设置延迟

setTimeout( AnimateLine, 10000);

答案 2 :(得分:0)

您可以随时向Animate圈子功能添加回调功能,该功能会在完成后调用您的下一个动画。

function AnimateCircle(current, callback) {
...

if (circleDefaults.currentPercent < circleDefaults.endPercent) {
        requestAnimationFrame(function () {
            AnimateCircle(circleDefaults.currentPercent / 100, callback);
        });
    }
else
    callback();
...
}

...

AnimateCircle(null, AnimateLine);

但请确保您在AnimateLine中更改此条件,否则该行不会出现:

if (circleDefaults.currentPercent < lineDefaults.linePos.x) {

答案 3 :(得分:0)

您可以使用jQuery的Deferred对象轻松地按顺序处理函数。一个简单的例子(source):

function wait(ms) {
  var deferred = $.Deferred();
  setTimeout(deferred.resolve, ms);
  return deferred.promise();
}

wait(1500).then(function () {
  // Do something after wait() has resolved
});

以下是应用于画布动画时的外观: CSSDeck example