【问题标题】:JavaScript Animation: Handling Complex Animations That Use Callbacks & LoopJavaScript 动画:处理使用回调和循环的复杂动画
【发布时间】:2015-06-29 18:05:35
【问题描述】:

我正在使用 Snap.svg 为 13 个 SVG 制作动画。所有的 SVG 都从一个点开始,并通过其他几个动画(通过回调)进行动画处理。下面用代码描述了我的动画的简化示例:

var reset = function(person) {
    person.attr({transform: 't0,0', opacity: 0});
    animatePerson(person);
};

var animatePerson = function(person) {
    person.animate({opacity: 1}, 300, null,function() {
        person.animate({transform: 't100,20'}, 1000, null, function() {
            person.animate({opacity: 0}, 300, null, function() {
                reset(person);
            });
        });
    });
};

var people = [Snap('#Person_1'), Snap('#Person_2'), Snap('#Person_3'), Snap('#Person_4'), Snap('#Person_5')];

我的第一次尝试是映射数组并为第一个动画设置超时,如下所示:

people.map(function(person, index) {
    setTimeout(function() {
        animatePerson(person);
    }, (300*index));
});

但这不起作用,因为 SVG 在循环时会开始相互重叠/超越。然后我尝试将超时设置为动画的一个完整“圈”所花费的时间长度,并将其除以 SVG 的总数,如下所示:

people.map(function(person, index) {
    setTimeout(function() {
        animatePerson(person);
    }, (1600/people.length));
});

在 Snap.svg 或 JavaScript 中是否有一种方法可以使用回调和/或超时来实现动画循环,或者我在这里?

这是我所指的完整动画的图像:

【问题讨论】:

  • 无关说明:Array.prototype.map 用于通过操作数组中的现有元素来创建新数组。如果您只想遍历数组,请使用Array.prototype.forEach 使您的意图更清晰(并避免创建 map 生成的额外数组)

标签: javascript snap.svg


【解决方案1】:

我这样做的一种方法是编写一个小函数,它接收一个元素和一组预设动画,并通过回调依次遍历它们,看起来像这样......

编辑:稍作修改,以便能够在每个动画中包含不同的元素,下面的示例 2 链接包括包含每次调用的函数的选项。

function nextFrame ( frameArray,  whichFrame ) {
    if( whichFrame >= frameArray.length ) { return }
    frameArray[ whichFrame ].el.animate(    
          frameArray[ whichFrame ].animation,
          frameArray[ whichFrame ].dur,
          frameArray[ whichFrame ].easing,
          nextFrame.bind(null,  frameArray, whichFrame + 1 )
    );
}

然后你可以传递一个动画数组,像这样......

var myFrames = [
    {   el: g,  animation: { transform: 'r360,150,150' }, dur: 1000, easing: mina.bounce },
    {   el: r,  animation: { transform: 't100,-100s2,3' }, dur: 1000, easing: mina.bounce },
    {   el: r,  animation: { transform: 't100,100' }, dur: 1000, easing: mina.bounce },
    {   el: g,  animation: { transform: 's2,1' }, dur: 1000, easing: mina.bounce },
    {   el: r,  animation: { transform: 's1,2' }, dur: 1000, easing: mina.bounce },
    {   el: c,  animation: { transform: 's1,1' }, dur: 1000, easing: mina.bounce }];

然后你可以用

调用它
nextFrame( el, myFrames, 0 );

example(点击运行)

example 2(这允许您包含要调用的函数以及它的一部分)

【讨论】:

  • 这适用于在一个元素上制作多个动画,但不适用于在多个元素上制作多个动画。我遇到的问题是元素相互重叠。
  • 很容易,只需在其中添加元素。我已经编辑了帖子并链接到一个示例,其中包含一个包含该元素的数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多