【问题标题】:canvas:how to complete translate,skew,rotate...in just one transform statement?画布:如何在一个变换语句中完成平移、倾斜、旋转……?
【发布时间】:2013-08-28 12:35:07
【问题描述】:

我最近几天在学习“变换”,现在我知道如何通过变换的 matirx 进行平移、旋转、倾斜、缩放。但是如果我想在一个转换语句中执行上述所有操作,我该怎么做?

ctx.transform(a,b,c,d,e,f);

当我们想通过变换旋转某些东西时,我们必须为每个参数 (a,b,c,d) 发布 4 个参数,所以,如果我想旋转和缩放,例如,旋转 30 度和缩放 (1.5,2 ),转换可以同时完成吗?那么(a,b,c,d)的值是多少?以及如何计算?

还有一个问题:变换有顺序吗?我的意思是如果我使用变换来旋转、缩放和平移,它们之间的顺序是什么?毕竟顺序很重要,'先翻译,再缩放'和'先缩放,再翻译',会得到不同的结果。

【问题讨论】:

    标签: javascript canvas transform


    【解决方案1】:

    这是由 context.transform(a,b,c,d,e,f) 完成的数学运算

    当你使用单个 context.transform 做多个操作时(translate+scale+rotate)

    • 首先完成翻译。
    • 接下来进行缩放和旋转(这些顺序无关紧要)。

    这是javascript形式的矩阵数学:

        // a=0, b=1, c=2, d=3, e=4, f=5
    
        // declare an array that will hold our transform math
        // this is the identity matrix (where no transforms exist)
        var matrix=[1,0,0,1,0,0];
    
        // for example, 
    
        // rotate 30 degrees clockwise from 0 degrees
        // note: 0 degrees extends rightward horizontally from the origin
        rotate(30*Math.PI/180);
    
        // scale by 1.5 in X and 2.0 in Y scales
        scale(1.5,2,0);
    
        // plug our transform array into the context
        context.transform(matrix[0],matrix[1],matrix[2],matrix[3],matrix[4],matrix[5]);
    
    
    
        // do the translate to the array 
        function translate(x,y){
            matrix[4] += matrix[0] * x + matrix[2] * y;
            matrix[5] += matrix[1] * x + matrix[3] * y;
        }
    
        // do the scale to the array
        function scale(x,y){
            matrix[0] *= x;
            matrix[1] *= x;
            matrix[2] *= y;
            matrix[3] *= y;    
        }
    
        // do the rotate to the array
        function rotate(radians){
            var cos = Math.cos(radians);
            var sin = Math.sin(radians);
            var m11 = matrix[0] * cos + matrix[2] * sin;
            var m12 = matrix[1] * cos + matrix[3] * sin;
            var m21 = -matrix[0] * sin + matrix[2] * cos;
            var m22 = -matrix[1] * sin + matrix[3] * cos;
            matrix[0] = m11;
            matrix[1] = m12;
            matrix[2] = m21;
            matrix[3] = m22;   
        }
    

    【讨论】:

    • 好,如果我知道这些,我可以深入理解转换。你能为我写一个“旋转30度并缩放(1.5,2)”的变换吗?谢谢
    • 感谢您的回复,如果我使用这些功能,您的代码让我知道,我可以控制转换的顺序,这是我的目标,谢谢。你能告诉我“倾斜”功能吗?原谅我,我的数学太弱了……
    • 倾斜变换:function skew(radiansX,radiansY){ var tanX=radiansX;//Math.tan(radiansX); var tanY=radiansY;//Math.tan(radiansY);变种矩阵0=矩阵[0]; var matrix1=matrix[1] matrix[0] += tanYmatrix[2];矩阵[1] += tanY矩阵[3];矩阵[2] += tanXmatrix0;矩阵[3] += tanXmatrix1; }
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      每个变换函数都使用 4*4 矩阵进行数学描述, 要执行超过 1 个函数,比如旋转和缩放,那么您需要将为每个函数创建的 4*4 矩阵相乘,

      变换函数的数学描述请参考http://www.w3.org/TR/css3-transforms/#Scale3dDefined>

      有关如何应用多个变换的详细信息,请参阅矩阵、向量和 matrix3d() http://dev.opera.com/articles/view/understanding-3d-transforms/中的部分

      根据您给出的顺序,您的转换有一个顺序 每个函数都没有任何优先级, 说 scale(10) translate(200) 与 ttranslate(200)scale(10) 不同,这很明显 矩阵乘法一般不是可交换的 AB≠BA

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-06
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多