【问题标题】:How to mix css3 transform properties without overriding (in realtime)?如何在不覆盖(实时)的情况下混合css3转换属性?
【发布时间】:2013-12-08 15:42:07
【问题描述】:

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

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

【问题讨论】:

  • 你有什么问题?你能试着描述一下实际的问题吗
  • @1977 如何在不覆盖的情况下混合 css3 转换
  • 别忘了点击接受你最喜欢的答案!
  • Css 变量是可行的方法。

标签: html css transform


【解决方案1】:

您可以做的一件事是在 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)';

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 包装可能是最好的选择。
    【解决方案3】:

    目前没有办法做到这一点,它一次只接受一个transform 的命令,不能像你想要的那样加减。因此,您必须根据第一种和第二种类型添加或删除一个类,并为该元素编写一个自定义 transform

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

    【讨论】:

    • 好的,如果你有 5-10 个状态的 5 种转换呢?我展示了简单的案例,只是为了描述案例而不是显示转换次数
    • @EugeneKrevenets 刚刚更新了 SASS 解决方案以接受任意数量的参数。至于实际的加减变换,等我有空的时候再研究一下矩阵数学
    • 在我的情况下,它会导致 100k 组合的转换。所以它没有帮助
    • @EugeneKrevenets 我确实意识到了这一点。我正在尝试提供 CSS 必须提供的最佳解决方案,您想要的根本不可能。正如我提到的,当我有更多时间时,我会尝试制定一个 js 解决方案
    • 我真的很想知道你的解决方案,所以如果你要做任何有效的实验,请与我们分享。 :)
    【解决方案4】:

    这里尝试用 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 解析仅限于 scale(x,y)、translate(x,y) 和旋转角度或弧度值
    • 它只适用于 webkit 供应商前缀

    如果对任何人有用,我可能会将其整理并变成实用程序。

    【讨论】:

    • 一个完整的实用程序真的很棒。我不是专业人士,但我很乐意尽我所能帮助您
    • 我已将 javascript 实用程序添加到 github:github.com/brejep/additive-transform-js。目前,它适用于 2D 变换函数 - rotate、scale、scaleX、scaleY、translate、translateX、translateY、skew、skewX 和 skewY。
    • 您能否在上述内容的基础上编制一份需要改进的综合清单?
    • Zeaklous,我会将它需要的改进添加到 github 的问题部分。它可以做的改进包括:使其适用于 3D 变换函数并修复 translate 函数,使其适用于 w3c 规范中的所有值(%、em 等),而不仅仅是像素值。
    • 但是getCSSRulesForClass() 函数已经是一个很好的解决方案,我认为cssText 也可以做同样的事情,因为内联CSS 的优先级高于cssRules。跨度>
    【解决方案5】:

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

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

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

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

    关于矩阵计算的解释:

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

    【讨论】:

    • 是的。谢谢!我知道如何使用线性矩阵,但是 - 我有这样一种情况,设计师将更新有关转换的信息,而不是我 - 他更喜欢为每种转换调整 CSS 参数。
    • 很公平。我不确定有没有办法让设计师了解这些东西。 :)
    • 重读一下,我明白你的意思了。我认为 CSS 中的任何变换实际上都是在描述一个矩阵,即使您只是使用缩放、倾斜或旋转功能。所以如果你缩放(0.5,0.5),你实际上是在对浏览器矩阵说(0.5,0,0,0.5,0,0)。所以任何旋转都将被覆盖。因为 CSS 都是关于样式相互覆盖的,这不能仅在 CSS 中解决。所以预处理器或 Javascript 只是可能性。我对 javascript 解决方案的尝试很快就会出现......
    【解决方案6】:

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

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

    【讨论】:

    • AFAIK 也是唯一的方法。注意:不要使用,
    • 我希望还有其他方法。因为我有很多带有转换的简单类,它们的所有组合的总和将是一个非常大的数字
    • 是的,如果可以的话,您肯定想尝试 SASS 或 LESS(请参阅 Zeaklous 的回答)。由于许多原因,这些脚本非常棒。 @EugeneKrevenets
    • @m59 是的,我已经在使用 SASS - 但我需要实时更新类。所以这与预处理无关
    猜你喜欢
    • 2018-02-27
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多