OSDN Git Service

Version 0.6.202, update xnode.animate().
authoritozyun <itozyun@user.sourceforge.jp>
Sat, 19 Dec 2015 06:57:29 +0000 (15:57 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Sat, 19 Dec 2015 06:57:29 +0000 (15:57 +0900)
0.6.x/css/xui.css
0.6.x/js/02_dom/02_XNodeFlags.js
0.6.x/js/02_dom/06_XNodeCSS.js
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 6f91c92..18bdf2c 100644 (file)
                .IE5x .ScrollBox-IndicatorH {\r
                        line-height : 0.5;\r
                }\r
+\r
+.IE8 * {\r
+       filter : inherit;\r
+}\r
index 166e14b..77ef0e2 100644 (file)
@@ -33,18 +33,19 @@ var X_NodeFlags_DESTROYED              = 0x0,
        X_NodeFlags_GPU_NOW                = 2 << 22, // 3:GPU now!\r
        X_NodeFlags_GPU_RELEASE_RESERVED   = 2 << 23, // 4:GPU解除予約\r
        X_NodeFlags_GPU_CHILD              = 2 << 24, \r
-               \r
+       \r
        X_NodeFlags_IE4_HAS_TEXTNODE       = X_UA[ 'IE4' ] ? 2 << 21 : 0,\r
        X_NodeFlags_IE4_HAS_ELEMENT        = X_UA[ 'IE4' ] ? 2 << 22 : 0,\r
        X_NodeFlags_IE4_DIRTY_CHILDREN     = X_UA[ 'IE4' ] ? 2 << 23 : 0,\r
        X_NodeFlags_IE4_FIXED              = X_UA[ 'IE4' ] ? 2 << 24 : 0,\r
 \r
        X_NodeFlags_IE5_DISPLAY_NONE_FIX   = X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? 2 << 24 : 0,\r
-       X_NodeFlags_IE8_OPACITY_FIX        = X_UA[ 'IE8' ] && X_UA[ 'ActiveX' ] ? 2 << 25 : 0,\r
+       X_NodeFlags_IE8_OPACITY_FIX        = 0,//X_UA[ 'IE8' ] && X_UA[ 'ActiveX' ] ? 2 << 25 : 0,\r
+       X_NodeFlags_IE_FILTER_FIX_AFTER    = X_UA[ 'ActiveX' ] && 2 << 26,\r
        \r
        // http://modernizr.com/downloads/modernizr.js\r
        // Thanks to Erik Dahlstrom\r
-       X_NodeFlags_IS_SVG                 = document.createElementNS && document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' )[ 'createSVGRect' ] ? 2 << 26 : 0,\r
+       X_NodeFlags_IS_SVG                 = document.createElementNS && document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' )[ 'createSVGRect' ] ? 2 << 27 : 0,\r
        X_NodeFlags_IS_VML                 =\r
                        ( function(){\r
                                if( !X_UA[ 'ActiveX' ] || X_UA[ 'IE' ] < 5 || 9 < X_UA[ 'IE' ] /* || X_UA[ 'ieExeComError' ] */ ) return 0; // standalone の除外 -> X_UA[ 'ieExeComError' ]\r
@@ -65,12 +66,10 @@ var X_NodeFlags_DESTROYED              = 0x0,
                                                document.getElementById( 'vmltest2' ).removeNode( true );\r
                                        case 1 :\r
                                                document.getElementById( 'vmltest1' ).removeNode( true );\r
-                                               return 2 << 27;\r
+                                               return 2 << 28;\r
                                };\r
                                return 0;\r
                        })(),\r
-       \r
-       X_NodeFlags_SYSTEM_NODE     = 2 << 28,\r
 \r
        X_Node_BITMASK_RESET_STYLE  = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\r
                X_NodeFlags_STYLE_IS_DISPLAY_NONE |\r
