Пример: 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;
}
расслоение плотной файла:
$(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 o, как я исследовал, у меня есть следующая ситуация:
- TweenMax (так как использует requestAnimationFrame) зависает, когда вкладка неактивна.
- setInterval продолжать движение, когда вкладка неактивна (также может зависеть ее задержка, если вкладка неактивна, зависит от браузера)
- Есть ли какая-либо другая функция javascript, которая изменяется, когда вкладка неактивна?
Тогда у меня есть 2 решения:
- Замораживание вся игра, когда вкладка неактивна.
- Продолжайте движение, когда вкладка неактивна.
С первым решением у меня есть следующая проблема: в TweenMax использует requestAnimationFrame, он работает правильно в соответствии с этим решением (замерзает анимацию), но как я могу заморозить интервалы и время ожидания, когда вкладка неактивна, а затем возобновить интервалы и время ожидания?
Со вторым решением я могу использовать TweenMax.lagSmoothing (0) и TweenMax.ticker.useRAF (false) для анимации, и это работает, но в любом случае что-то не так с интервалами и/или таймаутами. Я ожидал, что анимация пойдет не так из-за изменения задержки интервала до 1000+ мс, когда вкладка неактивна (согласно http://stackoverflow...w-is-not-active), но я отключил ускорение и установил задержки на 2000 мс, и это не помогло.
Пожалуйста, помогите мне хотя бы с одним решением. Лучше, чтобы оба имели разновидность.