web-dev-qa-db-ja.com

(リアルタイムで)オーバーライドせずにcss3変換プロパティを混合するにはどうすればよいですか?

オーバーライドせずにCSS変換プロパティを組み合わせる(ミックスする)方法はありますか?たとえば、回転とスケーリングを行いたいと思います。 http://jsfiddle.net/hyzhak/bmyN3/

html

<div class="item rotate-90 tiny-size">
    Hello World!
</div>

cSS

.rotate-90 {
    -webkit-transform: rotate(90deg);
}
.tiny-size {
    -webkit-transform: scale(0.25, 0.25);
}

PS

要素のビューを変換するための要素と単純なクラスがたくさんあります。そして、いくつかのクラスを追加および削除して、それらのビューを調整したいだけです。何百もの組み合わせになるため、すべてのクラスの組み合わせは機能しません。

また、リアルタイムでやりたいです。

変換の数は約5にすることができ、それぞれが約10の状態を保持できます。したがって、手でそれらのすべての組み合わせを説明するだけでおよそ

10*10*10*10*10 = 100000 cases

それは悪い解決策です。

26

これはJavascriptで問題を解決する試みです: http://jsfiddle.net/eGDP7/

適用する変換を含むクラスをリストするために、htmlのdata属性を使用しています。

<div class="compoundtransform" data-transformations="scaletrans2, rotatetrans1">Test subject</div>

私はクラスを繰り返し処理し、それらが表すCSSルールを見つけます。

function getCSSRulesForClass( selector ) {
    var sheets = document.styleSheets;
    var cssRules = [];
    for (var i = 0; i<sheets.length; ++i) {
        var sheet = sheets[i];
        if( !sheet.cssRules ) { continue; }
        for (var j = 0; j < sheet.cssRules.length; ++j ) {
            var rule = sheet.cssRules[j];
            if (rule.selectorText && rule.selectorText.split(',').indexOf(selector) !== -1) {
                var styles = rule.style;
                for( var k = 0; k<styles.length; ++k ) {
                    var style = styles[k];
                    cssRules.Push( { 
                        property: style,
                        value: styles[style]
                    } );
                }
            }
        }
    }
    return cssRules;
}

変換を見つけて、行列に適用します。

function convertTransformToMatrix( source, transformValue ) {
    var values = transformValue.split(") "); // split into array if multiple values
    var matrix = cloneObject( source );
    for ( var i = 0; i<values.length; ++i ) {
        var value = values[i];
        if( isRotate( value ) ) {
            var rotationValue = cssRotationToRadians( value );
            var cosValue = Math.cos( rotationValue );
            var sinValue = Math.sin( rotationValue );
            var a = matrix.a;
            var b = matrix.b;
            var c = matrix.c;
            var d = matrix.d;
            var tx = matrix.tx;
            var ty = matrix.ty;
            matrix.a = a*cosValue - b*sinValue;
            matrix.b = a*sinValue + b*cosValue;
            matrix.c = c*cosValue - d*sinValue;
            matrix.d = c*sinValue + d*cosValue;
            matrix.tx = tx*cosValue - ty*sinValue;
            matrix.ty = tx*sinValue + ty*cosValue;
        } else if ( isScale( value ) ) {
            var scale = cssScaleToObject( value );
            matrix.a *= scale.x;
            matrix.b *= scale.y;
            matrix.c *= scale.x;
            matrix.d *= scale.y;
            matrix.tx *= scale.x;
            matrix.ty *= scale.y;
        } else if ( isTranslate( value ) ) {
            var translate = cssTranslateToObject( value );
            matrix.tx += translate.x;
            matrix.ty += translate.y;
        }
    }
    return matrix;
}

そして最後に、そのマトリックスを変換としてノードに適用します。

現在:

  • コードは少し乱雑です
  • CSS解析は、scale(x、y)、translate(x、y)に制限され、次数またはラジアン値で回転します
  • そしてそれはwebkitベンダープレフィックスでのみ機能します

私はそれを片付けて、誰かに役立つ場合はユーティリティに変えるかもしれません。

7
BrettJephson

うーん...私が知る限り、新しいクラスを作成して、このように(スペースで区切って)結合する必要があります。

-webkit-transform: rotate(90deg) scale(0.25, 0.25);
10
m59

この問題を回避する方法は、必要なラッパークラスを追加することです。たとえば、JavaScriptを介して位置が設定されているラッパーと、cssアニメーションの影響を受ける内部-両方が変換プロパティにあります。

DOMノードの追加は理想的ではありませんが、スクリプトを多用するソリューションを回避し、ブラウザーが通常どおりアニメーションと遷移を最適化できるようにします。

7

現在、これを行う方法はありません。transformに対して一度に1つのコマンドしか受け入れず、希望するように加算または減算することはできません。したがって、最初と2番目のタイプに応じてクラスを追加または削除し、その要素のカスタムtransformを記述する必要があります

SASSやLESSなどのCSSプリプロセッサ言語を使用すると、トランジションを簡単に組み合わせることができます。以下を使用すると、任意の数のtransitionsを1つに組み合わせることができますが、追加するものを通知する必要があります(これはSCSSです)。

.item {
  width:500px;
  height:500px;
  font-size:150px;
  background:blue;
}

$firstTransform: rotate(90deg);
$secondTransform: scale(0.25, 0.25);

@mixin transform($transform...) {
  -webkit-transform: $transform;
     -moz-transform: $transform;
      -ms-transform: $transform;
       -o-transform: $transform;
          transform: $transform;
}
.rotate-90 {
  @include transform($firstTransform);
}
.tiny-size {
  @include transform($secondTransform);
}
.both {
  @include  transform($firstTransform $secondTransform);
}

デモ

実際にそれを行う唯一の方法は、JavaScriptを使用することです。基本的には、変換を含むクラスを追加し、そのクラスの変換の変数を保存し、クラスを削除して、別のクラスで同じことを行い、クラスの2つの行列を結合します。 '変換します。 EDIT:このアプローチの詳細については brejepのJavaScriptの回答 を参照してください

4
Zach Saucier

回転とスケーリングの代わりに、行列関数を使用できます。

transform: matrix(a, b, c, d, tx, ty);

与えられた例では、次のようにすると望ましい結果が得られると思います。

transform: matrix(0,-0.25,0.25,0,0,0);

行列計算の説明について:

また、これらの行列をCSSとして計算するための便利なツールがいくつかあります。

2
BrettJephson

あなたができることの1つは、JSで計算された変換スタイルを取得し、2次変換値を連結することです。

[〜#〜] html [〜#〜]

<div class="rotate-scale"></div>

[〜#〜] css [〜#〜]

.rotate-scale {
   transform: rotate(90deg);
}

[〜#〜] js [〜#〜]

var el = document.querySelector('.rotate-scale'),
    // rotation will get the transform value declared in css
    rotation = window.getComputedStyle(el).getPropertyValue('transform');

el.style.transform = rotation + 'scale(0.25, 0.25)';
0
Taylor Plante