CSS3 2D Transform Matrix

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

内容简介:© 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

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


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

查看所有标签

猜你喜欢:

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

MySQL必知必会

MySQL必知必会

[英] Ben Forta / 刘晓霞、钟鸣 / 人民邮电出版社 / 2009-1 / 39.00元

《MySQL必知必会》MySQL是世界上最受欢迎的数据库管理系统之一。书中从介绍简单的数据检索开始,逐步深入一些复杂的内容,包括联结的使用、子查询、正则表达式和基于全文本的搜索、存储过程、游标、触发器、表约束,等等。通过重点突出的章节,条理清晰、系统而扼要地讲述了读者应该掌握的知识,使他们不经意间立刻功力大增。一起来看看 《MySQL必知必会》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具