想象一下,我有一個具有指定寬度和高度的視口。我克隆一個元素出來查看右側,並且在隨機y
位置代碼,它飛跨視這樣的:JQuery動畫 - 任何方式來「拖延」完整的觸發器?
...
.css({
'left': BASE_NODE_INIT_LEFT_PX,
'top' : rand(BASE_NODE_INIT_TOP_MIN_PX, BASE_NODE_INIT_TOP_MAX_PX) + 'px',
'width': _width + 'px',
'height': _height + 'px',
})
.animate({
left: BASE_NODE_ANIMATE_DISTANCE_X_PX
}
...
夠簡單的動畫。以下是有趣的部分:每一步我都想對這個元素應用一些物理。
事情是這樣的:
...
step:function(currentStep){
if($(this).data('animating-wind') !== true)
{
$(this).data('animating-wind',true);
var wind = (rand(1,2) == 2) ? '+=' + rand(1, 100) + 'px' : '-=' + rand(1, 100) + 'px';
$(this).animate({
'top': wind,
'text-indent': wind,
},{
duration: 500,
complete: function(){
$(this).data('animating-wind',false);
},
queue: false
});
}
}
...
基本上發生的事情是,而不是從右側直接穿過飛往左,它會減慢,加快和提高了隨機驟降,只是因爲我打算。
我面臨的問題是,有時「風」足夠強大,以便當步數達到總計算步數時該元素仍然可以在視口上看到,並且它會消失(發生這種情況在我complete:function(){ ...$(this).remove(); ...}
顯然發生了什麼是JQuery的認爲動畫完成,因爲它計算的步驟,並說:「我在動畫這個對象在過這麼多步驟的毫秒這麼多的像素 - 它的存在。」不過,風動畫是以外的動畫隊列所以這個動畫過程是非明智的。
我想開始動畫並保持動畫效果,直到元素從任何方向退出視口 - 一旦它不再可見,無論是從其最初的飛行路徑還是從風扇吹過屏幕,我都會檢測到它並觸發onComplete
回調。我能想到的唯一的事情就是把這個動畫放到一個函數中,並在complete:function(){}
中對自己進行遞歸調用,然後在step:function(){}
內部執行「在視口中可見」檢查並且如果true
調用stop(true,false)
。這看起來像是一個非常昂貴的檢查 - 在400-1200ms內運行100次以上可能會導致動畫波濤洶涌,所以我正在尋找更優雅的解決方案。
TL; DR:由於額外的動畫 如何防止動畫的東西,只要還沒有到達它的目的地尚未被設置就可以了?
更新:我申請@mu is too short's idea以及與此想出了:
/**
* Create a new clone of the master div for user interaction. Position it
* randomly off the canvas, and animate it across at a random speed.
*/
function spawn_target() {
spawn_timeout = setTimeout(function() {
var bonus = (rand(1, BONUS_ODDS) == BONUS_ODDS) ? ' ' + BONUS_CLASS : '';
var _img_src = (bonus.length > 0) ? BONUS_NODE_IMG_SRC : BASE_NODE_IMG_SRC;
var _width = $('#' + BASE_NODE_ID).width();
_width = Math.floor(rand(_width/3, _width));
var _height = _width;
var _framerate = 10 - Math.floor(_height/10);
var _clone = $('#' + BASE_NODE_ID).clone().addClass(CLONE_CLASS + bonus).attr('id', CLONE_ID).appendTo('#' + CANVAS_ID).css({
'left': BASE_NODE_INIT_LEFT_PX,
'top': rand(BASE_NODE_INIT_TOP_MIN_PX, BASE_NODE_INIT_TOP_MAX_PX) + 'px',
'width': _width + 'px',
'height': _height + 'px',
})
$(_clone).children('img').attr('src', _img_src);
/**
* Handle the actual flight across the viewport
* @param object _this The clone we are animating manually
* @return object pointer This contains the interval so we can clear it later
*/
function fly(_this) {
var animating_wind = false;
var pointer = {
timer_id: null
};
pointer.timer_id = setInterval(function() {
// Get rid of the node if it is no longer visible in the viewport
if (!$(_this).is(':onviewport')) {
clearInterval(pointer.timer_id);
$(_this).remove();
adj_game_data(GAME_DATA_LIVES_ID, -1);
check_lives();
spawn_target();
}
// Move node along with slight realism
var distance = rand(FLY_DISTANCE_MIN, FLY_DISTANCE_MAX);
$(_this).css('left', '-=' + distance + 'px');
// Only trigger the wind animation when it is idle
if (animating_wind !== true) {
animating_wind = true;
// Setup the wind physics
var _wind_power = rand(WIND_POWER_MIN, WIND_POWER_MAX);
var _wind_dir = (rand(1, 2) == 2) ? '+=' : '-=';
// Override wind direction to keep node inside viewport
if(($(_this).offset().top + $(_this).height() + _wind_power) > CANVAS_HEIGHT)
{
_wind_dir = '-=';
}
if(($(_this).offset().top - _wind_power) < CANVAS_TOP_BUFFER_PX)
{
_wind_dir = '+=';
}
var _wind = _wind_dir + _wind_power + 'px';
// Apply the wind physics and don't let the node break the top or bottom
// boundaries of the viewport
$(_this).animate({
'top': _wind
}, {
duration: WIND_ANIMATION_DURATION,
complete: function() {
animating_wind = false;
},
queue: false
});
}
}, _framerate);
return pointer;
}
$(_clone).data('interval', fly(_clone));
}, rand(SPAWN_TARGET_TIMEOUT_MIN, SPAWN_TARGET_TIMEOUT_MAX));
}
這是我到目前爲止有:http://jsfiddle.net/AlienWebguy/DmtQ7/embedded/result/
我喜歡這個主意雖然它看起來像jQuery應該有一些內置這正是我所希望的。現在,我不得不$(obj).stop()
clearInterval($(obj).data('interval').timer_id);
。 *劃痕頭......
您是否考慮過親自動手製作動畫?如果你仍然在頁面上,你可以做一步,併爲下一步調用'setTimeout',然後不斷重複,直到它停止。那麼你不必擔心試圖預先計算步數的'animate'。 –
你可以嘗試使用+ =而不是 - =,這樣它就會隨風而流。這意味着它會超過停止位置而不是下衝,但是如果沒有演示,我不知道這種效果會導致什麼結果。你能發佈整個動畫功能嗎? –
等不及要看演示! –