OSDN Git Service

Version 0.6.200, fix X.Node.Anime.
authoritozyun <itozyun@user.sourceforge.jp>
Wed, 9 Dec 2015 13:55:51 +0000 (22:55 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Wed, 9 Dec 2015 13:55:51 +0000 (22:55 +0900)
0.6.x/img/loading.gif
0.6.x/js/02_dom/10_XNodeAnime.js
0.6.x/js/02_dom/20_XNode.js
0.6.x/js/20_ui/15_ScrollBox.js

index 2f53369..4c87a7a 100644 (file)
Binary files a/0.6.x/img/loading.gif and b/0.6.x/img/loading.gif differ
index 6ba1bc2..cbf6a33 100644 (file)
@@ -41,9 +41,7 @@ var X_NODE_ANIME_RESET = 1,
  */\r
 function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){\r
        var list  = X_NodeAnime_QUEUE,\r
-               obj   = this[ '_anime' ],\r
-               isNew = !obj,\r
-               now, stop;\r
+               obj   = this[ '_anime' ];\r
        \r
        if( !( this[ '_flags' ] & X_NodeFlags_IN_TREE ) ){\r
                alert( '@animate 要素はツリーに追加されていません!' );\r
@@ -51,10 +49,9 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
                return this;\r
        };\r
        \r
-       if( isNew ){\r
+       if( !obj ){\r
                this[ '_anime' ] = obj = {\r
                                x : 0, y : 0, a : 1,\r
-                               destX : 0, destY : 0, destA : 1,\r
                                duration : 0\r
                                //phase, lazyRelease, easing, follower, releaseNow\r
                        };\r
@@ -62,30 +59,27 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
        \r
        if( 0 <= duration && X_Type_isFinite( duration ) ){\r
                obj.duration  = duration;\r
-               stop = !duration;\r
        };\r
 \r
-       if( obj.phase !== 7 ){\r
-               // アニメーション中は easing の変更ができない\r
-               obj.easing = X_Type_isFunction( easing ) ? easing : X_NodeAnime_ease[ easing ] || X_NodeAnime_ease[ 'circular' ];\r
-       };\r
+       obj.easing = X_Type_isFunction( easing ) ? easing : X_NodeAnime_ease[ easing ] || X_NodeAnime_ease[ 'circular' ];\r
+               \r
 // form :\r
        obj.startX = obj.x = X_NodeAnime_getFinite( start[ 'x' ],       obj.x );\r
        obj.startY = obj.y = X_NodeAnime_getFinite( start[ 'y' ],       obj.y );\r
        obj.startA = obj.a = X_NodeAnime_getFinite( start[ 'opacity' ], obj.a );\r
 \r
  // to :\r
-       obj.destX     = X_NodeAnime_getFinite( dest[ 'x' ],       obj.destX );\r
-       obj.destY     = X_NodeAnime_getFinite( dest[ 'y' ],       obj.destY );\r
-       obj.destA     = X_NodeAnime_getFinite( dest[ 'opacity' ], obj.destA );\r
+       obj.destX  = X_NodeAnime_getFinite( dest[ 'x' ],       obj.x );\r
+       obj.destY  = X_NodeAnime_getFinite( dest[ 'y' ],       obj.y );\r
+       obj.destA  = X_NodeAnime_getFinite( dest[ 'opacity' ], obj.a );\r
 \r
        obj.lazyRelease = 0 <= lazyRelease && X_Type_isFinite( lazyRelease ) ? lazyRelease : 0;\r
+       obj.inited = false;\r
 \r
-       if( stop && 6 <= obj.phase ){\r
+       if( !obj.duration && 6 <= obj.phase ){\r
                this[ 'stop' ](); // 現在値で停止\r
-       } else\r
-       if( !stop || obj.lazyRelease ){\r
-               if( isNew || !obj.phase ){\r
+       } else {\r
+               if( !obj.phase ){\r
                        list[ list.length ] = this;\r
                        obj.phase = 1;\r
                        obj.uid   = ++X_NodeAnime_uid;\r
@@ -97,14 +91,14 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
                        obj.uid   = ++X_NodeAnime_uid;\r
                        X_NodeAnime_needsDetection = true;\r
                } else\r
-               if( !stop ){\r
+               if( obj.duration ){\r
                        // リストの先頭にいるため検査不要でアニメーション開始可能 4, 5, 6, 7\r
                        obj.phase = 6;\r
                } else\r
-               // obj.lazyRelease はあり\r
+               // GPU 転送予約、または transform や opacity の値のみ設定\r
                if( obj.phase !== 5 ){ // GPU解除待ち ではない -> 4. 6, 7\r
-                       obj.phase      = 4; // 強制停止(GPU転送予約)\r
-                       obj.releaseNow = false; // TODO folower がるため GPU 転送できないケースあり\r
+                       obj.phase      = 4; // 強制停止(GPU転送予約)または値のみ更新\r
+                       obj.releaseNow = false; // TODO folower がるため GPU 転送できないケースあり\r
                        X_NodeAnime_needsDetection = true;\r
                };\r
                \r
@@ -120,11 +114,6 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
                                X_NodeAnime_updateTimerID = X_Timer_requestFrame( X_NodeAnime_updateAnimations );\r
                        };\r
                };      \r
-       } else {\r
-               if( obj.phase ){\r
-                       this[ 'stop' ](); // リストから外す\r
-               };\r
-               console.log( 'リストに加えない!' );\r
        };\r
 \r
        return this;\r
@@ -167,6 +156,8 @@ function X_Node_stop( option ){
                                obj.startA = obj.destA = obj.a = 1;\r
                        }; // TODO 終了値で停止も,,,\r
                        \r
+                       // obj.canceled = true;\r
+                       \r
                        if( rm ) break; // 1,2,3,6 の場合ここまで\r
                \r
                        obj.destX = obj.x;\r
@@ -188,12 +179,34 @@ function X_Node_stop( option ){
 \r
        return this;\r
 };\r
+/*\r
+ * remove(append swap 等でない部的に呼ばれている場合も), kill 時に\r
+ */\r
+function X_NodeAnime_stopNow( xnode ){\r
+       var obj   = xnode[ '_anime' ],\r
+               flags = xnode[ '_flags' ],\r
+               list  = X_NodeAnime_QUEUE,\r
+               skipUpdate;\r
+       \r
+       // if( !obj || !obj.phase ) return; 呼び出し側で検証済\r
+\r
+       X_NodeAnime_needsDetection = true;\r
+       list.splice( list.indexOf( xnode ), 1 );\r
+       obj.phase = 0;\r
+\r
+       // この部分 startUpdate へ?\r
+       if( flags & ~X_Node_BitMask_RESET_GPU ){\r
+               skipUpdate = flags & X_NodeFlags_GPU_RESERVED;\r
+               ( flags & X_NodeFlags_GPU_RELEASE_RESERVED ) || X_NodeAnime_updatePosition( xnode, obj.x, obj.y, obj.a, false );\r
+               skipUpdate || ( xnode[ '_rawObject' ].style.cssText = X_Node_CSS_objToCssText( xnode ) );\r
+               xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
+       };\r
+};\r
 \r
 /*\r
  * 1. 新規アニメーションが現在アニメーション中の要素の親か子であればアニメーションを待機\r
- * 2. \r
  */\r
-function X_NodeAnime_detectWaitAnimation( xnode, duration, isText ){\r
+function X_NodeAnime_detectWaitAnimation( xnode, duration, isTest ){\r
        var list = X_NodeAnime_QUEUE,\r
                i    = 0, _xnode;\r
        \r
@@ -203,7 +216,7 @@ function X_NodeAnime_detectWaitAnimation( xnode, duration, isText ){
                // アニメーションの優先度はリストにいる順\r
                // まず先行する後続待機要素の中に、親子関係のものがいないか?探す\r
                if( _xnode[ '_anime' ].phase <= 3 ){\r
-                       if( xnode[ 'contains' ]( _xnode ) || _xnode[ 'contains' ]( xnode ) ){\r
+                       if( xnode[ 'contains' ]( _xnode ) || _xnode[ 'contains' ]( xnode ) ){ // 祖先か?見た方が早そう\r
                                // -> いる、このような要素が複数いる場合、誰に後続すればいいか?判然としないため、準待機フラグを立てる\r
                                return 2;\r
                        };\r
@@ -218,7 +231,7 @@ function X_NodeAnime_detectWaitAnimation( xnode, duration, isText ){
 \r
                if( 6 <= _xnode[ '_anime' ].phase ){\r
                        if( xnode[ 'contains' ]( _xnode ) || _xnode[ 'contains' ]( xnode ) ){\r
-                               return isText ? 3 : _xnode;\r
+                               return isTest ? 3 : _xnode;\r
                        };\r
                };\r
        };\r
@@ -228,17 +241,16 @@ function X_NodeAnime_detectWaitAnimation( xnode, duration, isText ){
 \r
 function X_NodeAnime_updateAnimations( e ){\r
        var list = X_NodeAnime_QUEUE,\r
-               i    = list.length,\r
                now  = X_Timer_now(),\r
-               c = false,\r
+               c    = false,\r
                i, xnode, obj, _xnode,\r
-               rm, easing, follower, lazy;\r
+               rm, easing, lazy;\r
        \r
        if( X_NodeAnime_needsDetection ){\r
                X_NodeAnime_needsDetection = false;\r
                \r
                //\r
-               list.sort( X_NodeAnime_sortAnimationNode );             \r
+               list.sort( X_NodeAnime_sortAnimationNode );\r
                \r
                for( i = 0; xnode = list[ i ]; ++i ){\r
                        obj = xnode[ '_anime' ];\r
@@ -254,7 +266,7 @@ function X_NodeAnime_updateAnimations( e ){
                };\r
        };\r
        \r
-       for( ; i; ){\r
+       for( i = list.length; i; ){\r
                rm    = false;\r
                xnode = list[ --i ];\r
                obj   = xnode[ '_anime' ];\r
@@ -271,11 +283,17 @@ function X_NodeAnime_updateAnimations( e ){
                                        break;\r
                                };\r
                                // アニメーション終了\r
+                               xnode[ 'asyncDispatch' ]( X_EVENT_ANIME_END );\r
+                               \r
                        case 4 : // 強制停止(GPU転送予約)\r
                                lazy = !obj.follower && !obj.releaseNow && obj.lazyRelease;\r
                                X_NodeAnime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, !!lazy );\r
 \r
-                               xnode[ 'asyncDispatch' ]( X_EVENT_ANIME_END );\r
+                               //if( obj.canceled ){\r
+                               //      xnode[ 'asyncDispatch' ]( X_EVENT_CANCELED );\r
+                               //} else {\r
+                                       \r
+                               //};\r
                                \r
                                if( lazy ){\r
                                        console.log( 'アニメーション終了(' + obj.phase + ') -> GPU 解除待機 ' + lazy );\r
@@ -292,10 +310,11 @@ function X_NodeAnime_updateAnimations( e ){
                                obj.startTime = now;\r
                                obj.destTime  = now + obj.duration;\r
                                obj.phase     = 7; // アニメーション中\r
-                               obj.progress  = 0;\r
-                               X_NodeAnime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, true );\r
+                               obj.progress  = 0;                                      \r
                                xnode[ 'asyncDispatch' ]( X_EVENT_ANIME_START );\r
                                c = true;\r
+                               //obj.canceled  = false;\r
+                               ( obj.inited && !X_NodeAnime_translateZ ) || X_NodeAnime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, true );\r
                                break;\r
                        \r
                        case 5 : // GPU解除待ち\r
@@ -305,7 +324,13 @@ function X_NodeAnime_updateAnimations( e ){
                                } else {\r
                                        c = true;\r
                                };\r
-                               break;  \r
+                               break;\r
+                       \r
+                       default : // 2 or 3\r
+                               // 待機状態でも親要素が GPU 化していなければ、開始値をセットすることは可能\r
+                               obj.inited || X_NodeAnime_updatePosition( xnode, obj.startX, obj.startY, obj.startA, false );\r
+                               obj.inited = false;\r
+                               break;\r
                };\r
                \r
                obj.releaseNow = false;\r
index e40f832..ab4e26b 100644 (file)
@@ -781,12 +781,13 @@ function X_Node_remove(){
        
        if( !parent ) return this;
 
-       // TODO anime
        // stop() ->
        if( this[ '_anime' ] && this[ '_anime' ].phase ){
                console.log( 'Animation 中の REMOVE' );
-               this[ 'stop' ]();
+               X_NodeAnime_stopNow( this );
        };
+       // 子孫にアニメーション中の要素が要る
+       // 先祖に GPU 化した要素が要る
 
        delete this.parent;
        parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( this ), 1 );
@@ -798,7 +799,7 @@ function X_Node_remove(){
                if( X_UA_DOM.IE4 ){
                        if( elm = this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ){
                                X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;
-                               X_Node_reserveUpdate();                 
+                               X_Node_reserveUpdate();
                        } else
                        if( !this[ '_tag' ] && ( ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ){
                                parent[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN;
@@ -849,8 +850,6 @@ function X_Node_onKill( that ){
        
        parent && parent[ '_xnodes' ] && parent[ '_xnodes' ].splice( parent[ '_xnodes' ].indexOf( that ), 1 );
 
-       elm = that[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( that );
-
        if( xnodes && ( i = xnodes.length ) ){
                delete that[ '_xnodes' ];
                for( ; i; ){
@@ -861,12 +860,13 @@ function X_Node_onKill( that ){
 
        X_Node_CHASHE[ that[ '_uid' ] ] = null; // array に対して delete X_Node_CHASHE[ uid ] はまずい!
 
-// TODO anime
        if( that[ '_anime' ] && that[ '_anime' ].phase ){
                console.log( 'Animation 中の KILL' );
-               that[ 'stop' ]();
+               X_NodeAnime_stopNow( that );
        };
 
+       elm = that[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( that );
+
 // remove _xnodes
        if( X_UA_DOM.IE4 ){
                if( elm ){
@@ -895,26 +895,15 @@ function X_Node_onKill( that ){
  * @example node.contains( testNode );
  */
 function X_Node_contains( v ){
-       var elm, type, xnodes, i;
+       var xnodes;
        
        if( !v || !this[ '_tag' ] || this === v ) return false;
-       
-       // contains ie4+
-       /*
-       if( ( elm = this[ '_rawObject' ] || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ) ) && document.contains && ( type = X_Node_getType( v ) ) && ( type === X_NodeType_RAW_HTML || type === X_NodeType_RAW_TEXT ) ){
-               return elm.contains( v );
-       }; */
 
-       //if( document.compareDocumentPosition ){
-       //      
-       //};
-       
        xnodes = this[ '_xnodes' ];
        if( !xnodes || !xnodes.length ) return false;
-       if( this === v[ 'parent' ] ) return true; // fast
-       if( xnodes.indexOf( v ) !== -1 ) return true; // fast
-       for( i = xnodes.length; i; ){
-               if( xnodes[ --i ][ 'contains' ]( v ) ) return true;
+
+       while( v = v[ 'parent' ] ){
+               if( this === v ) return true;
        };
        return false;
 };
@@ -1237,6 +1226,17 @@ function X_Node_call( name /*, opt_args... */ ){
                        return this.parent ? X_Node_CSS_getCharSize( this ) : 0;
                case 'inGPU' :
                        return !!( this[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) );
+               case 'isGPUChild' :
+                       if( this[ '_flags' ] & X_NodeFlags_IN_TREE ){
+                               parent = this;
+                               while( parent = parent.parent ){
+                                       if( parent[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) ) return true;
+                               };
+                       };
+                       return false;
+               case 'containGPU' :
+                       
+                       return false;
                case 'canAnimateNow' :
                        return ( this[ '_flags' ] & X_NodeFlags_IN_TREE ) && X_NodeAnime_detectWaitAnimation( this, true, true ) === 6;
                case 'animeState' :
@@ -1460,12 +1460,12 @@ var X_Node__commitUpdate =
                                console.log( 'GPU 解放 ' );
                                //X_Node_updateReservedByReleaseGPU = true;
                                that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
-                               //return elm;// TODO もしかしたらこのタイミングで更新できるかも
+                               //return elm;// このタイミングで更新できるっぽい
                        };
 
                        // 3. GPU予約 -> GPU
                        if( that[ '_flags' ] & X_NodeFlags_GPU_RESERVED ){
-                               // TODO size 取得のための update の場合、GPU化を待つ
+                               // TODO size 取得のための update の場合、GPU化をスキップ
                                that[ '_flags' ] &= X_Node_BitMask_RESET_GPU;
                                that[ '_flags' ] |= X_NodeFlags_GPU_NOW;
                        };
@@ -1518,7 +1518,7 @@ var X_Node__commitUpdate =
                                if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){
                                        elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() );
                                        
-                                       // math http://www.w3.org/1998/Math/MathML
+                                       // TODO math http://www.w3.org/1998/Math/MathML
                                } else {
                                        elm = document.createElement( that[ '_tag' ] );
                                };
index 9a93207..1770704 100644 (file)
@@ -597,11 +597,7 @@ function X_UI_ScrollBox_resetPosition( that, time ){
 };\r
 \r
 function X_UI_ScrollBox_onAnimeEnd( e ){\r
-       if( e.target !== this.xnodeSlider ){\r
-               console.log( '- not much -' );\r
-               console.dir(e);\r
-       };\r
-       if( e.target === this.xnodeSlider && this.isInTransition && !X_UI_ScrollBox_resetPosition( this, this.bounceTime ) ){\r
+       if( this.isInTransition && !X_UI_ScrollBox_resetPosition( this, this.bounceTime ) ){\r
                this.isInTransition = false;\r
                //console.log( '-2-' );\r
                this[ 'dispatch' ]( XUI_Event.SCROLL_END );\r