5 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
\r
7 return k * ( 2 - k );
\r
11 style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
\r
13 return Math.sqrt( 1 - ( --k * k ) );
\r
17 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
\r
20 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
\r
26 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
\r
27 return 7.5625 * k * k;
\r
28 } else if ( k < ( 2 / 2.75 ) ) {
\r
29 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
\r
30 } else if ( k < ( 2.5 / 2.75 ) ) {
\r
31 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
\r
33 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
\r
43 if ( k === 0 ) { return 0; }
\r
44 if ( k == 1 ) { return 1; }
\r
46 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
\r
52 // transform や transition animation は スタイルシートに書かない
\r
54 // 新規アニメーションが追加された場合、
\r
55 // tree が dirty なら AFTER_COMMIT を待つ
\r
56 // 1) xnode の既存アニメーションとの親子関係の調査
\r
57 // 親なら -> 既存アニメーションの GPU レイヤー解除
\r
58 // 子なら -> GPU レイヤーを設定しない
\r
60 // 3) アニメーション完了後も GPU レイヤーはしばらく解除しない スクロール等の連続アニメーション時に GPU 転送時間で画面ががたつくから
\r
63 var X_Node_ANIMATIONS = [],
\r
64 X_Node_Anime_reserved = false,
\r
65 X_Node_Anime_updateTimerID = 0,
\r
66 X_Node_Anime_needsDetection = false,
\r
67 X_Node_Anime_onTransition = false,
\r
69 X_Node_Anime_hasTransform = !!X_Node_CSS_VENDER_PREFIX[ 'transform' ],
\r
70 /* Opera mobile で translateZ(0) が有効だと XY が 0 0 になる */
\r
71 /* GPUレイヤーにいる間に要素のコンテンツを変更をすると transitionend が動かなくなるっぽい Mac safari と firefox */
\r
72 X_Node_Anime_translateZ = X_Node_CSS_VENDER_PREFIX[ 'perspective' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ? ' translateZ(0)' : '',
\r
73 /* Opera12(XP,8.1) 切った方がスムース, win Safari3 で、たまに動作が止まってしまう、、、 */
\r
74 X_Node_Anime_hasTransition = false && !!X_Node_CSS_VENDER_PREFIX[ 'transitionDelay' ] && !( X_UA[ 'iOS' ] < 6 ) && !X_UA[ 'Opera' ] && !X_UA[ 'Blink' ], // && !( X_UA[ 'Webkit' ] <= 528.16 ),
\r
75 X_Node_Anime_transitionProps = X_Node_Anime_hasTransform ? X_Node_CSS_VENDER_PREFIX[ 'transform' ] : 'left,top',
\r
76 // transitionEnd イベント中に要素の更新( X_Node_startUpdate() )ができるか?
\r
77 // iOS3+4 では可能、iOS6.1.5 で不可。TODO iOS5 及び他の環境で調査。ダメな場合、anime.html が正しく描画されない。
\r
78 X_Node_updateOnTransitionEnd = false;
\r
80 // gpu化だけ transformX , willChange
\r
86 * TODO : scale, ActiveX transform, zoom, fontSizeScale
\r
87 * TODO : rotate, ActiveX transform -> 位置補正のために size 情報が必要なので、commitUpdate 後に計算して適用
\r
92 * TODO scrollLeft, scrollTop
\r
95 * GPU サポートの効いたアニメーションの設定 X.Event.ANIME_START, X.Event.ANIME_END, X.Event.GPU_RELEASED
\r
97 * @alias Node.prototype.animate
\r
98 * @param {object} start { x : 0, y : 0, opacity : 1 }
\r
99 * @param {object} dest { x : 100, y : 100, opacity : 0 }
\r
100 * @param {number=} duartion アニメーション時間 ms
\r
101 * @param {string=} easing 'quadratic', 'circular', 'back', 'bounce', 'elastic'
\r
102 * @param {number=} wait GPU レイヤーの遅延解除 ms
\r
103 * @return {Node} メソッドチェーン
\r
105 function X_Node_animate( start, dest, duration, easing, wait ){
\r
106 var isNew = !this[ '_anime' ],
\r
107 obj = this[ '_anime' ];
\r
110 this[ '_anime' ] = obj = X_Node_Anime_getComputedPosition( this );
\r
116 obj.duration = 0 <= duration && X_Type_isFinite( duration ) ? duration : 500;
\r
117 obj.easing = ease[ easing ] || ease[ 'circular' ];
\r
118 // 現在 GPUレイヤーのtop になっているか?将来については phase で判定
\r
119 obj.gpuParent = obj.gpuParent || false;
\r
120 obj.phase = duration === 0 ? 9 : obj.phase === 9 ? 9 : 0; //
\r
121 obj.wait = X_Type_isFinite( wait ) ? wait : 1000;
\r
123 obj.startTime = X_Timer_now();
\r
124 obj.startX = ( start.x || start.x === 0 ) ? start.x : obj.x || NaN;
\r
125 obj.startY = ( start.y || start.y === 0 ) ? start.y : obj.y || NaN;
\r
126 obj.startA = 0 <= start.opacity && start.opacity <= 1 ? start.opacity : obj.a || 1;
\r
128 obj.destTime = obj.startTime + obj.duration;
\r
129 obj.destX = ( dest.x || dest.x === 0 ) ? dest.x : obj.destX || NaN;
\r
130 obj.destY = ( dest.y || dest.y === 0 ) ? dest.y : obj.destY || NaN;
\r
131 obj.destA = 0 <= dest.opacity && dest.opacity <= 1 ? dest.opacity : obj.destA || 1;
\r
133 X_Node_ANIMATIONS.indexOf( this ) === -1 &&
\r
134 ( X_Node_ANIMATIONS[ X_Node_ANIMATIONS.length ] = this );
\r
137 if( X_Node_Anime_onTransition ) return this;
\r
139 if( X_Node_Anime_hasTransition ){
\r
141 if( obj.gpuTimerID ){
\r
142 X_Timer_remove( obj.gpuTimerID );
\r
143 delete obj.gpuTimerID;
\r
146 X_Node_Anime_needsDetection = true;
\r
148 X_Node_Anime_reserveUpdate( true );
\r
150 if( !X_Node_Anime_reserved ){
\r
151 X_Node_Anime_reserved = true;
\r
152 if( X_Node_updateTimerID ){
\r
153 X_System[ 'listen' ]( X_EVENT_UPDATED, X_Node_Anime_updateAnimationsNoTransition );
\r
154 X_Node_Anime_updateTimerID && X_Timer_cancelFrame( X_Node_Anime_updateTimerID );
\r
155 X_Node_Anime_updateTimerID = 0;
\r
157 X_System[ 'unlisten' ]( X_EVENT_UPDATED, X_Node_Anime_updateAnimationsNoTransition );
\r
158 X_Node_Anime_updateTimerID = X_Timer_requestFrame( X_Node_Anime_updateAnimationsNoTransition );
\r
162 isNew && this[ 'dispatch' ]( { type : X_EVENT_ANIME_START, 'gpu' : false } );
\r
165 // console.log( 'animate() ' + this[ '_id' ] + ' y:' + obj.startY + ' > ' + obj.destY + ' d:' + obj.duration );
\r
172 * @alias Node.prototype.stop
\r
173 * @return {Node} メソッドチェーン
\r
175 function X_Node_stop(){
\r
176 var obj = this[ '_anime' ];
\r
178 if( !obj ) return this;
\r
180 if( X_Node_Anime_hasTransition ){
\r
182 X_Node_Anime_needsDetection = true;
\r
183 X_Node_Anime_reserveUpdate();
\r
185 X_Node_ANIMATIONS.splice( X_Node_ANIMATIONS.indexOf( this ), 1 );
\r
186 //obj.gpuTimerID && X_Timer_remove( obj.gpuTimerID );
\r
187 delete this[ '_anime' ];
\r
192 function X_Node_Anime_reserveUpdate( before ){
\r
193 if( !X_Node_Anime_reserved ){
\r
194 X_Node_Anime_reserved = true;
\r
196 if( X_Node_updateTimerID ){
\r
197 //console.log( before ? '> BEFORE_UPDATE' : '> UPDATED' );
\r
199 X_System[ 'listenOnce' ]( before ? X_EVENT_BEFORE_UPDATE : X_EVENT_UPDATED, X_Node_Anime_updateAnimations );
\r
201 //console.log( '> Timer' );
\r
202 // Opera12 requestAnimationFrame では transition が動かない、、、
\r
203 X_Node_Anime_updateTimerID =
\r
205 X_Timer_once( 0, X_Node_Anime_updateAnimations ) :
\r
206 X_Timer_requestFrame( X_Node_Anime_updateAnimations );
\r
209 // console.log( ' X_Node_Anime_reserved 済、予約なし' );
\r
213 function X_Node_Anime_updateAnimations( v, updateNow ){
\r
214 var i = X_Node_ANIMATIONS.length, c = false, ret, xnode;
\r
216 // console.log( v.type || v );
\r
218 //console.log( 'updateAnimations len:' + i + ' time:' + v + ' det:' + X_Node_Anime_needsDetection );
\r
220 if( X_Node_Anime_needsDetection ) X_Node_Anime_detectAnimationLayers();
\r
223 xnode = X_Node_ANIMATIONS[ --i ];
\r
224 //console.log( 'phase : ' + xnode[ '_id' ] + ' ' + xnode[ '_anime' ].phase + ' ' + xnode[ '_anime' ].duration );
\r
225 ret = X_Node_Anime_updateAnimation( xnode );
\r
226 if( ret === true ){
\r
227 X_Node_ANIMATIONS.splice( i, 1 );
\r
228 xnode[ '_anime' ].gpuTimerID && X_Timer_remove( xnode[ '_anime' ].gpuTimerID );
\r
229 delete xnode[ '_anime' ];
\r
231 if( ret !== false ){
\r
236 if( ( X_Node_Anime_updateTimerID || updateNow ) && X_Node_updateTimerID ) X_Node_startUpdate();
\r
238 X_Node_Anime_updateTimerID = 0;
\r
239 X_Node_Anime_reserved = false;
\r
241 X_Node_Anime_reserveUpdate();
\r
245 // TODO X_Timer_requestFrame 経由の BEFORE_UPDATE で更新を行う
\r
246 function X_Node_Anime_detectAnimationLayers(){
\r
247 var i = X_Node_ANIMATIONS.length,
\r
249 j, xnode, parent, _xnode, hasGPUChild, remove;
\r
252 xnode = X_Node_ANIMATIONS[ --i ];
\r
253 parent = hasGPUChild = false;
\r
255 _xnode = X_Node_ANIMATIONS[ --j ];
\r
257 if( xnode.parent === _xnode.parent ){
\r
260 if( _xnode[ 'contains' ]( xnode ) ){
\r
261 if( ( _xnode[ '_anime' ].phase === 3 && _xnode[ '_anime' ].gpuParent ) || _xnode[ '_anime' ].phase === 10 ){
\r
262 _xnode[ '_anime' ].phase = 15;
\r
264 if( xnode[ '_anime' ].gpuParent ){
\r
266 xnode[ '_anime' ].phase = xnode[ '_anime' ].phase === 2 ? 6 : 15;// GPU レイヤーの解除 > アニメーションは継続, すでに終了フェイズなら破棄
\r
268 if( [ 7, 8, 9, 13, 14 ].indexOf( xnode[ '_anime' ].phase ) !== -1 ){// GPU レイヤーの中止
\r
270 xnode[ '_anime' ].phase -= 8;
\r
274 if( xnode[ 'contains' ]( _xnode ) ){
\r
275 if( ( xnode[ '_anime' ].phase === 3 && xnode[ '_anime' ].gpuParent ) || xnode[ '_anime' ].phase === 10 ){
\r
276 xnode[ '_anime' ].phase = 15;
\r
278 if( _xnode[ '_anime' ].gpuParent ){
\r
279 hasGPUChild = true;
\r
280 _xnode[ '_anime' ].phase = _xnode[ '_anime' ].phase === 2 ? 6 : 15;// GPU レイヤーの解除 > アニメーションは継続, すでに終了フェイズなら破棄
\r
282 if( [ 7, 8, 9, 13, 14 ].indexOf( _xnode[ '_anime' ].phase ) !== -1 ){// GPU レイヤーの中止
\r
283 hasGPUChild = true;
\r
284 _xnode[ '_anime' ].phase -= 8;
\r
290 if( !parent && xnode[ '_anime' ].phase !== 15 ){
\r
291 if( xnode[ '_anime' ].phase === 0 ){
\r
293 xnode[ '_anime' ].phase = hasGPUChild ? 7 : 8;// 非GPU -> GPU 子に GPU アニメをもつなら、タイミングをずらす。
\r
295 if( [ 3, 4, 10, 100 ].indexOf( xnode[ '_anime' ].phase ) === -1 ){
\r
297 xnode[ '_anime' ].phase = hasGPUChild ? 13 : 14;// 非GPU -> GPU 子に GPU アニメをもつなら、タイミングをずらす。
\r
302 X_Node_Anime_needsDetection = false;
\r
305 function X_Node_Anime_updateAnimation( xnode ){
\r
306 var obj = xnode[ '_anime' ],
\r
314 case -1 :// 子の GPU レイヤー解除待ち
\r
318 case 0 : // 開始位置+アニメーションの設定
\r
320 X_ViewPort[ 'unlisten' ]( X_EVENT_AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );
\r
323 //willChange : X_Node_Anime_transitionProps + ',opacity,width,height',
\r
324 backfaceVisibility : 'hidden',
\r
325 transitionTimingFunction : obj.easing.style,
\r
326 transitionDelay : '0s' // 0.001 にすると transitionend のタイミングが狂う、、、
\r
329 //console.log( '開始位置 ' + phase );
\r
330 X_Node_Anime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, phase === 8 );
\r
332 xnode[ 'dispatch' ]( { type : X_EVENT_ANIME_START, 'gpu' : phase === 8 } );
\r
336 case 9 : // 終了位置の設定
\r
337 obj.gpuParent = phase === 9;
\r
338 if( obj.duration ){
\r
339 xnode[ 'listenOnce' ]( 'transitionend', X_Node_Anime_onTransitionEnd );
\r
342 transitionProperty : X_Node_Anime_transitionProps + ',opacity,width,height',
\r
343 transitionDuration : obj.duration + 'ms'
\r
346 //console.log( '修了位置 ' + phase );
\r
347 X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, obj.gpuParent );
\r
351 //console.log( 'duration = 0 の場合、アニメーションの解除' );
\r
352 // duration = 0 の場合、アニメーションの解除
\r
354 case 3 : // TransitionEnd -> アニメーションの解除
\r
355 obj.phase = obj.gpuParent ? 10 : 4;
\r
357 //console.log( '#### アニメーションの解除 ' + obj.phase );
\r
359 // このタイミングで animation 関連の css を削除したところ(X_Node_Anime_clearTransition)、iOS3、4 で再描画忘れが度々起きるように、、、
\r
360 if( !obj.gpuParent ) X_Node_Anime_clearTransition( xnode );
\r
364 // アニメーションは停止・GPU=false -> リストから削除
\r
365 obj.gpuParent = false;
\r
369 // アニメーションは停止・GPUレイヤーは解除していない(再アニメーションに備えて待機)
\r
370 if( !obj.gpuTimerID ){
\r
371 //console.log( '#### アニメーションは停止 ' + obj.wait );
\r
373 obj.gpuTimerID = X_Timer_once( obj.wait, xnode, X_Node_Anime_releaseGPULayer );
\r
375 X_Node_Anime_releaseGPULayer.call( xnode );
\r
386 // GPU レイヤーの変更> アニメーションは継続,但し残り時間が短ければ停止
\r
389 now = X_Timer_now();
\r
390 time = obj.duration - now + obj.startTime;
\r
392 X_Node_Anime_clearTransition( xnode );
\r
393 X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, phase === 14 );
\r
394 obj.phase = phase === 14 ? 10 : 4;
\r
395 xnode[ 'dispatch' ]( time, { type : X_EVENT_ANIME_END, 'gpu' : obj.gpuParent } );
\r
397 current = X_Node_Anime_getComputedPosition( xnode );
\r
398 obj.startX = current.x;
\r
399 obj.startY = current.y;
\r
400 obj.startA = current.a;
\r
401 obj.duration = time;
\r
402 obj.startTime = now;
\r
403 X_Node_Anime_updatePosition( xnode, current.x, current.y, current.a, phase === 14 );
\r
404 obj.phase = phase === 14 ? 9 : 1;
\r
409 // GPU有効で停止(待機)している xnode の解除
\r
410 //console.log( 'GPU有効で停止(待機)している xnode の解除' + xnode[ '_tag' ] + xnode[ 'getOrder' ]() );
\r
411 // console.log( 'GPU有効で停止(待機)している xnode のGPU解除' );
\r
412 X_Node_Anime_clearTransition( xnode );
\r
413 X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );
\r
414 //obj.gpuTimerID && X_Timer_remove( obj.gpuTimerID );
\r
415 //delete obj.gpuTimerID;
\r
416 X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, xnode, X_Node_Anime_gpuReleased );
\r
419 case 100 : // stop() : アニメーションを中断して削除
\r
420 //console.log( 'stop() gpu:' + obj.gpuParent );
\r
421 // console.log( 'アニメーションを中断して削除' );
\r
422 current = X_Node_Anime_getComputedPosition( xnode );
\r
424 X_Node_Anime_clearTransition( xnode );
\r
425 X_Node_Anime_updatePosition( xnode, current.x, current.y, current.a, obj.gpuParent );
\r
426 obj.phase = obj.gpuParent ? 10 : 4;
\r
432 function X_Node_Anime_getComputedPosition( that ){
\r
433 var raw = that[ '_rawObject' ],
\r
434 x = NaN, y = NaN, a = 1, style, matrix;
\r
437 if( X_Node_Anime_hasTransform ){
\r
438 if( style = X_Node_CSS_getComputedStyle( raw, null ) ){
\r
439 matrix = ( style[ X_Node_CSS_VENDER_PREFIX[ 'transform' ] ] || '' ).split( ')' )[ 0 ].split( ', ' );
\r
440 x = + ( matrix[ 12 ] || matrix[ 4 ] );
\r
441 y = + ( matrix[ 13 ] || matrix[ 5 ] );
\r
442 a = matrix[ X_Node_CSS_Support[ 'opacity' ] ];
\r
445 if( X_Node_CSS_getComputedStyle ){
\r
446 if( style = X_Node_CSS_getComputedStyle( raw, null ) ){
\r
447 x = parseFloat( style[ 'left' ] );
\r
448 y = parseFloat( style[ 'top' ] );
\r
449 a = parseFloat( style[ X_Node_CSS_Support[ 'opacity' ] ] );
\r
452 if( style = ( raw.currentStyle || raw.style ) ){
\r
453 x = parseFloat( style[ 'left' ] );
\r
454 y = parseFloat( style[ 'top' ] );
\r
455 a = that[ '_css' ] && 0 <= that[ '_css' ].opacity ? that[ '_css' ].opacity : 1;
\r
456 //parseFloat( ( style[ 'filter' ] || 'opacity=1' ).split( 'opacity=' )[ 1 ] );
\r
460 return { x : x, y : y, a : a };
\r
463 function X_Node_Anime_onTransitionEnd( e ){
\r
464 console.log( '[TransitionEnd] ' + ( this[ '_anime' ] && this[ '_anime' ].phase ) );
\r
466 if( !this[ '_anime' ] || this[ '_anime' ].phase !== 2 ){
\r
467 // ここで return してしまうと、view の更新イベント待ちの場合、アニメが止まる
\r
468 X_Node_Anime_reserved && !X_Node_Anime_updateTimerID && !X_Node_updateTimerID && X_Node_Anime_reserveUpdate( X_Node_Anime_reserved = false );
\r
469 return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION;
\r
472 this[ '_anime' ].phase = 3;
\r
474 X_Node_Anime_clearTransition( this ); // X_EVENT_ANIME_END より前で呼んでおく
\r
476 X_Node_Anime_onTransition = true;
\r
477 this[ 'dispatch' ]( { type : X_EVENT_ANIME_END, 'gpu' : this[ '_anime' ].gpuParent } );
\r
478 X_Node_Anime_onTransition = false;
\r
480 X_Node_Anime_needsDetection = true;
\r
481 // iOS は transitionend 内の 更新でアニメーション可能 iOS3, iOS4 で確認
\r
483 X_Node_Anime_updateAnimations( 0, X_Node_updateOnTransitionEnd );
\r
485 return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION;
\r
488 function X_Node_Anime_releaseGPULayer(){
\r
489 var obj = this[ '_anime' ], tmp;
\r
491 // console.log( '_anime無' );
\r
494 X_Node_Anime_clearTransition( this );
\r
495 X_Node_Anime_updatePosition( this, obj.destX, obj.destY, obj.destA, false );
\r
496 X_Node_ANIMATIONS.splice( X_Node_ANIMATIONS.indexOf( this ), 1 );
\r
497 delete obj.gpuTimerID;
\r
498 delete this[ '_anime' ];
\r
499 //console.log( 'GPUレイヤーの破棄を指示' );
\r
501 X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, X_Node_Anime_gpuReleased );
\r
504 function X_Node_Anime_gpuReleased(){
\r
505 //console.log( 'GPU レイヤーが解放されました' );
\r
506 this[ 'dispatch' ]( { type : X_EVENT_GPU_RELEASED, 'gpu' : true } );
\r
509 function X_Node_Anime_clearTransition( xnode ){
\r
511 // アニメーション指定のセット(または解除)(対象のみ)
\r
513 xnode[ 'unlisten' ]( 'transitionend', X_Node_Anime_onTransitionEnd );
\r
517 backfaceVisibility : '',
\r
518 transitionTimingFunction : '',
\r
519 transitionDelay : '',
\r
520 transitionDuration : ''
\r
524 function X_Node_Anime_updatePosition( xnode, x, y, opacity, useGPU ){
\r
525 //console.log( 'updatePosition x:' + x + ' gpu:' + !!useGPU );
\r
526 if( X_Node_Anime_hasTransform ){
\r
528 transform : 'translate(' + ( x | 0 ) + 'px,' + ( y | 0 ) + 'px)' + ( useGPU ? X_Node_Anime_translateZ : '' ),
\r
532 x === x && xnode[ 'css' ]( 'left', ( x | 0 ) + 'px' );
\r
533 y === y && xnode[ 'css' ]( 'top', ( y | 0 ) + 'px' );
\r
534 opacity === opacity && xnode[ 'css' ]( 'opacity', opacity );
\r
537 if( X_Node_Anime_translateZ ){
\r
539 if( xnode[ '_flags' ] & X_NodeFlags_GPU_RELEASE_RESERVED ){
\r
540 xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
\r
541 xnode[ '_flags' ] |= X_NodeFlags_GPU_NOW;
\r
543 if( !( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ) ){
\r
544 xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
\r
545 xnode[ '_flags' ] |= X_NodeFlags_GPU_RESERVED;
\r
548 if( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ){
\r
549 xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
\r
550 xnode[ '_flags' ] |= X_NodeFlags_GPU_RELEASE_RESERVED;
\r
552 if( xnode[ '_flags' ] & X_NodeFlags_GPU_RESERVED ){
\r
553 xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
\r
559 function X_Node_Anime_updateAnimationsNoTransition( e ){
\r
560 var i = X_Node_ANIMATIONS.length,
\r
561 now = X_Timer_now(),
\r
563 newX, newY, newA, easing,
\r
567 xnode = X_Node_ANIMATIONS[ --i ];
\r
568 obj = xnode[ '_anime' ];
\r
570 if( obj.destTime <= now ){
\r
571 X_Node_Anime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );
\r
573 delete xnode[ '_anime' ];
\r
574 X_Node_ANIMATIONS.splice( i, 1 );
\r
575 //console.log( obj.destA );
\r
576 // filter な 親が解除されないと子要素への filter が反映されない
\r
577 xnode[ 'asyncDispatch' ]( { type : X_EVENT_ANIME_END, 'gpu' : false } );
\r
579 easing = obj.easing.fn( ( now - obj.startTime ) / obj.duration );
\r
580 newX = ( obj.destX - obj.startX ) * easing + obj.startX;
\r
581 newY = ( obj.destY - obj.startY ) * easing + obj.startY;
\r
582 newA = ( obj.destA - obj.startA ) * easing + obj.startA;
\r
583 X_Node_Anime_updatePosition( xnode, newX, newY, newA, false );
\r
591 //c && console.log( 'anime... ' + X_Node_updateTimerID );
\r
593 if( X_Node_Anime_reserved = c ){
\r
594 if( X_Node_updateTimerID ){
\r
595 // scrollbox では X_System X_EVENT_UPDATED は不可。。。
\r
596 !e || e.type !== X_EVENT_UPDATED ?
\r
597 X_System[ 'listen' ]( X_EVENT_UPDATED, X_Node_Anime_updateAnimationsNoTransition ) :
\r
598 X_Node_Anime_updateTimerID && X_Timer_cancelFrame( X_Node_Anime_updateTimerID );
\r
599 X_Node_Anime_updateTimerID = 0;
\r
601 X_System[ 'unlisten' ]( X_EVENT_UPDATED, X_Node_Anime_updateAnimationsNoTransition );
\r
602 X_Node_Anime_updateTimerID = X_Timer_requestFrame( X_Node_Anime_updateAnimationsNoTransition );
\r
605 X_System[ 'unlisten' ]( X_EVENT_UPDATED, X_Node_Anime_updateAnimationsNoTransition );
\r
606 X_Node_Anime_updateTimerID = 0;
\r