index 9bcfdfd..2463840 100644 (file)
@@ -277,9 +277,9 @@ function X_Node_CSS_objToCssText( that, skipFilter ){
        };
        
        if( filterFix ){
-               v = X_Node_CSS_objToIEFilterText( that, filterFix, css );
+               v = X_Node_CSS_objToIEFilterText( that, filterFix /* , css */ );
                if( v ){
-                       css[ ++n ] = 'filter:' + v;
+                       css[ ++n /* css.length */ ] = 'filter:' + v;
                };
                skipFilter = skipFilter && v;
        } else {
@@ -303,10 +303,11 @@ var
 X_Node_CSS_FILTER_FIX_PROPS =
        X_UA[ 'ActiveX' ] && X_UA[ 'IE' ] < 9 ?
                {
-                       'opacity'    : 2,
-                       'boxShadow'  : 3,
-                       'textShadow' : 4,
-                       'transform'  : 5
+                       'opacity'     : 2,
+                       'boxShadow'   : 3,
+                       'textShadow'  : 4,
+                       'transform'   : 5,
+                       'dxtransform' : 7 // X.NodeAnime で使用
                } :
        X_UA[ 'ActiveX' ] && X_UA[ 'IE9' ] ? // == 9
                {
@@ -317,14 +318,13 @@ X_Node_CSS_FILTER_FIX_PROPS =
 function X_Node_CSS_objToIEFilterText( that, opt_css, opt_cssList ){
        var obj     = opt_css || that[ '_css' ],
                test    = X_Node_CSS_FILTER_FIX_PROPS,
-               css     = {},
                filters = [],
                n       = -1,
                p, id, v, num, ary, params, i, l, dir,
                afterUpdate, impossible;
 
        for( p in obj ){
-               if( X_EMPTY_OBJECT[ p ] ) continue;
+               //if( X_EMPTY_OBJECT[ p ] ) continue;
                
                if( !( id = test[ p ] ) ) continue;
                v = obj[ p ];
@@ -403,25 +403,131 @@ function X_Node_CSS_objToIEFilterText( that, opt_css, opt_cssList ){
                                        X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, that, X_Node_CSS_onAfterUpdateForIEFilterFix );
                                        break;
                                };
-                               dir = Math.atan2( params[ 1 ] + params[ 3 ], params[ 0 ] + params[ 3 ] ) * 180 / Math.PI + 90;
-                               dir += dir < 0 ? 360 : 0;
+                               dir = X_Node_CSS_ieMathRangeFix( Math.atan2( params[ 1 ] + params[ 3 ], params[ 0 ] + params[ 3 ] ) * 180 / Math.PI + 90 );
                                filters[ ++n ] = 'shadow(color=' + color + ',strength=' + params[ 3 ] + ',direction=' + ( dir | 0 ) + ')';
                                break;
                        case 4 : //'textShadow' :
                                //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none
                                //glow(Color=yellow,Strength=10);
-                               //どうやらCSSのbackgroundプロパティと同時に使えないようです。 s
+                               //どうやらCSSのbackgroundプロパティと同時に使えないようです。 
                                break;
                        case 6 : //'backgroundImage' :
                                //
-                       
+                               break;
+
                        case 5 : // transform scale, matrix
-                               
+                               break;
+                       case 7 : // dxtransform
+                               that[ '_flags' ] |= X_NodeFlags_IE_FILTER_FIX_AFTER;
+                               break;
                };
        };
        return filters.join( ' ' );
 };
 
