0

jsfiddleを50〜100回更新するたびに、私が作成した新しい問題の解決に役立つstackoverflowコミュニティにアクセスできるようです。ほんとありがと!

背景:アニメーションを含むいくつかの関数があります。関数は、前の関数が完了した後に起動されます。いくつかの助けと調査により、私は$ .whenと.promise()を使用して、各関数の最初の非常に醜いコールバック文字列とsetTimeoutsを制御し始めました。

私のジレンマは次のとおりです。ある時点で、ユーザーはすべてを一時停止して、暇なときに再開したいと思うかもしれません。この機能を追加できないようです!

$('div:animated')。stop()を使用してすべてのアニメーションを一時停止できますが、.promise()はまだ解決されるため、これは一時的なものです。その動作をオーバーライドする方法はありますか?一時停止と再開を実装しやすくするのに役立つ可能性のあるリストラはありますか?

明日は、すべてのアニメーションをプロキシオブジェクトキューに追加する予定ですが、新しいオブジェクトでグローバルキューを作成すると、既存の構造でどれだけうまく機能するかわかりません。また、値がオフになっているかどうかを確認するためにブール値を追加することも検討します。関数を呼び出したり、アニメーション化したりしないでください。これらの解決策のいずれかが私が取るべき適切な方向性であるかどうかわかりませんか?

この投稿をプレビューした後、ネストされたスタートボタン機能をリファクタリングする方法も学びたいと思います。

一時停止および再開機能の実装に関するあらゆる指示をいただければ幸いです。

以下のコードは非常に単純化されており、各関数にはより多くの要素とアニメーションが含まれています。

ここにフィドル

JS:

    $('#start').click( function() {
    // run a and wait one second, when done run b and wait 1 second...
    a().delay(100).promise().done( function(){
        b().delay(100).promise().done( function(){
            c().delay(100).promise().done( function(){
                d().delay(100).promise().done( function(){
                    e().delay(100).promise().done( function(){
                        f().delay(100).promise().done( function(){
                            alert('all done!');
                        });
                    });
                });
            });
        });
    });


    });

    $('#reset').click( function() {
        $('.box').css({
            top: '0px'
        });
    });
    $('#pause').click( function() {
        $('div:animated').stop();
    });
   function a() {
        return $('.box1').animate({top: '100px'}, 1000, function(){
            $('.box1').animate({top: '50px'}, 1000);        
        });
        return $('.box6').animate({top: '200px'}, 4000);
    }
    function b(){
        return $('.box2').animate({top: '100px'}, 1000);
    }
    function c(){
        return $('.box3').animate({top: '100px'}, 1000, function(){
            $('.box3').animate({top: '50px'}, 1000);        
        });
    }
    function d(){
        return $('.box4').animate({top: '100px'}, 1000);
    }
    function e(){
        return $('.box5').animate({top: '100px'}, 1000, function(){
            $('.box5').animate({top: '50px'}, 1000);        
        });
    }
    function f(){
        return $('.box6').animate({top: '100px'}, 1000);
    }

htmlとCSS

<button id='start'>animate</button>
<button id='reset'>Reset</button>
<button id='pause'>pause</button>
<div class='boxes'>
    <div class='box box1'></div>
    <div class='box box2'></div>
    <div class='box box3'></div>
    <div class='box box4'></div>
    <div class='box box5'></div>
    <div class='box box6'></div>
</div>​
.boxes{position: relative}
.box{width: 40px; height: 40px; background-color: green; position:absolute;}
.box1{left: 0px;}
.box2{left: 60px;}
.box3{left: 120px;}
.box4{left: 180px;}
.box5{left: 240px;}
.box6{left: 300px;}
​

編集 あなたの答えは私が探していた学習体験を提供してくれました。マインドシェアに本当に感謝しています!私の考案した例では、提示された回答では複数のアニメーションを同時に起動できないため、現実の問題を十分に示していない可能性がありますか?少なくとも思いませんか?たとえば、box1とbox2が同時に移動する場合や、box3が起動するとbox6も移動する場合があります。私が実装した最初の非常に醜いpromiseシステムは、各関数が多くのアニメーションで構成されていたため、多くの関数を使用していました。提案された回答でこれをどのように達成しますか?

EDIT2 2つの答え、charlietflを使用すると、同時に起動する2次関数を簡単に追加できます非常に重要です。Alnitak'sには、配列を作成してアニメーションに適用するエレガントな方法があり、アニメーションの種類を非常に簡単に変更できます(fadeOut()、fadeIn())。

