0

サンプル: http://codepen.io/anon/pen/xgZMVd/Javascriptのアニメーションがうまくいかない

htmlファイル:

<div class="game-page"> 
</div> 

CSSファイル:

.game-page { 
    width: 1024px; 
    height: 768px; 
    position: absolute; 
    background-color: grey; 
} 

.stick { 
    position: absolute; 
    left: 50%; 
    margin-left: -94px; 
    top: -60px; 
    width: 188px; 
    height: 50px; 
    background-color: black; 
} 

JSファイル:

$(document).ready(function() { 
    init(); 
}); 

var CSS_CLASS = { STICK: "stick" }, 
    changeSpeedTime = 1000, //in milliseconds 
    gameTime = 60, //in seconds 
    timer = 1, //in seconds 
    windowWidth = 1024, 
    windowHeight = 768, 
    stickTop = -60, 
    restStickTime = 0, //in milliseconds 
    initialStickInterval = 1000, //in milliseconds 
    stickInterval = null, //in milliseconds 
    initialStickDuration = 7, //in seconds 
    stickDuration = null, //in seconds 
    stickTweensArray = [], 
    changeSpeedInterval = null, 
    countdownTimerInterval = null, 
    generateSticksInterval = null, 
    generateSticksTimeout = null, 
    $gamePage = null; 

function init() { 
    initVariables(); 
    initGamePage(); 
} 

function changingSpeedFunction(x){ 
    var y = Math.pow(2, (x/20)); 
    return y; 
} 

function initVariables() { 
    $gamePage = $(".game-page"); 
    stickDuration = initialStickDuration; 
    stickInterval = initialStickInterval; 
} 

function initGamePage() { 
    TweenMax.ticker.useRAF(false); 
    TweenMax.lagSmoothing(0); 
    initGamePageAnimation(); 
} 

function initGamePageAnimation() { 
    generateSticks(); 

    changeSpeedInterval = setInterval(function() { 
    changeSpeed(); 
    }, changeSpeedTime); 

    countdownTimerInterval = setInterval(function() { 
    updateCountdown(); 
    }, 1000); 
} 

function changeSpeed() { 
    var x = timer; 
    var y = changingSpeedFunction(x); //change speed function 
    stickDuration = initialStickDuration/y; 
    stickInterval = initialStickInterval/y; 

    changeCurrentSticksSpeed(); 
    generateSticks(); 
} 

function changeCurrentSticksSpeed() { 
    stickTweensArray.forEach(function(item, i, arr) { 
    var tween = item.tween; 
    var $stick = item.$stick; 

    var oldTime = tween._time; 
    var oldDuration = tween._duration; 
    var newDuration = stickDuration; 
    var oldPosition = stickTop; 
    var newPosition = $stick.position().top; 
    var oldStartTime = tween._startTime; 

    var distance = newPosition - oldPosition; 
    var oldSpeed = distance/oldTime; 
    var newSpeed = oldSpeed * oldDuration/newDuration; 
    var newTime = distance/newSpeed; 
    var currentTime = oldStartTime + oldTime; 
    var newStartTime = currentTime - newTime; 

    item.tween._duration = newDuration; 
    item.tween._startTime = newStartTime; 
    }); 
} 

function generateSticks() { 
    if (restStickTime >= changeSpeedTime) { 
    restStickTime -= changeSpeedTime; 
    restStickTime = Math.abs(restStickTime); 
    } else { 
    generateSticksTimeout = setTimeout(function() { 
     generateSticksInterval = setInterval(function() { 
     generateStick(); 
     restStickTime -= stickInterval; 
     if (restStickTime <= 0) { 
      clearInterval(generateSticksInterval); 
      restStickTime = Math.abs(restStickTime); 
     } 
     }, stickInterval); 
     generateStick(); 
     restStickTime = changeSpeedTime - Math.abs(restStickTime) - stickInterval; 
     if (restStickTime <= 0) { 
     clearInterval(generateSticksInterval); 
     restStickTime = Math.abs(restStickTime); 
     } 
    }, restStickTime); 
    } 
} 

function generateStick() { 
    var $stick = $("<div class='" + CSS_CLASS.STICK + "'></div>").appendTo($gamePage); 

    animateStick($stick); 
} 

function animateStick ($stick) { 
    var translateYValue = windowHeight + -stickTop; 

    var tween = new TweenMax($stick, stickDuration, { 
    y: translateYValue, ease: Power0.easeNone, onComplete: function() { 
     $stick.remove(); 
     stickTweensArray.shift(); 
    } 
    }); 

    stickTweensArray.push({tween:tween, $stick:$stick}); 
} 

function updateCountdown() { 
    timer++; 

    if (timer >= gameTime) { 
    onGameEnd(); 
    clearInterval(changeSpeedInterval); 
    clearInterval(countdownTimerInterval); 
    clearInterval(generateSticksInterval); 
    clearTimeout(generateSticksTimeout); 
    } 
} 

function onGameEnd() { 
    var $sticks = $gamePage.find(".stick"); 
    TweenMax.killTweensOf($sticks); 
} 

S私が調査したとき、次の状況があります:

  1. タブがアクティブでないときにTweenMax(それはrequestAnimationFrameを使用する)がフリーズします。
  2. タブがアクティブでないときにタブが非アクティブになる(タブがアクティブでないときに遅延が変化する可能性があります。ブラウザによって異なります)
  3. タブがアクティブでないときに変更されるJavaScript機能はありますか?タブがアクティブでないとき、

    1. フリーズゲーム全体:

    は、その後、私は2つのソリューションを持っています。

  4. タブが非アクティブの場合は続行します。 TweenMaxはrequestAnimationFrameのを使用して、それが(アニメーションをフリーズ)をこの溶液によると、正しい動作しますが、どのように私はタブがアクティブでないときの間隔とタイムアウトを凍結し、その後の間隔とタイムアウトを再開することができます:私は次の問題を抱えている最初のソリューションで

TweenMax.lagSmoothing(0)とTweenMax.ticker.useRAF(false)をアニメーションに使用することはできますが、動作しますが、間隔やタイムアウトに問題が発生します。私は、タブが非アクティブ(http://stackoverflow...w-is-not-activeによる)であるときにインターバルの遅延が1000 + msに変更されたためにアニメーションがうまくいかないと思っていましたが、加速を無効にし、遅延を2000msに設定しました。

少なくとも1つの解決策で私を助けてください。どちらにしてもバラエティーに富んでいます。

答えて

0

最初の解決策の問題を解決しました。ゲーム全体をフリーズしました。 setTimeoutとsetIntervalの代わりにTweenMax.delayedCall()関数を使用し、アニメーション全体を同期させるだけです。

関連する問題