http://shawphy.com/2011/01/transformation-matrix-in-front-end.html

前端开发中需要用到的变换矩阵

6条回复

想写写关于矩阵变换的博文已经想了很久了,今天看到 winter 写的一篇博客CSS3:transform与transition背后的数学原理,于是就促成了本文。注意,下面的演示内容需要现代浏览器支持。比如Chrome/Firefox/Opera。阅读器中无法看到演示。

矩阵是线性代数中的内容,在计算机图形学中就拿来做矩阵变换。在以前,对于前端工作来说,几乎用不到矩阵变换。然而,随着浏览器的进步,HTML5和CSS3的普及,对于前端可以操作的东西越来越多,于是,矩阵变换也出现在视野当中了。

矩阵变换,听起来是一个挺高级的东西,其实本质上只不过是把一系列简单的数学运算给包装一下,赋予一个比较华丽和高深的外表而已。如果你之前没有接触过矩阵运算,也不用慌,跳过下面矩阵公式,直接看每条后面的黑体字公式即可。这些公式仅仅涉及高中水平的加减运算和三角函数而已。除了最开始的时候我会搬出那个矩阵,之后的讨论我会避开矩阵的公式,直接用容易理解的方式阐述问题。

最早浏览器中支持的矩阵变换可能是在SVG的标准中。之后跟图形带点边的CSS 3以及HTML5的Canvas中也有了矩阵变换,当然强大的Flash以及Flex中也有变换矩阵。他们的基本原理都是一样的。目前2D的矩阵变换已经有不少浏览器支持了,而3D的变换还需时日。

说了半天矩阵变换,其实本质上来说,一个元素渲染后就可以得到一张位图,然后对这个位图上每一点进行变换,就可以得到新的一张位图,从而产生平移、缩放、旋转,切变以及镜像反射等效果了。

基本公式

目前不论是SVG也好,CSS 3也好,还是Canvas,2D的矩阵变换都提供了6个参数a b c d e f,其使用基本公式是这样的:

其中,x和y是元素最开始的坐标,x’ 和y’则是通过矩阵变换后得到新的坐标。
通过中间的那个3×3的变换矩阵,对原先的坐标施加变换,就能得到新的坐标了。

注意!a b c d e f几个参数的排列方式,是竖着排的,网上有不少文章排列方向有误。

根据矩阵乘法的运算法则,上面的矩阵式子可以化成下面的两个式子

x’=ax+cy+e
y’=bx+dy+f

也就是说,别看上面有那么一大坨的东西,本质上就是上面这两条简简单单的公式而已。之后的讨论中,我将围绕着上面的两行来讨论,而不再涉及矩阵的内容了。

平移

如果调用时提供参数matrix(1,0,0,1,tx,ty),即a=d=1,b=c=0,那么上面的式子就简化成

x’ = 1x+0y+tx = x+tx
y’ = 0x+1y+ty = y+ty

很容易看到,这里就是在原先x,y的基础上进行平移,变成x+tx,y+ty点而已。非常简单。如果数学上讲,tx和ty就好比是Δx和Δy。

x’ = x+Δx
y’ = y+Δy

CSS 3中的transform: translate(tx, ty);就等价于transform: matrix(1,0,0,1,tx,ty);注意,使用matrix的时候不需要单位,默认是px,而translate需要单位,可以是px、em之类的单位。

缩放和拉伸

如果调用时提供参数matrix(Sx,0,0,Sy,0,0),即a或d不等于1,比如a=Sx,d=Sy而b=c=e=f=0,于是公式简化成

x’ = Sx*x+0y+0 = Sx*x
y’ = 0x+Sy*y+0 = Sy*y

可以想到,这个操作,实际上是让x的坐标扩大Sx倍,而y的坐标扩大Sy倍。
这主要是用来让元素进行缩放效果的。如果Sx和Sy大于1,则是放大,而Sx和Sy小于1,就是缩小了,如果等于1,那就是保持原状了。并且,由于x方向和y方向是相互独立的,所以可以一个方向放大,另一个方向缩小。
上面的那个例子中,我设置的m和n都是0.5,于是图形长宽就各缩小了一半。另外,值得注意的是,他是以元素的中心作为缩放的基点的,而不是左上角。
CSS 3中的transform: scale(Sx, Sy);就等价于transform: matrix(Sx,0,0,Sy,0,0);

