私は、定義された幅と高さを持つビューポートを持っているとします。私は、右側のビューの外の要素のクローンを作成し、このようなコードを使用してランダム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
コールバックをトリガーします。私が考えることができるのは、このアニメーションを関数の中に入れて、自身に再帰呼び出しを行い、次にstep:function(){}
の中に「ビューポートで表示」チェックを行い、stop(true,false)
の場合はtrue
と呼び出します。これはちょうど非常に高価なチェックのように思えます - 400-1200msで100回以上計算するとアニメーションが不安定になるので、より洗練されたソリューションを探しています。
TL; DR: は、どのように私はそれが原因追加のアニメーションは、それに設定されることにまだその先に到達していない限り、何かをアニメーション保つのですか?
UPDATE:私は@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));
}
は、ここで私がこれまで持っているものです:jQueryの何かを持っている必要がありますようにそれはそうかかわらhttp://jsfiddle.net/AlienWebguy/DmtQ7/embedded/result/
私はこのアイデアを気に入っ内蔵それは私が望んでいたものです。今、$(obj).stop()
の代わりに私はclearInterval($(obj).data('interval').timer_id);
する必要があります。 *傷ヘッド...
アニメーションを手作業で行うことを検討しましたか?もしあなたがまだページ上にあるならば、あなたは1つのステップを実行し、次のステップのために 'setTimeout'を呼び出すことができます。そうすれば、ステップ数を事前に計算しようとするアニメーションを心配する必要はありません。 –
あなたは+ =の代わりに+ =を使うことができますので、 "風と一緒に"流れます。これは、アンダーシュートではなく停止位置をオーバーシュートすることを意味しますが、デモがなければ、この効果がどのような結果になるかわかりません。アニメーション機能全体を投稿できますか? –
デモを見るのが待ちきれない! –