想写写关于矩阵变换的博文已经想了很久了,今天看到 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
也就是说,别看上面有那么一大坨的东西,本质上就是上面这两条简简单单的公式而已。之后的讨论中,我将围绕着上面的两行来讨论,而不再涉及矩阵的内容了。
平移
原始位置
平移120px, 50px后
如果调用时提供参数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之类的单位。
缩放和拉伸
原始大小
长宽放大1.5倍
如果调用时提供参数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);
旋转
原始方向
旋转37°
这里用到的就相对高级一些了,需要使用三角函数的一些知识了
如果调用时提供参数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值了。
切变
x方向倾斜45°
切变,就是把一个元素往某一个方向倾斜一定的角度。传入的参数应当是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点,买本计算机图形学的书来看是不可避免的,这篇文章也仅仅是个皮毛而已。希望对你有所帮助。

公众号网页更新缓存,这玩意儿,说简单也简单,说复杂也够你喝一壶的。你辛辛苦苦更新了公众号文章,结果用户打开还是老版本,这滋味,谁受得了?这篇文章,咱就来扒一扒这背后的弯弯绕绕,以及如何优雅地解决这个问题。读完之后,你就能轻松应对各种缓存难题,让你的用户始终体验到最新鲜的内容。先说点基础的。网页缓存,说白了就是浏览器或者服务器为了提高访问速度,把一些静态资源(比如图片、CSS、JS)或者页面内容存储起来。下次访问时,直接从缓存里取,不用再重新下载,速度自然快。但这玩意儿,也是个双刃剑。新版本上线,

本文展示了使用CSS为网页中添加有效的PNG边框。 它认为,与JavaScript或库相比,CSS提供了出色的性能,详细介绍了如何调整边界宽度,样式和颜色以获得微妙或突出的效果

本文讨论了使用HTML5表单验证属性,例如必需的,图案,最小,最大和长度限制,以直接在浏览器中验证用户输入。

本文讨论了html< datalist>元素,通过提供自动完整建议,改善用户体验并减少错误来增强表格。Character计数:159

本文讨论了HTML< Progress>元素,其目的,样式和与< meter>元素。主要重点是使用< progress>为了完成任务和LT;仪表>对于stati

本文讨论了HTML< meter>元素,用于在一个范围内显示标量或分数值及其在Web开发中的常见应用。它区分了< meter>从< progress>和前

本文解释了HTML5< time>语义日期/时间表示的元素。 它强调了DateTime属性对机器可读性(ISO 8601格式)的重要性,并在人类可读文本旁边,增强Accessibilit


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3汉化版
中文版,非常好用