旋转

这里用到的就相对高级一些了,需要使用三角函数的一些知识了

如果调用时提供参数matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

x’ = x*cosθ-y*sinθ+0 = x*cosθ-y*sinθ
y’ = x*sinθ+y*cosθ+0 = x*sinθ+y*cosθ

由于计算机图形学中,通常向右为x轴正方向,向下为y轴正方向,所以这里的θ表示元素绕坐标原点顺时针旋转的角度。而这里的原点不是元素的左上角,而是元素的中心点。
上面的例子中,我把一个div顺时针旋转了37°,cos37°=0.8,sin37°=0.6,所以提供的矩阵的参数就是 matrix(0.8,0.6,-0.6,0.8,0,0)
CSS 3中,transform:rotate(37deg)就等价于我上面的那个变换了。注意CSS 3中的角度必须带单位 deg。好处是不用自己算sin和cos值了。

切变

切变,就是把一个元素往某一个方向倾斜一定的角度。传入的参数应当是matrix(1,tan(θy),tan(θx),1,0,0)

x’ = x+y*tan(θx)+0 = x+y*tan(θx)
y’ = x*tan(θy)+y+0 = x*tan(θy)+y

这里的θx和θy分别代表往x正方向和往y正方向倾斜的角度,两者是相互独立的。上面的例子中,我把元素往x方向倾斜了45°,因此他的tan(θx)=1
CSS 3中的transform: skew(θx, θy);就等价于transform: matrix(tan(θx),0,0,tan(θy),0,0); 如果使用skew的话,直接使用角度即可,但必须带单位deg,比如上面的例子用矩阵的话写成transform: matrix(1,0,1,1,0,0);等价于 transform: skew(45deg, 0);

镜像反射

镜像反射就是指元素对某一条直线做镜像对称。最基本的情况是可以对经过原点的某条直线进行反射。定义(ux,uy)为直线方向的单位向量。也就是说,如果直线方程是y=kx,那么ux=1/sqrt(1+k^2),uy=k/sqrt(1+k^2)

那么对这种镜像反射变化时传入的参数应当是
matrix(2*ux^2-1,2*ux*uy,2*ux*uy,2*uy^2-1,0,0)
于是最终的方程

x’ = (2*ux^2-1)*x+2*ux*uy*y
y’ = 2*ux*uy*x+(2*uy^2-1)*y

上面的例子中,就是对y=2x这条直线进行的镜像对称。CSS 3中目前没有简化的规则与之对应。

至于如何对一条不过原点的线对称,则需要设置原点所在的坐标了。由于默认情况下,原点坐标是这个元素的中心,如果改变了原点的坐标,就可以改变对称的直线,当然也可以改变前面所有效果的呈现方式,CSS 3中使用transform-origin方法修改坐标原点的位置。

最后,如果你想要玩的更High点,买本计算机图形学的书来看是不可避免的,这篇文章也仅仅是个皮毛而已。希望对你有所帮助。

扩展阅读

前端观察,你需要知道的CSS3 动画技术
维基百科中关于矩阵变换的条目
理解矩阵(1)
理解矩阵(2)
理解矩阵(3)
w3 文档,关于坐标系以及矩阵变换属性
w3 文档,SVG中的3D变换矩阵
w3 文档,CSS 3中的3D变换矩阵,基本跟上一条的差不多

本条目发布于 2011-01-01。属于 jQuery分类。

