通过javascript获取到css的rotation的值

来源:互联网 发布:饥荒文件修改数据 编辑:程序博客网 时间:2024/06/16 01:03

原文地址: https://css-tricks.com/get-value-of-css-rotation-through-javascript/
一条来自Aditya的评论:
在javascript当中,能否有一种方法可以获取到元素的旋转角度?

这个看起来是个很合理的要求。所以,我们先写一段html

<div id="i-am-rotated">text</div>

接下来,利用css将它旋转一定角度。

#i-am-rotated {  -webkit-transform: rotate(30deg);   -moz-transform:    rotate(30deg);   -ms-transform:     rotate(30deg);   -o-transform:      rotate(30deg);  }

我们的目标是通过javascript,获取到数值为30的属性。通常情况下,我们获取以一个元素的css的属性值使用用这样的方法。 getComutedStyle() (只有现代的浏览器和IE9+才支持这个方法,老版本的IE仅支持 currentStyle())。我们现在利用 getComutedStyle() 方法尝试去获取样式。

顺便说一句,如果你先知道怎么去兼容两者,建议去看我之前写的博客。

var el = document.getElementById("i-am-rotated");var st = window.getComputedStyle(el, null);var tr = st.getPropertyValue("-webkit-transform") ||         st.getPropertyValue("-moz-transform") ||         st.getPropertyValue("-ms-transform") ||         st.getPropertyValue("-o-transform") ||         st.getPropertyValue("transform") ||         "Either no transform set, or browser doesn't do getComputedStyle";

你可能认为返回的值将会是“rotate(30deg)”然后,我们可以使用parseInt()进行类型转换得到”30”。但是,非常不幸的是——他将不起作用。因为,事实上,我们获取到的返回值是这样的

console.log(tr);// matrix(0.8660254037844387, 0.49999999999999994, -0.49999999999999994, 0.8660254037844387, 0, 0)

浏览器将CSS的旋转属性转化成了矩阵。我猜象它可能是,它可能是一个元素上面transform属性值的简化版。所以,我们改做点什么呢?
Nicolas Gallager研究过矩阵变化所对应的旋转变化。其本质是这样的

rotate(Xdeg) = matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);

我们现在仅仅需要一个可以转化的公式。我们需要得到 arcsin的值(就是sin的倒数,sin-1)。以确保它能转化成弧度。
首先,我们必须将开手头上面的数据分割成独立的矩阵值。

// UPDATE: below was causing errors sometimes...// var values = tr.split('(')[1].split(')')[0].split(',');// Replace with... (thanks Thierry)var values = tr.split('(')[1],    values = values.split(')')[0],    values = values.split(',');var a = values[0]; // 0.866025var b = values[1]; // 0.5var c = values[2]; // -0.5var d = values[3]; // 0.866025

我们都知道
sin(X) == 0.5 so asin(0.5) == radians 和 degrees == radians * 180/π.公式
所以:

var angle = Math.round(Math.asin(b) * (180/Math.PI));console.log(angle);

网友补充:
一位叫做Nicolas的网友做了一点改进,可以得出scale的属性值。

#complex-transform {  -webkit-transform: rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);   -moz-transform:    rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);   -ms-transform:     rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);   -o-transform:      rotate(30deg) scale(1.2) skew(10deg) translate(5px, 5px);  }
var el = document.getElementById("complex-transform");var st = window.getComputedStyle(el, null);var tr = st.getPropertyValue("-webkit-transform") ||         st.getPropertyValue("-moz-transform") ||         st.getPropertyValue("-ms-transform") ||         st.getPropertyValue("-o-transform") ||         st.getPropertyValue("transform") ||         "fail...";// With rotate(30deg)...// matrix(0.866025, 0.5, -0.5, 0.866025, 0px, 0px)console.log('Matrix: ' + tr);// rotation matrix - http://en.wikipedia.org/wiki/Rotation_matrixvar values = tr.split('(')[1];    values = values.split(')')[0];    values = values.split(',');var a = values[0];var b = values[1];var c = values[2];var d = values[3];var scale = Math.sqrt(a*a + b*b);// arc sin, convert from radians to degrees, round// DO NOT USE: see update belowvar sin = b/scale;var angle = Math.round(Math.asin(sin) * (180/Math.PI));// works!console.log('Rotate: ' + angle + 'deg');

大家都知道,在数学的象限里面。sin(30) = sin(150)。所以得出的角度不可靠。
不知道大家还记不记得这张图。只有利用tan。
这里写图片描述
最后改进,这样才能更精确的计算出角度。

var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));

至于源码,大家自己去访问博客原址。

原文的评论下面,还有很多精文。很不错。在此就不多说废话了。

自己的话:
其实我感觉tan也不可靠。270的时候 返回的是-90。这样的问题,在stackoverflow上面也有解决 但是 他在0 360时候是。是用判断解决问题。不是利用公式 这里再放一个好公式。当然,也是借鉴别人的!

var radians = Math.atan2(b, a);if ( radians < 0 ) {  radians += (2 * Math.PI);}var angle = Math.round( radians * (180/Math.PI));

第一次翻译外文,不足之处,请多包涵!

0 0
原创粉丝点击