X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F06_XNodeCSS.js;h=77bb0675073318ccbf3cd0b574a2c41f46ba89d6;hb=HEAD;hp=a951a50c9e2c10493c20470cc236dd2e21f5fc5e;hpb=f74335422a0ae2d66e3ce9bfa03f0c77a107e8d1;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 a951a50..77bb067 100644 --- a/0.6.x/js/02_dom/06_XNodeCSS.js +++ b/0.6.x/js/02_dom/06_XNodeCSS.js @@ -246,7 +246,7 @@ function X_Node_CSS_parseColor( x ){ function X_Node_CSS_objToCssText( that, skipFilter ){ var obj = that[ '_css' ], - plain = X_EMPTY_OBJECT, + //plain = X_EMPTY_OBJECT, css = [], n = -1, p, v, specialFix, filterFix; @@ -260,7 +260,7 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ for( p in obj ){ // object の拡張に備えて plain なオブジェクトを用意し、そのメンバーと一致するものは処理の対象外。 - if( plain[ p ] ) continue; + //if( plain[ p ] ) continue; v = obj[ p ]; @@ -277,8 +277,11 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ }; if( filterFix ){ - v = X_Node_CSS_objToIEFilterText( that, filterFix ); - if( v ) css[ ++n ] = 'filter:' + v; + v = X_Node_CSS_objToIEFilterText( that, filterFix, css ); + n = css.length; /* css が変更されている場合あり */ + if( v ){ + css[ ++n ] = 'filter:' + v; + }; skipFilter = skipFilter && v; } else { skipFilter = false; @@ -287,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( ';' ); @@ -301,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 { @@ -312,15 +317,16 @@ X_Node_CSS_FILTER_FIX_PROPS = } : null; -function X_Node_CSS_objToIEFilterText( that, opt_css ){ +function X_Node_CSS_objToIEFilterText( that, opt_css, opt_cssList ){ var obj = opt_css || that[ '_css' ], test = X_Node_CSS_FILTER_FIX_PROPS, 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 ]; @@ -330,7 +336,11 @@ function X_Node_CSS_objToIEFilterText( that, opt_css ){ filters[ ++n ] = v; break; case 2 : //'opacity' : - if( v !== 1 ) filters[ ++n ] = 'alpha(opacity=' + ( v * 100 | 0 ) +')'; + 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' : // TODO カンマ区切りの複数指定 @@ -396,25 +406,131 @@ function X_Node_CSS_objToIEFilterText( that, opt_css ){ 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; @@ -526,11 +642,11 @@ function X_Node_css( nameOrObj /* value */ ){ // setter:object if( X_Type_isObject( nameOrObj ) ){ if( !css ) css = this[ '_css' ] = {}; - plain = X_EMPTY_OBJECT; + //plain = X_EMPTY_OBJECT; camelize = X_Node_CSS_camelize; flags = this[ '_flags' ]; for( p in nameOrObj ){ - if( plain[ p ] ) continue; + //if( plain[ p ] ) continue; name = camelize( p ); v = nameOrObj[ p ]; if( css[ name ] === v ) continue; @@ -584,6 +700,7 @@ function X_Node_CSS_setStyle( css, flags, name, newValue ){ return flags; case 'opacity' : + flags |= X_NodeFlags_IE8_OPACITY_FIX; // すでに visibility:hidden で invisible if( flags & X_NodeFlags_STYLE_IS_INVISIBLE && css[ 'visibility' ] === 'hidden' ) return flags; newValue == 0 ? // 0 or "0" @@ -667,7 +784,7 @@ function X_Node_cssText( v ){ }; /* - * ここでは HTMLElement のチ1ェックは行わない! + * ここでは HTMLElement のチ1ェックは行わない! <- 行う! * TODO * body に css attr がセットされた場合には X_ViewPort_baseFontSize をクリア * class, id, attr() の変更があった場合は、変更の適用の後、charSize を取得 @@ -681,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' ]; @@ -731,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 ]; @@ -747,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; @@ -828,7 +947,7 @@ X[ 'CSS' ] = { for( j = vendors.length; j; ){ v = vendors[ --j ]; if( testStyle[ v + prop ] !== undefined ){ - if( v === 'ms' && !( 10 <= X_UA[ 'IEHost' ] ) ) v = 'Ms';// for ie9, 但し ie11 のieには不要 + if( v === 'ms'/* && !( 10 <= X_UA[ 'IEHost' ] )*/ ) v = 'Ms';// for ie9, 但し ie11 のieには不要 if( v === 'o' ) v = 'O';//for opera12 X_Node_CSS_VENDER_PREFIX[ search ] = v + prop; break;