【发布时间】:2017-05-26 07:45:50
【问题描述】:
示例: http://codepen.io/anon/pen/xgZMVd/
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);
}
所以,根据我的研究,我有下一个情况:
- TweenMax(因为它使用 requestAnimationFrame)在选项卡处于非活动状态时冻结。
- 当标签页处于非活动状态时,setInterval 继续运行(当标签页处于非活动状态时,它的延迟可能会改变,取决于浏览器)
- 在选项卡处于非活动状态时是否有任何其他JavaScript功能?
那么我有2个解决方案:
- 冻结整个游戏,当Tab无效时。 Li>
- 继续进行,当Tab无效时。 Li>
使用第一个解决方案我有下一个问题:由于 TweenMax 使用 requestAnimationFrame,它根据此解决方案正常工作(冻结动画),但是如何在选项卡处于非活动状态时冻结间隔和超时,然后恢复间隔和超时?
使用第二种解决方案,我可以将 TweenMax.lagSmoothing(0) 和 TweenMax.ticker.useRAF(false) 用于动画并且它可以工作,但无论如何间隔和/或超时都会出现问题。我期待动画出错,因为当Tab无效时间隔延迟到1000+ ms的变更(根据http://stackoverflow...w-is-not-active),但我禁用加速并将延迟设置为2000ms,它没有帮助。
请至少提供一种解决方案。最好两者都有一些变化。
【问题讨论】:
标签: javascript animation setinterval requestanimationframe gsap