OSDN Git Service

Version 0.6.202, update xnode.animate().
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 10_XNodeAnime.js
index 5404814..4613689 100644 (file)
@@ -6,6 +6,9 @@ var X_NodeAnime_QUEUE           = [],
        X_NodeAnime_needsDetection  = false,\r
        \r
        X_NodeAnime_hasTransform    = !!X_Node_CSS_VENDER_PREFIX[ 'transform' ],\r
+       \r
+       X_NodeAnime_hasDXTransform  = 5.5 <= X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 && X_UA[ 'ActiveX' ],\r
+       \r
        /* Opera mobile で  translateZ(0) が有効だと XY が 0 0 になる */\r
        /* GPUレイヤーにいる間に要素のコンテンツを変更をすると transitionend が動かなくなるっぽい Mac safari と firefox */\r
        X_NodeAnime_translateZ      = X_Node_CSS_VENDER_PREFIX[ 'perspective' ] && !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] ? ' translateZ(0)' : '',\r
@@ -26,22 +29,72 @@ var X_NodeAnime_QUEUE           = [],
  */\r
 \r
 var X_NODE_ANIME_RESET = 1,\r
-       X_NODE_ANIME_STAY_GPU = 2;\r
+       X_NODE_ANIME_STAY_GPU = 2,\r
+       \r
+       X_NodeAnime_DEFAULT = {\r
+               x        : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               y        : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               toX      : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               toY      : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               fromX    : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               fromY    : X_NodeAnime_hasTransform ? 0 : NaN,\r
+               rotate   : NaN, fromRotate   : NaN, toRotate   : NaN,\r
+               skewX    : NaN, fromSkewX    : NaN, toSkewX    : NaN,\r
+               skewY    : NaN, fromSkewY    : NaN, toSkewY    : NaN,\r
+               scaleX   : 1,   fromScaleX   : 1,   toScaleX   : 1,\r
+               scaleY   : 1,   fromScaleY   : 1,   toScaleY   : 1,\r
+               alpha    : NaN,\r
+               scrollX  : NaN, fromScrollX  : NaN, toScrollX  : NaN,\r
+               scrollY  : NaN, fromScrollY  : NaN, toScrollY  : NaN,\r
+               doScroll : false//,\r
+               //duration : 0\r
+               //phase, lazyRelease, easing, follower, releaseNow, inited, progress doScroll, fallbackKind\r
+               // fromTime, toTime\r
+       };\r
 \r
 /**\r
- * GPU サポートの効いたアニメーションの設定 X.Event.ANIME_START, X.Event.ANIME_END, X.Event.GPU_RELEASED\r
+ * GPU サポートの効いたアニメーションの設定\r
+ * <a href="https://outcloud.blogspot.jp/2015/12/pettanR-Node-Anime.html">ぺったんRフレームワークのアニメーションメソッド</a>\r
  * @alias Node.prototype.animate\r
- * @param {object} start { x : 0, y : 0, opacity : 1 }\r
- * @param {object} dest  { x : 100, y : 100, opacity : 0 }\r
- * @param {number=} duartion アニメーション時間 ms\r
- * @param {string=} easing 'quadratic', 'circular', 'back', 'bounce', 'elastic'\r
- * @param {number=} wait GPU レイヤーの遅延解除 ms\r
- * @param {number=} option フォールバックについて\r
+ * @param {object} obj\r
  * @return {Node} メソッドチェーン\r
+ * @example\r
+ * xnode.animate{\r
+ *      from       : {\r
+ *         x       : num,\r
+ *      y       : num,\r
+ *      opacity : 0.0, //~1.0\r
+ *      rotate  : deg,\r
+ *      skew    : deg,\r
+ *      skewX   : deg,\r
+ *      skewY   : deg,\r
+ *      scale   : num,\r
+ *      scaleX  : num,\r
+ *      scaleY  : num,\r
+ *      scrollX : num,\r
+ *      scrollY : num\r
+ *    },\r
+ *   to          : {}, // from と同じ\r
+ *   duration    : ms,\r
+ *   lazyRelease : ms,\r
+ *   easing      : 'quadratic', // function, 'circular', 'back', 'bounce', 'elastic'\r
+ *   fallback    : bitFlag // 16:DXTransform, 8:css-p, 4:zoom(s) > 2:fontSize(s) > 1:width&height(vh,s)\r
+ *   ** tree にいなくてもアニメーションを行いイベントを発生\r
+ *   ** SVG transfrom\r
+ *   fallbackWidth, fallbackHeight, transformOrigin( 0.5, 0.5 )\r
+ * }\r
  */\r
