0

私は、JavaScript によって管理される多くのアニメーションを含む Web サイトを実行しています。開始時に、アニメーション用の関数といくつかの変数を定義し、このようにプロセスを繰り返しました。そして、考えるのは良い方法ではありません。

//BRIGHT ANIMATION  
var frameWidth1 = 386;
var frameHeight1 = 100;
var spriteWidth1 = 20067;
var spriteHeight1 = 100;
var spriteElement1 = document.getElementById("bright");

var curPx1 = 0;
var ti1;

function animateSpriteB() {

    spriteElement1.style.backgroundPosition = "-" + curPx1 + 'px 0px';
    curPx1 = curPx1 + frameWidth1;

    if (curPx1 >= spriteWidth1) {
        curPx1 = 0;
    }

    ti1 = setTimeout(animateSpriteB, 70);

}

animateSpriteB();


//  PAPIRO ANIMATION

var frameWidth = 56;
var frameHeight = 218;
var spriteWidth = 2016;
var spriteHeight = 218;
var spriteElement = document.getElementById("roll-off");

var curPx = 0;
var ti;

function animateSprite() {

    spriteElement.style.backgroundPosition = "-" + curPx + 'px 0px';
    curPx = curPx + frameWidth;

    ti = setTimeout(animateSprite, 27.7);

    if (curPx === spriteWidth) {
        clearTimeout(ti);
    }

}

function slideMask(){
    var mask = $("#paper-mask");
    var paper = $("#paper");

    mask.animate({
        width: 450
    },{
        duration: 1000,
        complete: function(){
            $("#paper-content").fadeIn();
        }
    });

}

var ti = setTimeout(function(){
    animateSprite();
    slideMask();
}, 3000);

そこで、コンストラクターを使用して同じコードを再利用し、Web サイト内のすべてのアニメーションを管理することにしました。私はこのようなものを持ってきました:

// CONSTRUCTOR WHO MANAGE THE ANIMATIONS FOR THE WEBSITE
        function SpriteAnimation(frameWidth, spriteWidth, spriteElement, isLoop){
            this.frameWidth = frameWidth;
            this.spriteWidth = spriteWidth;
            this.spriteElement = spriteElement;
            this.isLoop = isLoop;
            this.curPx = 0;
            this.ti;
        }

        SpriteAnimation.prototype.start = function(){

            var selector = document.getElementById(this.spriteElement);

            selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
            this.curPx = this.curPx + this.frameWidth;

            this.ti = setTimeout(this.start, 2000);

            if (this.curPx === this.spriteWidth){
                clearTimeout(this.ti);
            }

            this.start();

        }

        var letter = new SpriteAnimation(935.4, 17774, "letter", true);
        letter.start();

コードを実行するたびにブラウザがクラッシュするだけで、パフォーマンスに問題があります。また、ループがうまくいかないと思います。ここで私の質問があります: ループ アニメーションやスプライト パラメーターのようなパラメーターを渡すことができるオブジェクト コンストラクターを使用してアニメーションを管理するにはどうすればよいですか?

@Tibosあなたのコードは私にとって大きな助けになりました。これを達成するためにほぼ4時間費やしましたが、それから出てきて本当に簡単になりました。そのため、すべてのアニメーションで異なるフレーム レートを使用できます。また、スプライトが消えるまでアニメーションが実行されていたため、if ステートメントを少し変更しました。最後のフレームにとどまる必要があります。これが正しい形式であるかどうかを教えてください。

// CONSTRUCTOR WHO MANAGE THE ANIMATIONS FOR THE WEBSITE
        function SpriteAnimation(frameWidth, spriteWidth, spriteElement, shouldLoop, frameRate){
            this.frameWidth = frameWidth;
            this.spriteWidth = spriteWidth;
            this.selector = document.getElementById(spriteElement);
            this.shouldLoop = shouldLoop ;
            this.curPx = 0;
            this.frameRate = frameRate;
            this.ti;
        }

        SpriteAnimation.prototype.start = function(){

            this.selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
            this.curPx += this.frameWidth;

            if (this.curPx < (this.spriteWidth - this.frameWidth)){
                setTimeout(this.start.bind(this), this.frameRate);
            } else if (this.shouldLoop) {
                this.curPx = 0;
                this.start();
            }

        };

        var letter = new SpriteAnimation(935.4, 17774, "letter", true, 60);
        letter.start();
4

2 に答える 2

1

コードにいくつかの問題があります。影響の大きい順にここに示します。

  • start を再帰的に呼び出す
  • これへの参照を失う
  • タイムアウトが設定されるとすぐにクリアする
  • 未使用の変数
  • 各反復で要素を選択する

ここにいくつかのより良いコードがあります(動作します):

function SpriteAnimation(frameWidth, spriteWidth, spriteElement, shouldLoop){
    this.frameWidth = frameWidth;
    this.spriteWidth = spriteWidth;
    this.selector = document.getElementById(spriteElement);
    this.curPx = 0;
    this.shouldLoop = shouldLoop;
}

SpriteAnimation.prototype.start = function(){
    this.selector.style.backgroundPosition = "-" + this.curPx + "px 0px";
    this.curPx += this.frameWidth;

    if (this.curPx <= this.spriteWidth){
        setTimeout(this.start.bind(this), 2000);
    } else if (this.shouldLoop) {
        this.curPx = 0;
        this.start();
    }
};

var letter = new SpriteAnimation(935.4, 17774, "letter", true);
letter.start();

デモ: http://jsbin.com/oJIYoRU/1/edit

于 2013-10-31T15:14:29.743 に答える
0

この関数は、基本ケースなしで自分自身を再帰的に呼び出します。呼び出すとすぐに、UI がロックされ、コール スタックがオーバーフローします。

SpriteAnimation.prototype.start = function(){
    ... some code ...
    this.start();

}
于 2013-10-31T15:02:50.617 に答える