X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F06_XNodeCSS.js;h=77bb0675073318ccbf3cd0b574a2c41f46ba89d6;hb=d56e8cc1e13089eb6cbc9dcc6900d7f1828b93df;hp=9bcfdfd6319b9f8aa6079b2523b5ed4282089ff3;hpb=d5cd3943f09c2e3ca76ddb2959c911e6ff4a38d7;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/02_dom/06_XNodeCSS.js b/0.6.x/js/02_dom/06_XNodeCSS.js index 9bcfdfd..77bb067 100644 --- a/0.6.x/js/02_dom/06_XNodeCSS.js +++ b/0.6.x/js/02_dom/06_XNodeCSS.js @@ -278,6 +278,7 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ if( filterFix ){ v = X_Node_CSS_objToIEFilterText( that, filterFix, css ); + n = css.length; /* css が変更されている場合あり */ if( v ){ css[ ++n ] = 'filter:' + v; }; @@ -289,6 +290,7 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ if( 0 <= n ){ // cssText には完全なものを控えるが、戻すのは filter を抜いたもの that[ '_cssText' ] = css.join( ';' ); + //console.log( that[ '_cssText' ] ); if( skipFilter ){ --css.length; return css.join( ';' ); @@ -303,10 +305,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 +320,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; + p, id, v, num, vu, u, _v, ary, params, i, l, dir, + afterUpdate, impossible, color; for( p in obj ){ - if( X_EMPTY_OBJECT[ p ] ) continue; + //if( X_EMPTY_OBJECT[ p ] ) continue; if( !( id = test[ p ] ) ) continue; v = obj[ p ]; @@ -334,9 +336,10 @@ function X_Node_CSS_objToIEFilterText( that, opt_css, opt_cssList ){ filters[ ++n ] = v; break; case 2 : //'opacity' : - //if( v === 0 ){ - // opt_cssList && ( opt_cssList[ opt_cssList.length ] = 'visibility:hidden' ); - //} else + if( v === 0 ){ + console.log( '@opacity:0 ' + !!opt_cssList ); + opt_cssList && ( opt_cssList[ opt_cssList.length ] = 'visibility:hidden' ); + } else if( v < 1 ) filters[ ++n ] = 'alpha(opacity=' + ( v * 100 | 0 ) +')'; break; case 3 : //'boxShadow' : @@ -403,25 +406,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( ' ' ); + return filters.join( ' ' );//n !== -1 ? 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[ params[ 7 ] ] = dx + 'px'; // left or right + elm.style[ params[ 8 ] ] = dy + 'px'; // top or bottom + + //フィルターで回転と拡大縮小を加えます。 + 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, id; + + 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 +784,7 @@ function X_Node_cssText( v ){ }; /* - * ここでは HTMLElement のチ1ェックは行わない! + * ここでは HTMLElement のチ1ェックは行わない! <- 行う! * TODO * body に css attr がセットされた場合には X_ViewPort_baseFontSize をクリア * class, id, attr() の変更があった場合は、変更の適用の後、charSize を取得 @@ -689,12 +798,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' ]; @@ -739,11 +849,12 @@ X_Node_CSS_getCharSize = }) : X_UA_DOM.IE4 ? (function( that ){ - var font, vu, v, u, _v; + var font, vu, v, u, _v, elm; + 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 +866,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', '
X
' ); elm = document.all[ 'ie4charsize' ]; v = elm.offsetHeight;