【问题标题】:Why aren't my setTimeouts between functions working?为什么我的函数之间的 setTimeouts 不起作用?
【发布时间】:2012-04-26 16:42:40
【问题描述】:

我有一系列拉斐尔动画,我想按特定顺序触发。

  1. 淡入曲线。
  2. 淡入球。
  3. 沿曲线为球设置动画。

我在每个函数之间都有一个 setTimeout,但动画只是同时触发。

View it on JSFiddle 或这里:

Raphael("bounce", 640, 480, function () {
        var r = this,
            p =                 r.path("M0,77.255c0,0,269.393,37.431,412.96,247.653 c0,0,95.883-149.719,226.632-153.309").attr({stroke: "#666", opacity: .0, "stroke-width": 1}),
            len = p.getTotalLength(),
        e = r.circle(0, 0, 7).attr({stroke: "none", fill: "#000", opacity:0}).onAnimation(function () {
                var t = this.attr("transform");
            });
        r.customAttributes.along = function (v) {
            var point = p.getPointAtLength(v * len);
            return {
                transform: "t" + [point.x, point.y] + "r" + point.alpha
            };
        };
        e.attr({along: 0});

        var rotateAlongThePath = true;
        function fadecurve(ca,ba,aa,ab){
            ca.animate({opacity:1},2000);
            setTimeout(fadeball(ba,aa,ab),6000);
        }
        function fadeball(ba,aa,ab) {
               ba.animate({opacity:1},400);
               setTimeout(run(ba, aa,ab),5000);
        }
        function run(ba,aa,ab) {
               ba.animate({opacity:1},400);
               ba.animate({along: aa}, ab, ">", function () {
                ba.attr({along: aa});
            });
        }
        fadecurve(p,e,.9,500);
});   

【问题讨论】:

    标签: javascript jquery animation raphael settimeout


    【解决方案1】:

    使用匿名函数,例如:

    setTimeout(function(){
      fadeball(ba,aa,ab);
    },6000);
    

    使用setTimeout(fadeball(ba,aa,ab),6000);,函数fadeball 会因为() 而立即被调用,这就是问题所在。

    确保也以这种方式调用run 函数:)

    【讨论】:

      【解决方案2】:

      问题在于你的函数在你的 setTimeout 中引用

      setTimeout(fadeball(ba,aa,ab),6000);
      

      您在这里所做的是执行函数,然后将结果分配为 ​​setTimeout 的第一个参数,如果您使用匿名函数就可以了。

      setTimeout(function(){
        fadeball(ba,aa,ab);
      },6000);
      

      【讨论】:

        【解决方案3】:

        您正在立即调用您的函数,然后将该函数的结果传递给setTimeout。您需要将函数传递给setTimeout

        setTimeout(function(){
            fadeball(ba,aa,ab);
        },6000);
        

        【讨论】:

          【解决方案4】:

          很抱歉,如果这是题外话,但你这样做的方式是不可扩展的。虽然像这样设置重复超时适用于一些功能,但随着步数的增加,多步动画变得越来越麻烦。 jQuery 可以对动画进行排序,但 jQuery 的内置动画队列通常不提供所需的功能(如瀑布属性)。这是Frame.js 的更简洁、强大和可扩展的替代方案:

            var ca = p, ba = e, aa = .9, ab = 500;
            Frame(500, function(next){
                ca.animate({opacity:1}, 2000, next);
            });
            Frame(4000, function(next){
                ba.animate({opacity:1}, 400, next);
            });
            Frame(5000, function(next){
                ba.animate({opacity:1}, 400);
                ba.animate({along: aa}, ab, ">", next);
            });
            Frame(function(next){
                ba.attr({ along: aa });
                next();
            });
            Frame.init();
          

          【讨论】:

            【解决方案5】:

            JQuery 的 animate 函数有一个动画完成回调,因此您可以连续触发动画:

            function SecondAnimation() { $('element').animate(....., ThirdAnimation); }
            function ThirdAnimation() { $('element').animate(....., FourthAnimation); }
            function FourthAnimation() { $('element').animate(.....); }
            
            
            $('element').animate(....., SecondAnimation);
            

            【讨论】:

            • delay 将是必需的,并且动画不会立即连续运行,但这是一个有效的替代方案。
            猜你喜欢
            • 2021-03-21
            • 2021-12-18
            • 2011-06-23
            • 1970-01-01
            • 2017-08-18
            • 2010-10-18
            • 1970-01-01
            • 2022-11-25
            • 1970-01-01
            相关资源
            最近更新 更多