CSS3 2D Transform Matrix

栏目: CSS · 发布时间: 7年前

内容简介:© Young 2019-04-29 17:17Welcome to My给自己出了一道题如下:

© Young 2019-04-29 17:17

Welcome to My GitHub

给自己出了一道题如下:

题目

在某个大矩形中心有一个 黄色 的矩形,对该黄色矩形进行一系列 transform 变换得到灰色矩形;

以大矩形中心为 坐标原点 ,屏幕水平向左为 X 轴正方向 ,屏幕垂直向上为 Y 轴正方向 ,黄色矩形初始位置中心在坐标原点,根据其宽高可以得到其初始位置四个顶点的坐标 initPoints

那么求黄色矩形经过一系列变换后新的顶点坐标。

CSS3 2D Transform Matrix

在线地址: https://newbieyoung.github.io/CSS_learn/transform3.html

解答

CSS3 2D Transform Matrix

其实不管 CSS3 transform 属性 有多复杂,都是可以通过 getComputedStyle 直接获得最终变换矩阵的,具体方法实现如下:

//获得transform属性对应的矩阵形式
function getTransformMatrix(transform){
    var $div = document.createElement('div');
    $div.style.visibility = 'hidden';
    $div.style.position = 'fixed';


    //处理transform属性的兼容性
    var transformProperty = 'transform';
    if('transform' in $div.style){
        transformProperty='transform'
    } else if( 'WebkitTransform' in $div.style ){
        transformProperty='webkitTransform'
    } else if('MozTransform' in $div.style){
        transformProperty='MozTransform'
    } else if('OTransform' in $div.style){
        transformProperty='OTransform'
    }


    $div.style[transformProperty] = transform;
    document.body.appendChild($div);


    var style = window.getComputedStyle($div);
    var matrix = style[transformProperty];


    document.body.removeChild($div);


    return matrix;
}

通过 getTransformMatrix 函数可以获得以下形式的变换矩阵:

matrix(a, b, c, d, e, f);


matrix(0.430963, 1.01542, -0.234879, 1.76697, 5, 40)

转换为三阶矩阵:

[a, c, e,
 b, d, f,
 0, 0, 1];

不知道大家想过没有,明明是 2D 变换,转换为 三阶 矩阵干啥?

其实这里是引入了一个 齐次坐标 的概念,用 N+1 维的向量来表示 N 维向量;

比如在 2D 坐标系中某个点 (x, y) 可以在逻辑上表示为 (x*w, y*w, w)w 即为新增的那个量。

引入齐次坐标的好处在于可以把 缩放旋转平移 等变换都统一转换成矩阵乘法的形式,这样不管进行多少次变换,都可以表示成矩阵连乘的形式了。

如果某个 2D 坐标系中点为 (x, y) ,转换为齐次坐标 (x, y, 1) ,那么经过上述变换后的新坐标为 (nx, ny, nz)

nx = a * x + c * y + 1 * e;
ny = b * x + d * y + 1 * f;
nz = 0 + 0 + 1;

再把齐次坐标还原,最终坐标为 (nx, ny)

具体方法实现如下:

//计算矩阵变换后的坐标点
function getMatrixPoints(p,matrix){
    var mat = matrixAnalyze(matrix);


    // var mat3 = [mat[0],mat[2],mat[4],
    //             mat[1],mat[3],mat[5],
    //             0,0,1];


    // var mat3 = [a,c,e,
    //             b,d,f,
    //             0,0,1];


    // var newX = a * x + c * y + 1 * e;
    // var newY = b * x + d * y + 1 * f;
    // var newZ = 0 + 0 +1;


    //计算变换后点坐标
    var newX = mat[0] * p.x + mat[2] * p.y + 1 * mat[4];
    var newY = mat[1] * p.x + mat[3] * p.y + 1 * mat[5];
    var newZ = 0 + 0 +1;


    return {x:newX/newZ,y:newY/newZ};
}

已知初始坐标 initPoints 和变换矩阵 matrix 相乘即可得到 matrixPoints ,到这里我以为这个题目已经解完了;

直到我尝试着在大矩形中用 红色 直线把计算得到的 matrixPoints 连起来才发现: 新坐标连接得到的图形和 CSS3 transform 变换得到灰色图形并不重合

这也就意味着 上述计算过程有问题

在走了不少弯路之后我才意识到一个问题: CSS3 2D transform 坐标系和题目中设定的坐标系的 Y 轴正方向是相反的

题目中设置的坐标系 Y 轴正方向是屏幕垂直向上而 CSS3 2D transform 坐标系的 Y 轴正方向是屏幕垂直向下。

因此在计算新坐标之前,需要对 getComputedStyle 得到的变换矩阵进行 镜像变换 ,从而转换为题目中设定坐标系的变换矩阵,也就是示例中 fixedMatrix ,最后计算的新坐标为 fixedPoints

蓝色 直线绘制出来就可以看到和灰色图形完全重合了。

总结

聊矩阵不聊坐标系都是耍流氓!

此外 张鑫旭 大神 2012 年的这篇文章 理解CSS3 transform中的Matrix(矩阵) 应该是有比较大问题的。

CSS3 2D Transform Matrix

文中多次出现 方向不明、坐标轴错误 的坐标系,如果有看到建议改下。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

操作系统概念(第六版)

操作系统概念(第六版)

(美)西尔伯斯查兹 / 郑扣根 / 高等教育出版社 / 2005-11 / 55.00元

《操作系统概念》(第6版翻译版)是讨论了操作系统中的基本概念和算法,并对大量实例(如Linux系统)进行了研究。全书内容共分七部分。第一部分概要解释了操作系统是什么、做什么、是怎样设计与构造的,也解释了操作系统概念是如何发展起来的,操作系统的公共特性是什么。第二部分进程管理描述了作为现代操作系统核心的进程以及并发的概念。第三部分存储管理描述了存储管理的经典结构与算法以及不同的存储管理方案。第四部分......一起来看看 《操作系统概念(第六版)》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具