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

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


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

查看所有标签

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

Search User Interfaces

Search User Interfaces

Marti A. Hearst / Cambridge University Press / 2009-9-21 / USD 59.00

搜索引擎的本质是帮助用户更快、更方便、更有效地查找与获取所需信息。在不断改进搜索算法和提升性能(以技术为中心)的同时,关注用户的信息需求、搜寻行为、界面设计与交互模式是以用户为中心的一条并行发展思路。创新的搜索界面及其配套的交互机制对一项搜索服务的成功来说是至关重要的。Marti Hearst教授带来的这本新作《Search User Interfaces》即是后一条思路的研究成果,将信息检索与人......一起来看看 《Search User Interfaces》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

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

正则表达式在线测试