Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

transform 中倾斜(skew)的概念

  在transform中,比较常用的几种变换有平移(translation)、缩放(scale)以及旋转(rotation),而倾斜(skew)则不太常用。因为倾斜的概念不太贴近现实,正常也不会用到。而且有些资料中把“skew”翻译成了“扭曲”,看得我整个脸都扭曲了。
  比起平移、缩放、旋转,倾斜有一个与众不同的地方。前三者在变换后向量之间的夹角是不变的,比如一个矩形,无论做多少次平移、缩放、旋转,它依然是矩形。平移和旋转本身不会改变图像的形状,而缩放如果只针对某一条轴的话,那么原来是正方形的图像就可能变成长方形,但无论如何它们依然是矩形。
  实际上这前三种变换都是保持着轴的垂直,比如有这么一个2D变换矩阵
    
ab
cd

  其中如果向量vec2(a,b)vec2(c,d)在坐标系平面内互相垂直的话,说明这个变换矩阵中不包含任何倾斜变换。当然,二维我们直接说“垂直”是很方便的,如果高维的话“垂直”就不好定义,于是我们使用它们的内积来描述。
    无倾斜:dot(vec,vec,...)==0
  这里我们对向量归一化之后再做内积来计算它们的夹角:
    α=acos(dot(normalize(vec2(a,b)),normalize(vec2(c,d))))
  实际上CSS3的transform中使用的skew修改的正是这两条向量的夹角。其实skew可以描述为这样的矩阵:
    skew(m deg,n deg)=
1tan(n)
tan(m)1

  如果把矩阵的两行看作是两个向量v1v2的话,skew的行为就是将第v1y坐标设置到一个值上,使得v1和X轴的夹角呈n度;将第v2x坐标设置到一个值上,使得v2和Y轴的夹角呈m度。如果同时设置mn,并且保持两条轴垂直的话实际上也可以得到旋转的效果,如果再使用scale还原缩放就可以模拟出和rotate一样的效果。不过在边界情况下矩阵可能会出奇异值,无法正常使用。
<style>
div {
  position:absolute;
  top:200px;left:200px;
  width:100px; height:100px;
  background:red; 
  transform-origin:0px 0px;
}
</style>
<div id="div"></div>
<script>
var i=-90;
var sqrt=Math.sqrt,π=Math.PI,tan=Math.tan;
setInterval(function(){
  i++;
  if(i>=270)i-=360;
  var r=tan(i/180*π);
  var s=1/sqrt(r*r+1);
  if(i<90)s*=-1;
  div.style.transform=[
    "skew("+(-i)+"deg,"+i+"deg)",
    "scale("+s+","+s+")"
  ].join(" ");
  console.log(i,div.style.transform);
},16);
</script>
  嘛,总之它也是个线性变化,不要把它和扭曲的概念混淆了,扭曲是比这个复杂的多的东西。另外,我不太建议在不必要情况下使用这个,因为它离现实太远了,反正目前我在脑子里模拟一个skew的运动模型还是非常吃力。如果真需要3D变换的话直接使用3D变换相关的方法就好了,完全不需要这东西。
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^