-function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){\r
-       var list  = X_NodeAnime_QUEUE,\r
-               obj   = this[ '_anime' ];\r
+function X_Node_animate( obj ){\r
+       var list        = X_NodeAnime_QUEUE,\r
+               from        = obj[ 'from' ] || {},\r
+               dest        = obj[ 'to' ]   || {},\r
+               duration    = obj[ 'duration' ],\r
+               lazyRelease = obj[ 'lazyRelease' ],\r
+               easing      = obj[ 'easing' ],\r
+               fallback    = obj[ 'fallback' ],\r
+               a, sameRate;\r
+               \r
+       obj = this[ '_anime' ];\r
        \r
        if( !( this[ '_flags' ] & X_NodeFlags_IN_TREE ) ){\r
                alert( '@animate 要素はツリーに追加されていません!' );\r
@@ -50,13 +103,9 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
        };\r
        \r
        if( !obj ){\r
-               this[ '_anime' ] = obj = {\r
-                               x : X_NodeAnime_hasTransform ? 0 : NaN,\r
-                               y : X_NodeAnime_hasTransform ? 0 : NaN,\r
-                               a : 1,\r
-                               duration : 0\r
-                               //phase, lazyRelease, easing, follower, releaseNow\r
-                       };\r
+               this[ '_anime' ] = obj = X_Object_copy( X_NodeAnime_DEFAULT );\r
+               a = this[ '_css' ] && parseFloat( this[ '_css' ].opacity );\r
+               if( 0 <= a ) obj.alpha = a;\r
        };\r
        \r
        if( 0 <= duration && X_Type_isFinite( duration ) ){\r
@@ -66,17 +115,72 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
        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
+       obj.fromX       = obj.x       = X_NodeAnime_getFinite( from[ 'x' ],       obj.x );\r
+       obj.fromY       = obj.y       = X_NodeAnime_getFinite( from[ 'y' ],       obj.y );\r
+       obj.fromRotate  = obj.rotate  = X_NodeAnime_getFinite( from[ 'rotate' ],  obj.rotate );\r
+       obj.fromSkewX   = obj.skewX   = X_NodeAnime_getFinite( from[ 'skewX' ],   from[ 'skew' ],  obj.skewX );\r
+       obj.fromSkewY   = obj.skewY   = X_NodeAnime_getFinite( from[ 'skewY' ],   from[ 'skew' ],  obj.skewY );\r
+       obj.fromScaleX  = obj.scaleX  = X_NodeAnime_getFinite( from[ 'scaleX' ],  from[ 'scale' ], obj.scaleX );\r
+       obj.fromScaleY  = obj.scaleY  = X_NodeAnime_getFinite( from[ 'scaleY' ],  from[ 'scale' ], obj.scaleY );\r
+       obj.fromAlpha   = obj.alpha   = X_NodeAnime_getFinite( from[ 'opacity' ], obj.alpha );\r
+       obj.fromScrollX = obj.scrollX = X_NodeAnime_getFinite( from[ 'scrollX' ], obj.scrollX );\r
+       obj.fromScrollY = obj.scrollY = X_NodeAnime_getFinite( from[ 'scrollY' ], obj.scrollY );\r
  // to :\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
+       obj.toX                       = X_NodeAnime_getFinite( dest[ 'x' ],       obj.x );\r
+       obj.toY                       = X_NodeAnime_getFinite( dest[ 'y' ],       obj.y );\r
+       obj.toRotate                  = X_NodeAnime_getFinite( dest[ 'rotate' ],  obj.rotate );\r
+       obj.toSkewX                   = X_NodeAnime_getFinite( dest[ 'skewX' ],   dest[ 'skew'  ], obj.skewX );\r
+       obj.toSkewY                   = X_NodeAnime_getFinite( dest[ 'skewY' ],   dest[ 'skew'  ], obj.skewY );\r
+       obj.toScaleX                  = X_NodeAnime_getFinite( dest[ 'scaleX' ],  dest[ 'scale' ], obj.scaleX );\r
+       obj.toScaleY                  = X_NodeAnime_getFinite( dest[ 'scaleY' ],  dest[ 'scale' ], obj.scaleY );\r
+       obj.toAlpha                   = X_NodeAnime_getFinite( dest[ 'opacity' ], obj.alpha );\r
+       obj.toScrollX                 = X_NodeAnime_getFinite( dest[ 'scrollX' ], obj.scrollX );\r
+       obj.toScrollY                 = X_NodeAnime_getFinite( dest[ 'scrollY' ], obj.scrollY );\r
+\r
+       if( obj.toRotate && obj.rotate !== obj.rotate ) obj.rotate = 0;\r
+       if( obj.toSkewX  && obj.skewX  !== obj.skewX  ) obj.skewX  = 0;\r
+       if( obj.toSkewY  && obj.skewY  !== obj.skewY  ) obj.skewY  = 0;\r
 \r
        obj.lazyRelease = 0 <= lazyRelease && X_Type_isFinite( lazyRelease ) ? lazyRelease : 0;\r
-       obj.inited = false;\r
+       obj.inited    = false;\r
+       obj.doScroll  = 0 <= obj.toScrollX || 0 <= obj.toScrollY;\r
+       obj.transform = false;\r
+       obj.fallback  = 0;\r
+       \r
+       if( obj.fromX === obj.fromX || obj.fromY === obj.fromY ){\r
+               obj.transform = !!X_NodeAnime_hasTransform;\r
+       };\r
+       \r
+       // scale\r
+       if( obj.toScaleX !== 1 && obj.fromScaleX !== 1 && obj.toScaleY !== 1 && obj.fromScaleY !== 1 ){\r
+               sameRate = obj.fromScaleX === obj.fromScaleY && obj.toScaleX === obj.toScaleY;\r
+               \r
+               if( X_NodeAnime_hasTransform ){\r
+                       obj.transform = true;\r
+               } else\r
+               if( X_NodeAnime_hasDXTransform && ( fallback & 16 ) ){ // DX Transform\r
+                       obj.fallback = 16;\r
+               } else\r
+               if( ( fallback & 4 ) && sameRate ){ // zoom\r
+                       obj.fallback = 4;\r
+               } else\r
+               if( ( fallback & 2 ) && sameRate ){ // fontSize\r
+                       obj.fallback = 2;\r
+               } else\r
+               if( fallback & 1 ){ // width & height\r
+                       obj.fallback = 1;\r
+               };\r
+       };\r
+\r
+       // rotate, skew\r
+       if( obj.toRotate === obj.toRotate || obj.toSkewX === obj.toSkewX || obj.toSkewY === obj.toSkewY ){\r
+               if( X_NodeAnime_hasTransform ){\r
+                       obj.transform = true;\r
+               } else\r
+               if( X_NodeAnime_hasDXTransform && ( fallback & 16 ) ){ // DX Transform\r
+                       obj.fallback = 16;\r
+               };\r
+       };\r
 \r
        if( !obj.duration && 6 <= obj.phase ){\r
                this[ 'stop' ](); // 現在値で停止\r
@@ -121,9 +225,10 @@ function X_Node_animate( start, dest, duration, easing, lazyRelease, option ){
        return this;\r
 };\r
 \r
-function X_NodeAnime_getFinite( a, b ){\r
+function X_NodeAnime_getFinite( a, b, c ){\r
        if( a || a === 0 ) return a;\r
        if( b || b === 0 ) return b;\r
+       if( c || c === 0 ) return c;\r
        return NaN;\r
 };\r
 \r
@@ -139,7 +244,7 @@ function X_NodeAnime_getFinite( a, b ){
 function X_Node_stop( option ){\r
        var obj    = this[ '_anime' ],\r
                list   = X_NodeAnime_QUEUE,\r
-               i, rm, j, xnode, _obj;\r
+               rm;\r
        \r
        if( !obj || !obj.phase ) return this;\r
 \r
@@ -154,19 +259,25 @@ function X_Node_stop( option ){
                case 4 : // 強制停止(GPU転送予約)\r
                case 7 : // アニメーション中\r
                        if( option & X_NODE_ANIME_RESET ){\r
-                               obj.startX = obj.startY = obj.destX = obj.destY = obj.x = obj.y = X_NodeAnime_hasTransform ? 0 : NaN;\r
-                               obj.startA = obj.destA = obj.a = 1;\r
+                               X_Object_override( obj, X_NodeAnime_DEFAULT );\r
                        }; // TODO 終了値で停止も,,,\r
                        \r
                        // obj.canceled = true;\r
                        \r
                        if( rm ) break; // 1,2,3,6 の場合ここまで\r
                \r
-                       obj.destX = obj.x;\r
-                       obj.destY = obj.y;\r
-                       obj.destA = obj.a;\r
-\r
-                       obj.phase = 4; // 強制解除\r
+                       obj.toX       = obj.x;\r
+                       obj.toY       = obj.y;\r
+                       obj.toRotate  = obj.rotate;\r
+                       obj.toSkewX   = obj.skewX;\r
+                       obj.toSkewY   = obj.skewY;\r
+                       obj.toScaleX  = obj.scaleX;\r
+                       obj.toScaleY  = obj.scaleY;\r
+                       obj.toAlpha   = obj.alpha;\r
+                       obj.toScrollX = obj.scrollX;\r
+                       obj.toScrollY = obj.scrollY;\r
+\r
+                       obj.phase     = 4; // 強制解除\r
                        X_NodeAnime_needsDetection = true;\r
                        \r
                case 5 : // GPU解除待ち\r
@@ -199,7 +310,7 @@ function X_NodeAnime_stopNow( xnode ){
        // この部分 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
+               ( flags & X_NodeFlags_GPU_RELEASE_RESERVED ) || X_NodeAnime_updatePosition( xnode, obj, 0.5, false );\r
                skipUpdate || ( xnode[ '_rawObject' ].style.cssText = X_Node_CSS_objToCssText( xnode ) );\r
                xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
        };\r
@@ -275,21 +386,29 @@ function X_NodeAnime_updateAnimations( e ){
 \r
                switch( obj.phase ){\r
                        case 7 : // アニメーション中\r
-                               if( now < obj.destTime ){\r
-                                       easing = obj.progress  = obj.easing.fn( ( now - obj.startTime ) / obj.duration );\r
-                                       X_NodeAnime_updatePosition( xnode, \r
-                                               obj.x = ( obj.destX - obj.startX ) * easing + obj.startX,\r
-                                               obj.y = ( obj.destY - obj.startY ) * easing + obj.startY,\r
-                                               obj.a = ( obj.destA - obj.startA ) * easing + obj.startA, true );\r
+                               if( now < obj.toTime ){\r
+                                       obj.progress = ( now - obj.fromTime ) / obj.duration;\r
+                                       easing      = obj.easing( obj.progress );\r
+                                       obj.x       = ( obj.toX       - obj.fromX       ) * easing + obj.fromX;\r
+                                       obj.y       = ( obj.toY       - obj.fromY       ) * easing + obj.fromY;\r
+                                       obj.rotate  = ( obj.toRotate  - obj.fromRotate  ) * easing + obj.fromRotate;\r
+                                       obj.skewX   = ( obj.toSkewX   - obj.fromSkewX   ) * easing + obj.fromSkewX;\r
+                                       obj.skewY   = ( obj.toSkewY   - obj.fromSkewY   ) * easing + obj.fromSkewY;\r
+                                       obj.scaleX  = ( obj.toScaleX  - obj.fromScaleX  ) * easing + obj.fromScaleX;\r
+                                       obj.scaleY  = ( obj.toScaleY  - obj.fromScaleY  ) * easing + obj.fromScaleY;\r
+                                       obj.alpha   = ( obj.toAlpha   - obj.fromAlpha   ) * easing + obj.fromAlpha;\r
+                                       obj.scrollX = ( obj.toScrollX - obj.fromScrollX ) * easing + obj.fromScrollX;\r
+                                       obj.scrollY = ( obj.toScrollY - obj.fromScrollY ) * easing + obj.fromScrollY;\r
+                                       X_NodeAnime_updatePosition( xnode, obj, obj.progress, true );\r
                                        c = true;\r
                                        break;\r
                                };\r
                                // アニメーション終了\r
                                xnode[ 'asyncDispatch' ]( X_EVENT_ANIME_END );\r
                                \r
-                       case 4 : // 強制停止(GPU転送予約)\r
+                       case 4 : // 強制停止(GPU転送予約)または transform や opacity の値のみ設定\r
                                lazy = !obj.follower && !obj.releaseNow && obj.lazyRelease;\r
-                               X_NodeAnime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, !!lazy );\r
+                               X_NodeAnime_updatePosition( xnode, obj, 1, !!lazy );\r
 \r
                                //if( obj.canceled ){\r
                                //      xnode[ 'asyncDispatch' ]( X_EVENT_CANCELED );\r
@@ -299,7 +418,7 @@ function X_NodeAnime_updateAnimations( e ){
                                \r
                                if( lazy ){\r
                                        console.log( 'アニメーション終了(' + obj.phase + ') -> GPU 解除待機 ' + lazy );\r
-                                       obj.releaseTime = now + lazy;\r
+                                       obj.toTime = now + lazy;\r
                                        obj.phase = 5; // GPU解除待ち\r
                                        c = true;\r
                                } else {\r
@@ -309,19 +428,19 @@ function X_NodeAnime_updateAnimations( e ){
                                break;\r
 \r
                        case 6 : // アニメーション開始可能\r
-                               obj.startTime = now;\r
-                               obj.destTime  = now + obj.duration;\r
-                               obj.phase     = 7; // アニメーション中\r
-                               obj.progress  = 0;                                      \r
+                               obj.fromTime = now;\r
+                               obj.toTime   = now + obj.duration;\r
+                               obj.phase    = 7; // アニメーション中\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
+                               ( !obj.inited || X_NodeAnime_translateZ ) && X_NodeAnime_updatePosition( xnode, obj, 0, true );\r
                                break;\r
                        \r
                        case 5 : // GPU解除待ち\r
-                               if( obj.releaseTime <= now || obj.follower || obj.releaseNow ){\r
-                                       X_NodeAnime_translateZ && X_NodeAnime_updatePosition( xnode, obj.destX, obj.destY, obj.destA, false );\r
+                               if( obj.toTime <= now || obj.follower || obj.releaseNow ){\r
+                                       X_NodeAnime_translateZ && X_NodeAnime_updatePosition( xnode, obj, 1, false );\r
                                        rm = true;\r
                                } else {\r
                                        c = true;\r
@@ -330,8 +449,8 @@ function X_NodeAnime_updateAnimations( e ){
                        \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
+                               obj.inited || X_NodeAnime_updatePosition( xnode, obj, 0, false );\r
+                               obj.inited = true;\r
                                break;\r
                };\r
                \r
@@ -378,65 +497,124 @@ function X_NodeAnime_sortAnimationNode( xnode1, xnode2 ){
     return a ? -1 : 1;\r
 };\r
 \r
-function X_NodeAnime_updatePosition( xnode, x, y, opacity, useGPU ){\r
-       //console.log( 'updatePosition x:' + x + ' gpu:' + !!useGPU );\r
-       if( X_NodeAnime_hasTransform ){\r
-               xnode[ 'css' ]({\r
-                       transform : 'translate(' + ( x | 0 ) + 'px,' + ( y | 0 ) + 'px)' + ( useGPU ? X_NodeAnime_translateZ : '' ),\r
-                       opacity   : opacity\r
-               });\r
+function X_NodeAnime_updatePosition( xnode, obj, ratio, useGPU ){\r
+       var str = '',\r
+               x, y, rotate, skewX, skewY, scaleX, scaleY, alpha,\r
+               scrollX, scrollY;\r
+       \r
+       if( ratio === 1 ){\r
+               x      = obj.x = obj.toX;\r
+               y      = obj.y = obj.toY;\r
+               rotate = X_Node_CSS_ieMathRangeFix( obj.rotate = obj.toRotate );\r
+               skewX  = X_Node_CSS_ieMathRangeFix( obj.skewX  = obj.toSkewX );\r
+               skewY  = X_Node_CSS_ieMathRangeFix( obj.skewY  = obj.toSkewY );\r
+               scaleX = obj.scaleX = obj.toScaleX;\r
+               scaleY = obj.scaleY = obj.toScaleY;\r
+               alpha  = obj.alpha  = obj.toAlpha;\r
        } else {\r
-               x === x && xnode[ 'css' ]( 'left', ( x | 0 ) + 'px' );\r
-               y === y && xnode[ 'css' ]( 'top', ( y | 0 ) + 'px' );\r
-               opacity === opacity && xnode[ 'css' ]( 'opacity', opacity );\r
+               x      = obj.x;\r
+               y      = obj.y;\r
+               rotate = X_Node_CSS_ieMathRangeFix( obj.rotate );\r
+               skewX  = X_Node_CSS_ieMathRangeFix( obj.skewX );\r
+               skewY  = X_Node_CSS_ieMathRangeFix( obj.skewY );\r
+               scaleX = obj.scaleX;\r
+               scaleY = obj.scaleY;\r
+               alpha  = obj.alpha;\r
        };\r
-\r
-       if( X_NodeAnime_translateZ ){\r
-               if( useGPU ){\r
-                       if( xnode[ '_flags' ] & X_NodeFlags_GPU_RELEASE_RESERVED ){\r
-                               xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
-                               xnode[ '_flags' ] |= X_NodeFlags_GPU_NOW;\r
-                       } else\r
-                       if( !( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ) ){\r
-                               xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
-                               xnode[ '_flags' ] |= X_NodeFlags_GPU_RESERVED;\r
-                       };\r
-               } else {\r
-                       if( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ){\r
-                               xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
-                               xnode[ '_flags' ] |= X_NodeFlags_GPU_RELEASE_RESERVED;\r
-                       } else\r
-                       if( xnode[ '_flags' ] & X_NodeFlags_GPU_RESERVED ){\r
-                               xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
-                       };\r
+       \r
+       //console.log( 'updatePosition x:' + x + ' gpu:' + !!useGPU );\r
+       if( obj.transform ){\r
+               if( x === x || y === y ) str += ' translate(' + ( x | 0 ) + 'px,' + ( y | 0 ) + 'px)';\r
+               if( rotate < 0 || 0 < rotate ) str += ' rotate(' + rotate + 'deg)'; // opera は rad?\r
+               if( skewX  < 0 || 0 < skewX  ) str += ' skewX('  + skewX  + 'deg)';\r
+               if( skewY  < 0 || 0 < skewY  ) str += ' skewY('  + skewY  + 'deg)';\r
+               if( scaleX < 1 || 1 < scaleX ) str += ' scaleX(' + scaleX + ')';\r
+               if( scaleY < 1 || 1 < scaleY ) str += ' scaleY(' + scaleY + ')';\r
+               xnode[ 'css' ]( 'transform', ( str ? str.substr( 1 ) : '' ) + ( useGPU ? X_NodeAnime_translateZ : '' ) );\r
+               \r
+               if( X_NodeAnime_translateZ ){\r
+                       if( useGPU ){\r
+                               if( xnode[ '_flags' ] & X_NodeFlags_GPU_RELEASE_RESERVED ){\r
+                                       xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
+                                       xnode[ '_flags' ] |= X_NodeFlags_GPU_NOW;\r
+                               } else\r
+                               if( !( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ) ){\r
+                                       xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
+                                       xnode[ '_flags' ] |= X_NodeFlags_GPU_RESERVED;\r
+                               };\r
+                       } else {\r
+                               if( xnode[ '_flags' ] & X_NodeFlags_GPU_NOW ){\r
+                                       xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
+                                       xnode[ '_flags' ] |= X_NodeFlags_GPU_RELEASE_RESERVED;\r
+                               } else\r
+                               if( xnode[ '_flags' ] & X_NodeFlags_GPU_RESERVED ){\r
+                                       xnode[ '_flags' ] &= X_Node_BitMask_RESET_GPU;\r
+                               };\r
+                       };              \r
                };              \r
+       } else\r
+       if( obj.fallback === 16 ){\r
+               xnode[ 'css' ]( 'dxtransform', [ x || 0, y || 0, rotate || 0, skewX || 0, skewY || 0, scaleX, scaleY ] );\r
+       } else {\r
+               x === x && xnode[ 'css' ]( 'left', ( x | 0 ) + 'px' );\r
+               y === y && xnode[ 'css' ]( 'top',  ( y | 0 ) + 'px' );\r
+               \r
+               switch( obj.fallback ){\r
+                       case 4 :\r
+                               xnode[ 'css' ]( 'zoom', scaleX );\r
+                               break;\r
+                       case 2 :\r
+                               xnode[ 'css' ]( 'fontSize', scaleX + 'em' );\r
+                               break;\r
+                       case 1 :\r
+                               \r
+                               break;\r
+               };\r
        };\r
+       \r
+       alpha === alpha && xnode[ 'css' ]( 'opacity', alpha );\r
 };\r
 \r
 \r
 var\r
        X_NodeAnime_ease = {\r
-               'quadratic' : {\r
+               'quadratic' : function (k) {\r
+                               return k * ( 2 - k );\r
+                               /*{\r
                        style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',\r
                        fn: function (k) {\r
                                return k * ( 2 - k );\r
-                       }\r
+                       }*/\r
                },\r
-               'circular' : {\r
-                       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
+               'circular' : function (k) {\r
+                               return Math.sqrt( 1 - ( --k * k ) );\r
+                       /*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
                        fn: function (k) {\r
                                return Math.sqrt( 1 - ( --k * k ) );\r
-                       }\r
+                       }*/\r
                },\r
-               'back' : {\r
-                       style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\r
+               'back' : function (k) {\r
+                               return --k * k * ( 5 * k + 4 ) + 1;\r
+                       /*style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\r
                        fn: function (k) {\r
                                var b = 4;\r
                                return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;\r
-                       }\r
+                       }*/\r
                },\r
-               'bounce' : {\r
-                       style: '',\r
+               'bounce' : function (k, X) {\r
+                               X = 7.5625;\r
+                               if ( k < ( 1 / 2.75 ) ) {\r
+                                       return X * k * k;\r
+                               } else\r
+                               if ( k < ( 2 / 2.75 ) ) {\r
+                                       return X * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;\r
+                               } else\r
+                               if ( k < ( 2.5 / 2.75 ) ) {\r
+                                       return X * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;\r
+                               } else {\r
+                                       return X * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;\r
+                               }\r
+                       /*style: '',\r
                        fn: function (k) {\r
                                if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {\r
                                        return 7.5625 * k * k;\r
@@ -447,10 +625,11 @@ var
                                } else {\r
                                        return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;\r
                                }\r
-                       }\r
+                       }*/\r
                },\r
-               'elastic' : {\r
-                       style: '',\r
+               'elastic' : function (k) {\r
+                               return k === 0 ? 0 : k === 1 ? 1 : ( 0.4 * Math.pow( 2, - 10 * k ) * Math.sin( ( k - 0.055 ) * 28.56 ) + 1 );\r
+                       /*style: '',\r
                        fn: function (k) {\r
                                var f = 0.22,\r
                                        e = 0.4;\r
@@ -459,6 +638,6 @@ var
                                if ( k == 1 ) { return 1; }\r
 \r
                                return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );\r
-                       }\r
+                       } */\r
                }\r
        };\r