通过javascript获取到css的rotation的值

原文地址: 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.866025
var b = values[1]; // 0.5
var c = values[2]; // -0.5
var 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_matrix

var 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 below
var 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));

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值