したがって、私がやろうとしているのは、Alnitaks配列形式を使用するセカンダリアニメーション用のネストされた配列を作成できるように、2つを組み合わせることです。

['.box1', 'animate', { top:  '50px'}, 1000],

つまり、私はまだすべての答えに取り組んでいますが、charlietflsに近づいています。Alnitakの配列を彼に追加するか、charlietflのネストをAlnitakに追加します。

これは私が今まで意図していたよりも激しくなりました。私はあなたの貢献と学ぶためのコードに感謝します....非常に有益です!

4

2 に答える 2

3

複数の同時アニメーションを許可するjQueryメソッドはすべて非常に優れていますが、アニメーションがすべてシーケンシャルである場合、それはやり過ぎです。

アニメーションの説明の配列を作成してから、単純なループで一度に1つずつ呼び出すことをお勧めします。

各説明では、アニメーション化する要素、呼び出す関数、および関数の引数を知る必要があります。

アニメーションを一時停止することは、ループを進行しないという問題にすぎません。

function next() {
    if (!animating) return;

    var a = list.shift();
    if (a) {
        var el = a[0];
        var fn = a[1];
        var args = a.slice(2);
        $.fn[fn].apply($(el), args).promise().done(next);
    } else {
        alert('all done!');
    }
};

デモについては、 http://jsfiddle.net/alnitak/ANRa3を参照してください。

于 2012-11-16T22:38:03.123 に答える
1

のコールバックを使用してセカンダリアニメーションを呼び出すのではなく、animateチェーンanimate().delay().animate()すると、セカンダリアニメーションのpromiseを返すことができます。

私のソリューションでは、オブジェクトのネストされた配列を使用しているため、1つのシーケンスに必要な数のアニメーションを簡単に追加できます。秘訣は、グループ内のすべてのPromiseの配列を作成し、その配列を使用して、アニメーションの完全なグループがいつ完了するかを決定することです。

サンプルデータ:

var animations = [
   /* first group array */
    [ {  "sel": ".box1","main": {"css": {"top": "100px"},"dur": 1000},
         "secondary": {"delay": 100,"css": {"top": "50px"},"dur": 1000    }
        },
        {"sel": ".box2","main": {"css": {"top": "100px"},"dur": 1000}},
       {"sel": ".box4","main": {"css": {"top": "100px"},"dur": 1000}},
      {    "sel": ".box5","main": {"css": {"top": "100px"},"dur": 1000},
            "secondary": {"delay": 100,"css": {"top": "50px"},"dur": 1000    }
        }      
    ],
     /* second group array */
    [ { "sel": ".box3","main": {"css": {"top": "100px"},"dur": 1000},
            "secondary": {"delay": 100,"css": {"top": "50px"},"dur": 1000    }
        },
       {"sel": ".box4","main": {"css": {"top": "100px"},"dur": 1000}}
    ]
];

JS:

var curr = -1;
var paused = false;

function animateBoxes() {
    if (paused) {
        return;
    }
    //curr = (curr + 1 < animations.length) ? curr + 1 : 0;
    curr=curr+1;

    if( !animations[curr]){
        alert('DONE!!');
        return;
    }
    /* array of animation deffereds*/
    var anims = [];

    $.each(animations[curr], function(i, currAnim) {
        var anim = boxAnimate(currAnim);
        anims.push(anim)
    });

    $.when.apply(null, anims).done(function() {
        animateBoxes();
    });
}


$('#start').click(function() {
    paused = false;
    animateBoxes();
});

$('#reset').click(function() {
    curr = -1;
    stopanimation();
    $('.box').css({
        top: '0px'
    });
});
$('#pause').click(function() {
    stopanimation();
});


function stopanimation() {
    paused = true;
    $('div:animated').stop(true, true);

}

function boxAnimate(obj) {

    var $el = $(obj.sel),
        anim;
    if (obj.secondary) {
        /* chain animate & delay to get promise for last effect */
        anim = $el.animate(obj.main.css, obj.main.dur)
                  .delay(obj.secondary.delay)
                  .animate(obj.secondary.css, obj.secondary.dur)
    } else {
        anim = $el.animate(obj.main.css, obj.main.dur)
    }
    return anim;
}

デモ:http://jsfiddle.net/SWHTx/5/

于 2012-11-16T23:04:19.460 に答える