JavaScript动画:处理使用回调的复杂动画&;环

JavaScript动画:处理使用回调的复杂动画&;环,javascript,snap.svg,Javascript,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},

我用它来制作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中有没有一种方法可以让动画循环使用回调和/或超时,或者在这里使用I方式

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


我这样做的一种方法是编写一个小函数,它接收一个元素和一组预设动画,然后通过回调依次遍历它们,如下所示

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 }];
编辑:稍加修改,以便能够在每个动画中包含不同的元素,下面的example2链接中包含了包含每次调用的函数的选项

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 );
(点击此处运行)


(这允许您包括要调用的func及其一部分)

不相关的注意:
Array.prototype.map
用于通过操纵数组中的现有元素来创建新数组。如果您只想在数组上迭代,请使用
array.prototype.forEach
使您的意图更清晰(并避免创建映射生成的额外数组),这对于在一个元素上设置多个动画非常有效,但对于在多个元素上设置多个动画则无效。我遇到的问题是元素相互重叠。只需在其中添加元素就足够简单了。我编辑了这篇文章,并链接到一个示例,该示例使用一个包含元素的数组来显示它。