+
+       //0 ~ 360の範囲に収める.
+       function X_Node_CSS_ieMathRangeFix( a ){
+               a %= 360;
+               return a < 0 ? 360 + a : a;
+       };
+
+/*
+ * http://p2b.jp/200912-CSS3-Transform-for-IE8
+ * http://rtilabs.rti-giken.jp/files/2011_09_16/rotate.html
+ */
+       function X_Node_CSS_IETransform( elm, params ){
+               var PI_180 = Math.PI / 180,
+
+                       rotate = X_Node_CSS_ieMathRangeFix( params[ 2 ] ),//回転
+                       radian = rotate * PI_180,
+                       cosX   = Math.cos( radian ),
+                       sinY   = Math.sin( radian ),
+                       
+                       skewX  = X_Node_CSS_ieMathRangeFix( params[ 3 ] ), //skew
+                       skewY  = X_Node_CSS_ieMathRangeFix( params[ 4 ] );
+                       
+                       _skX   = Math.tan( skewX * PI_180 ),
+                       _skY   = Math.tan( skewY * PI_180 ),
+                       
+                       scaleX = params[ 5 ], //拡大
+                       scaleY = params[ 6 ],
+                       
+                       m11    = cosX * scaleX,
+                       m12    = ( -sinY + _skX ) * scaleX,
+                       m21    = (  sinY + _skY ) * scaleY,
+                       m22    = cosX * scaleY,
+
+                       //absolute時には軸を補正してあげないとだめだ。
+                       //ブラウザとして軸がずれている。
+                       //計算式元ネタ http://p2b.jp/200912-CSS3-Transform-for-IE8
+       
+                       //offset*系のサイズは回転によって生じたゆがみも考慮されるらしい。
+       
+                       //拡大縮小も同じ.
+                       //this.get(0).style.width や height には拡縮の影響を受けない元の数字が入っている
+                       ow = elm.offsetWidth,
+                       oh = elm.offsetHeight,
+       
+                       absCosX = Math.abs( cosX ),
+                       absSinY = Math.abs( sinY ),
+       
+                               //回転の補正
+                       dx = ( ow - ( ow * absCosX + oh * absSinY ) ) / 2
+                               //skewの補正(rotate しながらskew すると補正がおかしくなります。 これがわからない)
+                                - ow / 2 * _skX
+                               //拡大の補正
+                                - ( ( ow * scaleX - ow ) / 2 | 0 )
+                               // x
+                                + params[ 0 ],
+                       dy = ( oh - ( ow * absSinY + oh * absCosX ) ) / 2
+                               //skewの補正(
+                                - oh / 2 * _skY
+                               //拡大の補正
+                                - ( ( oh * scaleY - oh ) / 2 | 0 )
+                               // y
+                                + params[ 1 ];
+
+               //console.log( ow +  ' ' + oh )
+               elm.style.left = dx + 'px';
+               elm.style.top  = dy + 'px';
+               
+               //フィルターで回転と拡大縮小を加えます。
+               return 'progid:DXImageTransform.Microsoft.Matrix(' +
+                                                               // 'Dx='  + dx +
+                                                               //',Dy='  + dy +
+                                                               'M11=' + m11 + 
+                                                               ',M12=' + m12 + 
+                                                               ',M21=' + m21 + 
+                                                               ',M22=' + m22 + 
+                                                               ',FilterType="bilinear",sizingMethod="auto expand")';
+       };
+
+function X_Node_CSS_onAfterUpdateIEFilterFix( that ){
+       var PI_180 = Math.PI / 180,
+               test   = X_Node_CSS_FILTER_FIX_PROPS,
+               css    = that[ '_css' ],
+               elm    = that[ '_rawObject' ],
+               filter = elm.style.filter || '',
+               origin = filter,
+               p, v, plus;
+
+       for( p in css ){
+               if( !( id = test[ p ] ) ) continue;
+               plus = 0;
+               switch( id ){
+                       case 7 : // dxtransform
+                               plus = X_Node_CSS_IETransform( elm, css[ p ] );
+                               break;
+                       default :
+                               continue;
+               };
+               if( plus ) filter += ( filter ? ' ' : '' ) + plus;
+       };
+       if( filter !== origin ) elm.style.filter = filter;
+};
+
+
 function X_Node_CSS_onAfterUpdateForIEFilterFix(){
        if( this[ '_flags' ] & X_NodeFlags_IN_TREE ){ // 要素があり、要素がツリーに属している
                this[ '_flags' ] |= X_NodeFlags_DIRTY_IE_FILTER;
@@ -675,7 +781,7 @@ function X_Node_cssText( v ){
 };
 
 /*
- * ここでは HTMLElement のチ1ェックは行わない!
+ * ここでは HTMLElement のチ1ェックは行わない! <- 行う!
  * TODO
  * body に css attr がセットされた場合には X_ViewPort_baseFontSize をクリア
  * class, id, attr(<font size><basefont>) の変更があった場合は、変更の適用の後、charSize を取得
@@ -689,12 +795,13 @@ X_Node_CSS_getCharSize =
                        X_Node_updateTimerID && X_Node_startUpdate();
                        if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize;
                        if( that[ '_fontSize' ] ) return that[ '_fontSize' ];
-                       return that[ '_fontSize' ] = parseFloat( X_Node_CSS_getComputedStyle( that[ '_rawObject' ], null ).fontSize );
+                       return that[ '_fontSize' ] = that[ '_rawObject' ] ? parseFloat( X_Node_CSS_getComputedStyle( that[ '_rawObject' ], null ).fontSize ) : 0;
                }) :
 
        5 <= X_UA[ 'IE' ] ?
                (function( that ){
                        var font, vu, v, u, _v;
+                       
                        X_Node_updateTimerID && X_Node_startUpdate();
                        if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize;
                        if( that[ '_fontSize' ] ) return that[ '_fontSize' ];
@@ -740,10 +847,11 @@ X_Node_CSS_getCharSize =
        X_UA_DOM.IE4 ?
                (function( that ){
                        var font, vu, v, u, _v;
+                       
                        X_Node_updateTimerID && X_Node_startUpdate();
                        if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize;
                        if( that[ '_fontSize' ] ) return that[ '_fontSize' ];
-                       
+
                        if( that[ '_css' ] && ( font = that[ '_css' ].fontSize ) ){
                                vu = X_Node_CSS__splitValueAndUnit( font );
                                v  = vu[ 0 ];
@@ -755,7 +863,7 @@ X_Node_CSS_getCharSize =
                                        if( _v = X_Node_CSS__UNIT_RATIO[ u ] ) return that[ '_fontSize' ] = v / _v;
                                };
                        } else {
-                               // 要素を生成して測定!
+                               // TODO 要素を生成して測定! ではなくて elm.style.fontSize が使えそう
                                ( that[ '_rawObject' ] || X_Node__ie4getRawNode( that ) ).insertAdjacentHTML( 'BeforeEnd', '<div id="ie4charsize" style="position:absolute;top:0;left:0;visivility:hidden;line-height:1;height:1em;">X</div>' );
                                elm = document.all[ 'ie4charsize' ];
                                v = elm.offsetHeight;
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
index 1656421..81c33fa 100644 (file)
@@ -1223,7 +1223,7 @@ function X_Node_call( name /*, opt_args... */ ){
                case 'treeIsDirty' :
                        return !!X_Node_updateTimerID;
                case 'fontSize' :
-                       return this.parent ? X_Node_CSS_getCharSize( this ) : 0;
+                       return ( this[ '_flags' ] & X_NodeFlags_IN_TREE ) ? X_Node_CSS_getCharSize( this ) : 0;
                case 'inGPU' :
                        return !!( this[ '_flags' ] & ( X_NodeFlags_GPU_NOW | X_NodeFlags_GPU_RELEASE_RESERVED ) );
                case 'isGPUChild' :
@@ -1367,7 +1367,7 @@ function X_Node_reserveUpdate(){
 var X_Node_updateReservedByReleaseGPU = false;
 
 function X_Node_startUpdate( time ){
-       var removal, i, xnodeOrElm;
+       var removal, i, xnodeOrElm, xnodesIEFilterFixAfter, xnode;
        
        if( !X_Node_updateTimerID || X_ViewPort_readyState < X_EVENT_INIT ){
                return;
@@ -1408,10 +1408,10 @@ function X_Node_startUpdate( time ){
        };
        
        if( X_Node_html[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
-               X_Node__commitUpdate( X_Node_html, X_Node_html[ '_rawObject' ].parentNode, null, X_Node_html[ '_flags' ], 1 );
+               X_Node__commitUpdate( X_Node_html, X_Node_html[ '_rawObject' ].parentNode, null, X_Node_html[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
        } else {
-               X_Node__commitUpdate( X_Node_head, X_Node_head[ '_rawObject' ].parentNode, null, X_Node_head[ '_flags' ], 1 );
-               X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ], 1 );
+               X_Node__commitUpdate( X_Node_head, X_Node_head[ '_rawObject' ].parentNode, null, X_Node_head[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
+               X_Node__commitUpdate( X_Node_body, X_Node_body[ '_rawObject' ].parentNode, null, X_Node_body[ '_flags' ], 1, xnodesIEFilterFixAfter = [] );
        };
        
        if( X_Node_updateReservedByReleaseGPU ){
@@ -1419,12 +1419,16 @@ function X_Node_startUpdate( time ){
                X_Node_updateReservedByReleaseGPU = false;
        };
        
-       if( time ){
-               // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに
-               X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ 'dispatch' ]( X_EVENT_UPDATED );   
-       } else {
-               X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ 'asyncDispatch' ]( X_EVENT_UPDATED );
+       if( X_NodeFlags_IE_FILTER_FIX_AFTER && xnodesIEFilterFixAfter.length ){
+               for( i = 0; xnode = xnodesIEFilterFixAfter[ i ]; ++i ){
+                       xnode[ '_flags' ] &= ~X_NodeFlags_IE_FILTER_FIX_AFTER;
+                       X_Node_CSS_onAfterUpdateIEFilterFix( xnode );
+               };
        };
+
+       // time を視て X.Timer 経由の場合、即座に発火する。
+       // width() 等で強制的にツリーを構築している場合、UPDATE イベントのコールバックで要素を変更しサイズを取ると無限ループになる,これを防ぐため asyncDispatch とする
+       X_System[ '_listeners' ] && X_System[ '_listeners' ][ X_EVENT_UPDATED ] && X_System[ time ? 'dispatch' : 'asyncDispatch' ]( X_EVENT_UPDATED );
        
        X_ViewPort[ '_listeners' ] && X_ViewPort[ '_listeners' ][ X_EVENT_AFTER_UPDATE ] && X_ViewPort[ 'asyncDispatch' ]( X_EVENT_AFTER_UPDATE );
 };
@@ -1444,9 +1448,9 @@ function X_Node_startUpdate( time ){
  */
 var X_Node__commitUpdate =
        X_UA_DOM.W3C ?
-               ( function( that, parentElement, nextElement, accumulatedFlags, ie8opacity ){
+               ( function( that, parentElement, nextElement, accumulatedFlags, ie8opacity, xnodesIEFilterFixAfter ){
                        var elm = that[ '_rawObject' ],
-                               created, xnodes, l, next;
+                               created, xnodes, l, next, anime, v;
 
                        // 1. GPU 一切の更新をスキップ
                        if( that[ '_flags' ] & X_NodeFlags_GPU_NOW ){
@@ -1474,7 +1478,8 @@ var X_Node__commitUpdate =
                        if( that[ '_flags' ] & X_NodeFlags_STYLE_IS_DISPLAY_NONE ){
                                if( X_Node_displayNoneFixForIE5 ){
                                        // filter の効いている要素を含む要素は display:none が無視される。
-                                       // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。                                         
+                                       // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。 
+                                       // TODO filters[0].enabled = false なんてどう?                                     
                                        if( elm && elm.parentNode ){
                                                X_Node__actualRemove( that );
                                        };
@@ -1600,10 +1605,14 @@ var X_Node__commitUpdate =
                                };
                        };
                        
+                       if( that[ '_flags' ] & X_NodeFlags_IE_FILTER_FIX_AFTER ){
+                               xnodesIEFilterFixAfter[ xnodesIEFilterFixAfter.length ] = that;
+                       };
+                       
                        // 10. 子要素の更新。
                        if( ( xnodes = that[ '_xnodes' ] ) && ( l = xnodes.length ) ) {
                                for( ; l; ){
-                                       next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags, ie8opacity );
+                                       next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags, ie8opacity, xnodesIEFilterFixAfter );
                                };
                        };
 
@@ -1618,6 +1627,26 @@ var X_Node__commitUpdate =
                                };
                        };
 
+                       if( ( anime = that[ '_anime' ] ) && 6 <= anime.phase && anime.doScroll ){
+                               if( anime.phase === 6 ){
+                                       v = anime.fromScrollX;
+                                       if( v === v ){
+                                               elm.scrollLeft = v;
+                                       } else {
+                                               anime.fromScrollX = elm.scrollLeft;
+                                       };
+                                       v = anime.fromScrollY;
+                                       if( v === v ){
+                                               elm.scrollTop = v;
+                                       } else {
+                                               anime.fromScrollY = elm.scrollTop;
+                                       };
+                               } else {
+                                       elm.scrollLeft = anime.scrollX;
+                                       elm.scrollTop  = anime.scrollY;
+                               };
+                       };
+
                        return elm;
                }) :
        X_UA_DOM.IE4 ? 
@@ -1647,68 +1676,90 @@ var X_Node__commitUpdate =
                                        prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that, false ) ) :
                                        parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that, false ) );
                                X_Node__afterActualCreate( that );
-                               return that[ '_rawObject' ] || X_Node__ie4getRawNode( that );
-                       };
-                       
-                       accumulatedFlags |= that[ '_flags' ];
-                       
-                       xnodes = that[ '_xnodes' ];
-                       l      = xnodes ? xnodes.length : 0;
-                       dirty  = !!( that[ '_flags' ] & X_NodeFlags_IE4_DIRTY_CHILDREN );
-                       
-                       /*
-                        * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知
-                        * HTML の下に HTML だけ
-                        * HTML の下は MIX -> TextNode, html の削除、変更、追加
-                        * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる
-                        */
-                       if( dirty ){
-                               that[ '_flags' ] &= ~X_NodeFlags_IE4_DIRTY_CHILDREN;
-                               for( i = 0; i < l; ++i ){
-                                       if( xnodes[ i ][ '_tag' ] ){
-                                               that[ '_flags' ] |= X_NodeFlags_IE4_HAS_ELEMENT;
-                                       } else {
-                                               that[ '_flags' ] |= X_NodeFlags_IE4_HAS_TEXTNODE;
+                               
+                               elm = that[ '_rawObject' ] || X_Node__ie4getRawNode( that );
+                       } else {
+                               accumulatedFlags |= that[ '_flags' ];
+                               
+                               xnodes = that[ '_xnodes' ];
+                               l      = xnodes ? xnodes.length : 0;
+                               dirty  = !!( that[ '_flags' ] & X_NodeFlags_IE4_DIRTY_CHILDREN );
+                               
+                               /*
+                                * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知
+                                * HTML の下に HTML だけ
+                                * HTML の下は MIX -> TextNode, html の削除、変更、追加
+                                * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる
+                                */
+                               if( dirty ){
+                                       that[ '_flags' ] &= ~X_NodeFlags_IE4_DIRTY_CHILDREN;
+                                       for( i = 0; i < l; ++i ){
+                                               if( xnodes[ i ][ '_tag' ] ){
+                                                       that[ '_flags' ] |= X_NodeFlags_IE4_HAS_ELEMENT;
+                                               } else {
+                                                       that[ '_flags' ] |= X_NodeFlags_IE4_HAS_TEXTNODE;
+                                               };
+                                               if( that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){
+                                                       mix = true;
+                                                       break;
+                                               };
                                        };
-                                       if( that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){
-                                               mix = true;
-                                               break;
+                               };
+                               
+                               if( that[ '_flags' ] & X_NodeFlags_IE4_FIXED || that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_NodeFlags_IE4_HAS_ELEMENT ){
+                                       for( i = 0; i < l; ++i ){
+                                               prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );
+                                       };
+                               } else
+                               if( mix ){
+                                       html = [];
+                                       for( i = 0; i < l; ++i ){
+                                               html[ i ] = X_Node__actualCreate( xnodes[ i ], false );
+                                       };
+                                       elm.innerHTML = html.join( '' );
+                                       for( i = 0; i < l; ++i ){
+                                               X_Node__afterActualCreate( xnodes[ i ] );
                                        };
+                                       that[ '_flags' ] |= X_NodeFlags_IE4_FIXED;
+                               } else
+                               if( that[ '_flags' ] & X_NodeFlags_IE4_HAS_TEXTNODE ){
+                                       dirty = dirty || false;
+                                       for( i = 0; i < l; ++i ){
+                                               text = xnodes[ i ];
+                                               if( text[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
+                                                       text[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
+                                                       dirty = true;
+                                               };
+                                       };
+                                       if( dirty ) elm.innerHTML = that[ 'text' ]();
                                };
+                               
+                               if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that[ '_fontSize' ];
+                               
+                               that[ '_flags' ] &= ~X_NodeFlags_DIRTY_POSITION;
+                               that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );                               
                        };
                        
-                       if( that[ '_flags' ] & X_NodeFlags_IE4_FIXED || that[ '_flags' ] & X_Node_BitMask_IE4_IS_MIX === X_NodeFlags_IE4_HAS_ELEMENT ){
-                               for( i = 0; i < l; ++i ){
-                                       prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );
-                               };
-                       } else
-                       if( mix ){
-                               html = [];
-                               for( i = 0; i < l; ++i ){
-                                       html[ i ] = X_Node__actualCreate( xnodes[ i ], false );
-                               };
-                               elm.innerHTML = html.join( '' );
-                               for( i = 0; i < l; ++i ){
-                                       X_Node__afterActualCreate( xnodes[ i ] );
-                               };
-                               that[ '_flags' ] |= X_NodeFlags_IE4_FIXED;
-                       } else
-                       if( that[ '_flags' ] & X_NodeFlags_IE4_HAS_TEXTNODE ){
-                               dirty = dirty || false;
-                               for( i = 0; i < l; ++i ){
-                                       text = xnodes[ i ];
-                                       if( text[ '_flags' ] & X_Node_BitMask_IS_DIRTY ){
-                                               text[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY;
-                                               dirty = true;
+                       if( ( anime = that[ '_anime' ] ) && 6 <= anime.phase && anime.doScroll ){
+                               if( anime.phase === 6 ){
+                                       v = anime.fromScrollX;
+                                       if( v === v ){
+                                               elm.scrollLeft = v;
+                                       } else {
+                                               anime.fromScrollX = elm.scrollLeft;
+                                       };
+                                       v = anime.fromScrollY;
+                                       if( v === v ){
+                                               elm.scrollTop = v;
+                                       } else {
+                                               anime.fromScrollY = elm.scrollTop;
                                        };
+                               } else {
+                                       elm.scrollLeft = anime.scrollX;
+                                       elm.scrollTop  = anime.scrollY;
                                };
-                               if( dirty ) elm.innerHTML = that[ 'text' ]();
                        };
-                       
-                       if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that[ '_fontSize' ];
-                       
-                       that[ '_flags' ] &= ~X_NodeFlags_DIRTY_POSITION;
-                       that[ '_flags' ] & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );
+
                        return elm;
                }) :
                (function(){});
@@ -1795,11 +1846,11 @@ var X_Node__updateRawNode =
                                delete that[ '_newAttrs' ];
                        };
                        
-                       
                        if( accumulatedFlags & X_NodeFlags_IE8_OPACITY_FIX ){
                                memory = that[ '_css' ] && that[ '_css' ].opacity;
-                               if( f = true ){
-                                       if( !that[ '_css' ] ) that[ '_css' ] = {};
+                               f = true;
+                               if( 0 <= memory && memory < 1 ){
+                                       //if( !that[ '_css' ] ) that[ '_css' ] = {};
                                        that[ '_css' ].opacity = ie8opacity;
                                        if( that[ '_flags' ] & X_NodeFlags_DIRTY_CSS ){
                                                that[ '_flags' ] |= X_NodeFlags_OLD_CSSTEXT;
@@ -1832,12 +1883,18 @@ var X_Node__updateRawNode =
                                };
                        };
                        
+                       /*
+                        * http://jsdo.it/esukei/imOL
+                        * IE8でのfilter:alpha継承
+                        * IE8でfilter:alphaの指定がposition:relative,position:absoluteの子要素に継承されない問題
+                        */
                        if( f ){
                                if( 0 <= memory ){
                                        that[ '_css' ].opacity = memory;
                                } else {
-                                       delete that[ '_css' ].opacity;
-                                       if( X_Object_isEmpty( that[ '_css' ] ) ) delete that[ '_css' ];
+                                       //elm.style.filter = 'inherit';
+                                       //delete that[ '_css' ].opacity;
+                                       //if( X_Object_isEmpty( that[ '_css' ] ) ) delete that[ '_css' ];
                                };
                        };
                        
index fd8946b..46bc52d 100644 (file)
@@ -24,11 +24,13 @@ function XUI_ScrollBox_start( scrollBox ){
                if( scrollBox.xnode !== XUI_ScrollBox_indicatorV.parent ){\r
                        console.log( '*** Scroll Indicator add ***' );\r
                        scrollBox.xnode[ 'append' ]( XUI_ScrollBox_indicatorV );\r
-                       XUI_ScrollBox_indicatorV[ 'animate' ](\r
-                                       { opacity : 0 },\r
-                                       { opacity : 0.5 },\r
-                                       900, 'circular', 300\r
-                               );\r
+                       XUI_ScrollBox_indicatorV[ 'animate' ]({\r
+                                       'from'        : { opacity : 0 },\r
+                                       'to'          : { opacity : 0.5 },\r
+                                       'duration'    : 900,\r
+                                       'easing'      : 'circular',\r
+                                       'lazyRelease' : 300\r
+                               });\r
                        scrollBox\r
                                [ 'listen' ]( [ X_EVENT_CANCELED, XUI_Event.SCROLL_END ], XUI_ScrollBox_indicatorV, XUI_ScrollBox_indicatorHandleEvent );\r
                };\r
@@ -44,11 +46,13 @@ function XUI_ScrollBox_start( scrollBox ){
                };\r
                if( scrollBox.xnode !== XUI_ScrollBox_indicatorH.parent ){                      \r
                        scrollBox.xnode[ 'append' ]( XUI_ScrollBox_indicatorH );\r
-                       XUI_ScrollBox_indicatorH[ 'animate' ](\r
-                                       { opacity : 0 },\r
-                                       { opacity : 0.5 },\r
-                                       900, 'circular', 300\r
-                               );\r
+                       XUI_ScrollBox_indicatorH[ 'animate' ]({\r
+                                       'from'        : { opacity : 0 },\r
+                                       'to'          : { opacity : 0.5 },\r
+                                       'duration'    : 900,\r
+                                       'easing'      : 'circular',\r
+                                       'lazyRelease' : 300\r
+                               });\r
                        scrollBox\r
                                [ 'listen' ]( [ X_EVENT_CANCELED, XUI_Event.SCROLL_END ], XUI_ScrollBox_indicatorH, XUI_ScrollBox_indicatorHandleEvent );                       \r
                };\r
@@ -65,11 +69,13 @@ function XUI_ScrollBox_indicatorHandleEvent( e ){
                case X_EVENT_CANCELED :\r
                case XUI_Event.SCROLL_END :\r
                        console.log( '-fadeout-' );\r
-                       this[ 'animate' ](\r
-                               { opacity : 0.5 },\r
-                               { opacity : 0 },\r
-                               900, 'circular', 300\r
-                       );\r
+                       this[ 'animate' ]({\r
+                                       'from'        : { opacity : 0.5 },\r
+                                       'to'          : { opacity : 0 },\r
+                                       'duration'    : 900,\r
+                                       'easing'      : 'circular',\r
+                                       'lazyRelease' : 300\r
+                               });\r
                        break;\r
        };\r
 };\r
@@ -295,17 +301,19 @@ function X_UI_ScrollBox_translate( that, x, y, opt_time, opt_easing, opt_release
        opt_easing  = opt_easing === '' ? '' : opt_easing || 'circular';\r
        opt_release = 0 <= opt_release ? opt_release : 300;\r
        \r
-       that.xnodeSlider[ 'animate' ](\r
-               {\r
-                       x : that.scrollX,\r
-                       y : that.scrollY\r
-               },\r
-               {\r
-                       x : x,\r
-                       y : y\r
-               },\r
-               opt_time, opt_easing, opt_release\r
-       );\r
+       that.xnodeSlider[ 'animate' ]({\r
+                                       'from'        : {\r
+                                                       x : that.scrollX,\r
+                                                       y : that.scrollY\r
+                                               },\r
+                                       'to'          : {\r
+                                                       x : x,\r
+                                                       y : y\r
+                                               },\r
+                                       'duration'    : opt_time,\r
+                                       'easing'      : opt_easing,\r
+                                       'lazyRelease' : opt_release\r
+                               });\r
 \r
        if( X_UA[ 'IE' ] < 6 ){\r
                XUI_ScrollBox_indicatorV && XUI_ScrollBox_indicatorV[ 'css' ]( 'left', ( scrollBoxW - that.fontSize * 0.6 | 0 ) + 'px' );\r
@@ -320,16 +328,17 @@ function X_UI_ScrollBox_translate( that, x, y, opt_time, opt_easing, opt_release
                        [ 'css' ]({\r
                                height : ( indicatorH | 0 ) + 'px'\r
                        })\r
-                       [ 'animate' ](\r
-                       {\r
-                               y : scrollBoxH * that.scrollY / that.scrollYMax\r
-                       },\r
-                       {\r
-                               y : scrollBoxH * y / that.scrollYMax,\r
-                               opacity : 0.5\r
-                       },\r
-                       opt_time, opt_easing, opt_release\r
-               );\r
+                       [ 'animate' ]({\r
+                                       'from'        : {\r
+                                                       y       : scrollBoxH * that.scrollY / that.scrollYMax },\r
+                                       'to'          : {\r
+                                                       y       : scrollBoxH * y / that.scrollYMax,\r
+                                                       opacity : 0.5\r
+                                               },\r
+                                       'duration'    : opt_time,\r
+                                       'easing'      : opt_easing,\r
+                                       'lazyRelease' : opt_release\r
+                               });\r
        };\r
        if( that.hasHScroll && XUI_ScrollBox_indicatorH && XUI_ScrollBox_indicatorH.parent === that.xnode ){\r
                indicatorW = scrollBoxW * scrollBoxW / ( - that.scrollXMax + scrollBoxW );\r
@@ -338,16 +347,17 @@ function X_UI_ScrollBox_translate( that, x, y, opt_time, opt_easing, opt_release
                        [ 'css' ]({\r
                                width : ( indicatorW | 0 ) + 'px'\r
                        })\r
-                       [ 'animate' ](\r
-                       {\r
-                               x : scrollBoxW * that.scrollX / that.scrollXMax\r
-                       },\r
-                       {\r
-                               x : scrollBoxW * x / that.scrollXMax,\r
-                               opacity : 0.5\r
-                       },\r
-                       opt_time, opt_easing, opt_release\r
-               );\r
+                       [ 'animate' ]({\r
+                                       'from'        : {\r
+                                                       x       : scrollBoxW * that.scrollX / that.scrollXMax },\r
+                                       'to'          : {\r
+                                                       x       : scrollBoxW * x / that.scrollXMax,\r
+                                                       opacity : 0.5\r
+                                               },\r
+                                       'duration'    : opt_time,\r
+                                       'easing'      : opt_easing,\r
+                                       'lazyRelease' : opt_release\r
+                               });\r
        };\r
        \r
        that.scrollX   = x;\r