为变换创建一个跨浏览器混合:旋转

Posted

技术标签:

【中文标题】为变换创建一个跨浏览器混合:旋转【英文标题】:Create a cross-browser mixin for transform: rotate 【发布时间】:2011-08-05 21:13:22 【问题描述】:

我想为 sass 创建一个 mixin,它将对指定元素应用旋转。 mixin 应该采用一个参数,用于应用的旋转度数。

从 css3please.com,我找到了一种使用 CSS 实现此功能的跨浏览器方法:

.box_rotate 
     -moz-transform: rotate(7.5deg);  /* FF3.5+ */
       -o-transform: rotate(7.5deg);  /* Opera 10.5 */
  -webkit-transform: rotate(7.5deg);  /* Saf3.1+, Chrome */
      -ms-transform: rotate(7.5deg);  /* IE9 */
          transform: rotate(7.5deg);  
             filter: progid:DXImageTransform.Microsoft.Matrix(/* IE6–IE9  */
                     M11=0.9914448613738104, M12=-0.13052619222005157,M21=0.13052619222005157, M22=0.9914448613738104, sizingMethod='auto expand');
               zoom: 1;

除了讨厌的 IE 矩阵表示法之外,这一切都非常容易制作 mixin。有人对使用 sass、javascript 或两者的组合将度数转换为 IE 矩阵转换的方法有任何建议吗?

【问题讨论】:

如果有人感兴趣,我写了 mixin,它托管在这里:github.com/adambom/CSS3-Please-for-SASS 我所知道的使用 IE 的过滤器/矩阵变换的最大问题是,当一个盒子被旋转时,它不会围绕盒子的中心旋转。想象旋转盒子,绘制一个包含旋转盒子的最小矩形,然后将该容器放置在盒子原来的位置。这产生了这些解决方案(截至 2012 年 10 月 31 日)都没有考虑的偏移量。如果该语句没有意义,请这样想:如果您仅使用 IE 中的矩阵在 html 正文的开头旋转了一个框,则旋转后的框将完全可见。在其他浏览器中,它会被剪裁。 【参考方案1】:

你去吧:

SASS:

@mixin rotate( $degrees )
  -webkit-transform: rotate(#$degreesdeg)
  -moz-transform: rotate(#$degreesdeg)
  -ms-transform: rotate(#$degreesdeg)
  -o-transform: rotate(#$degreesdeg)
  transform: rotate(#$degreesdeg)

  filter:  progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=#cos($degrees), M12=-#sin($degrees), M21=#sin($degrees), M22=#cos($degrees))
  -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=#cos($degrees), M12=-#sin($degrees), M21=#sin($degrees), M22=#cos($degrees))"
  zoom: 1

SCSS:

@mixin rotate( $degrees ) 
  -webkit-transform: rotate(#$degreesdeg);
  -moz-transform: rotate(#$degreesdeg);
  -ms-transform: rotate(#$degreesdeg);
  -o-transform: rotate(#$degreesdeg);
  transform: rotate(#$degreesdeg);

  filter:  progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=#cos($degrees), M12=-#sin($degrees), M21=#sin($degrees), M22=#cos($degrees));
  -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=#cos($degrees), M12=-#sin($degrees), M21=#sin($degrees), M22=#cos($degrees))";
  zoom: 1;
 

用法:

@include rotate( 24 )

或者您可以简单地使用指南针,让您的生活更轻松:P

【讨论】:

它的前缀声明应该是 rotate(#$degreesdeg);但感谢 IE 声明 :) 还有一点需要注意,罗盘的 sin 和 cos 函数需要弧度,而不是度数,所以前缀 $rad : $deg * pi() / 180; 并使用 $rad 表示 cos 和 sin 函数对我有用.【参考方案2】:

rotation matrix 定义为

[[cos(A), -sin(A)],
 [sin(A),  cos(A)]]

A 是角度。 IE矩阵中的M11是第一行的第一个元素; M12: 第一行的第二个元素等

JavaScript Math.sinMath.cos 对弧度进行操作,因此您必须将度数转换为弧度

radians = degrees * Math.PI / 180

把这些放在一起,我们得到了这个函数:

function rotationMatrix(degrees) 
  var A = degrees * Math.PI / 180;
  return [[Math.cos(A), -Math.sin(A)], [Math.sin(A),  Math.cos(A)]]

例子:

rotationMatrix(10) 
// => [[0.984807753012208, -0.17364817766693033], 
//     [0.17364817766693033, 0.984807753012208]]

【讨论】:

通常您会将问题的最佳答案标记为您接受的答案。不是第一个,但是如果您认为@lbdremy 的答案是最好的! 我只需要算法。无论如何,我最终还是用 sass 编写了这个函数。【参考方案3】:

此功能允许将度数转换为 IE 矩阵变换。

//deg input defines the requested angle of rotation.
function degreeToIEMatrix(deg)   
    var deg2radians = Math.PI * 2 / 360;
    var rad = deg * deg2radians ;
    var costheta = Math.cos(rad);
    var sintheta = Math.sin(rad);

    var M11 = costheta;
    var M12 = -sintheta;
    var M21 = sintheta;
    var M22 = costheta;

你会发现更多信息here。

【讨论】:

不鼓励使用隐式全局变量。 函数中的每个变量定义都会创建一个全局变量。您需要使用var 来创建局部变量。 我现在明白你为什么说“隐式”了。谢谢@adamse。有关范围的更多信息rx4ajax-jscore.com/ecmacore/more/scope.html【参考方案4】:

这是一个适合在 javascript 控制台中使用的 @Remy 代码版本。只需将其粘贴到您的控制台,然后尝试 makeIErotate(270),它就会吐出跨浏览器样式,准备好粘贴到您的 CSS 文件中。

注意:IE 中的抗锯齿很难看,除非你有纯色背景色——即使那样它也可能很模糊。更多here。

function makeIErotate(deg)     
    var deg2radians = Math.PI * 2 / 360;
    var rad = deg * deg2radians ;
    var costheta = Math.cos(rad);
    var sintheta = Math.sin(rad);
    return "-moz-transform: rotate(" + deg + "deg);\n\
            -o-transform: rotate(" + deg + "deg);\n\
            -webkit-transform: rotate(" + deg + "deg);\n\
            -ms-transform: rotate(" + deg + "deg);\n\
            transform: rotate(" + deg + "deg);\n\
            filter: progid:DXImageTransform.Microsoft.Matrix(\n\
                    M11=" + costheta + ",\n\
                    M12=" + -sintheta + ",\n\
                    M21=" + sintheta + ",\n\
                    M22=" + costheta + ", sizingMethod='auto expand');";

【讨论】:

【参考方案5】:

要使用mixin,你应该使用

@include rotate(24)

【讨论】:

RobinH 的答案是正确的。如果您正在使用 compass(并且您应该使用),只需键入: .yourbox @include rotate(-90deg); 让 compass 完成所有艰苦的工作并保持代码干净 =)

以上是关于为变换创建一个跨浏览器混合:旋转的主要内容,如果未能解决你的问题,请参考以下文章

CSS 跨浏览器问题 - 旋转在 Safari、Ipad 和 Iphone 上不起作用

一个简单、高性能和跨浏览器的jQuery旋转/转盘插件,用于由Animate.css提供支持的文本短语。

创建一个跨浏览器图标 webfont

SVG 变换原点 CSS 动画 – Firefox 错误

使用数字键盘但没有箭头按钮的跨浏览器数字输入

CSS3旋转替代?