如何混合css3转换属性而不覆盖(实时)?

时间:2013-11-23 20:05:05

标签: html css css3 transform

有没有办法在不重写的情况下组合(混合)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

这是一个糟糕的解决方案。

6 个答案:

答案 0 :(得分:9)

嗯......据我所知,你必须创建一个新类并以这种方式组合它们(用空格分隔):

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

答案 1 :(得分:7)

以下是使用Javascript解决问题的尝试:http://jsfiddle.net/eGDP7/

我在html上使用数据属性列出了我们要应用的转换类:

<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解析仅限于缩放(x,y),平移(x,y),以及使用度数或弧度值旋转
  • 它只适用于webkit供应商前缀

如果对任何人都有用,我可以整理一下并把它变成一个实用程序。

答案 2 :(得分:7)

我解决这个问题的方法是在我想要的那个周围添加一个包装类。例如,我有一个包装器,它的位置通过javascript设置,然后内部受到css动画的影响 - 两者都在转换属性上。

我知道添加DOM节点并不理想,但它绕过了脚本繁重的解决方案,让浏览器可以像往常一样优化动画和过渡。

答案 3 :(得分:4)

目前无法执行此操作,它一次只接受一个transform命令,无法按照您的喜好添加或减少。因此,您必须根据第一种和第二种类型添加或删除类,并为该元素编写自定义transform

使用像SASS或LESS这样的CSS预处理器语言可以使组合转换更容易,下面允许将任意数量的transition组合成一个,但需要告知要添加哪些(这是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);
}

Demo

目前唯一的方法是使用javascript,实际上是添加一个带变换的类,保存该类的变量'变换,删除类并对另一个类执行相同操作,然后组合这两个矩阵班级变革。 编辑:有关此方法的更多信息,请参阅brejep's javascript answer

答案 4 :(得分:2)

您可以使用矩阵函数代替旋转和缩放。

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

在给出的例子中,我相信以下内容会产生预期的结果:

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

有关矩阵计算的解释:

还有一些有用的工具可用于将这些矩阵计算为CSS,例如:

答案 5 :(得分:0)

您可以做的一件事是在JS中获取计算的变换样式并连接您的二次变换值:

<强> 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)';