前端开发中需要用到的变换矩阵(2D游戏适用)相关推荐

  1. CSS3前端开发中需要用到的变换矩阵

    2019独角兽企业重金招聘Python工程师标准>>> 想写写关于矩阵变换的博文已经想了很久了,今天看到 winter 写的一篇博客CSS3:transform与transition ...

  2. 前端开发中的性能那点事

     前端开发中的性能那点事(一)巧用xdebug 前言: 在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,funct ...

  3. 前端开发中的Error以及异常捕获

    本文首发于公众号:符合预期的CoyPan 写在前面 在前端项目中,由于JavaScript本身是一个弱类型语言,加上浏览器环境的复杂性,网络问题等等,很容易发生错误.做好网页错误监控,不断优化代码,提 ...

  4. java backbone_[Java教程]移动前端开发中的Backbone之一:Backbone中的模型和集合

    [Java教程]移动前端开发中的Backbone之一:Backbone中的模型和集合 0 2015-09-24 17:00:04 当我们开发含有大量Javascript的web应用程序时,首先你需要做 ...

  5. 【repost】一探前端开发中的JS调试技巧

    有请提示:文中涉及较多Gif演示动画,移动端请尽量在Wifi环境中阅读 前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问 ...

  6. 初学者Web介绍一些前端开发中的基本概念用到的技术

    Web开发是比较费神的,需要掌握很多很多的东西,特别是从事前端开发的朋友,需要通十行才行.今天,本文向初学者介绍一些Web开发中的基本概念和用到的技术,从A到Z总共26项,每项对应一个概念或者技术. ...

  7. 熟悉html css,编写HTML和CSS的前端开发中不一定熟悉JavaScript

    原标题:编写HTML和CSS的前端开发中不一定熟悉JavaScript 作为前端开发人员,HTML.css.Java是必备的知识技能,但是现实工作工作中并非所有的前端都知道Java,根据外国一个网站的 ...

  8. 前端中什么是中台开发环境_Web前端开发中需要学习什么?会使用到哪些开发工具?...

    今天我们来谈谈Web和前端开发过程中需要学习什么?前端开发需要使用什么开发工具?也简单介绍前端开发前景和薪水.下面和千锋广州小编一起来看看吧! ​前端工程师的主要职责: 前端工程师在不同的公司有不同的 ...

  9. 前端开发中的调试技巧

    前端开发中的调试技巧 骨灰级调试大师Alert 那还是互联网刚刚起步的时代,网页前端还主要以内容展示为主,浏览器脚本还只能为页面提供非常简单的辅助功能的时候.那个时候,网页主要运行在以IE6为主的浏览 ...

最新文章

  1. [Cake] 1. CI中的Cake
  2. SQL基础学习总结:6(INSERT语句的相关使用方法)
  3. mysql类exadata功能_几类关系型数据库的数据解决方案
  4. 2 0 1 8 全球人工智能技术大会--邀请函
  5. python语言入门z-python3基础笔记(一)
  6. 平时优化SQL的集合
  7. Day 28: OpenShift的Eclipse集成
  8. 翻币问题pascal程序
  9. 【Android】SDDL刷机
  10. 方舟编译器服务器端Java怎么用_方舟编译器可以运行Hello World了!
  11. C和指针之函数之归以字符形式按顺序打印数字的每位数字(递归和非递归)
  12. 考勤信息管理系统 需求说明
  13. linux 命令查看块设备,系统运维|用 Linux blkid 命令查找块设备详情
  14. 8月全球搜索引擎市场:百度位居第四 份额大涨
  15. 万字长文讲解编码知识,看这文就够了!| 原力计划
  16. 贺利坚老师汇编课程33笔记:[bx+idata]对同长度字符串进行同步处理
  17. C#之判断Mysql数据库是否存在
  18. python写接口调用模型_基于Python开发的SWMM模型调用接口
  19. 形式语言与自动机总结笔记
  20. boxy 你用了吗??

热门文章

  1. 【c语言中的运算符】
  2. h5物体拖动_【点我解锁】11种网易爆款H5交互手势及案例
  3. chrome清除https状态
  4. Matlab传统神经网络函数:Newff的使用方法记录
  5. Python数据分析面试实战
  6. 盘点Python那些简单实用的第三方库
  7. js强制保留两位小数
  8. 边缘计算(二)——边缘计算的类型与用途
  9. 拼多多退款怎么设置?万顿思教育
  10. 因果推断——现代统计的思想飞跃