canvas:how to complete translate,skew,rotate…in just one transform statement?

為{幸葍}努か 提交于 2019-12-11 06:13:40

问题


I studying 'transform' in recent days,and now i know how to do translate,rotate,skew,scale by transform's matirx. but if i want to do all actions above in one transform statement, how can i do?

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

when we want rotate something by transform, we must post 4 arguments for each one (a,b,c,d), So ,if i want rotate and scale, for example, rotate 30 deg and scale (1.5,2), can the transform done them at the same time? so what the values of (a,b,c,d)? and how calculate them?

and another question: Is there an order in transform? I mean if i use transform to rotate and scale and translate, what's the order between them? after all, the order is very important, 'translate first,scale next' with 'scale first,translate next', will get different results.


回答1:


This is the math done by context.transform(a,b,c,d,e,f)

When you use a single context.transform to do multiple operations (translate+scale+rotate)

  • The translate is done first.
  • The scale and rotate are done next (order of these does not matter).

This is the matrix math in javascript form:

    // 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;   
    }



回答2:


There's all kinds of flexibility here that might be what you're looking for. See for example:

CSS3 Multiple transforms

How to apply multiple transforms in CSS?

then see here:

http://www.quora.com/Is-there-any-way-to-make-sequential-CSS-transition-without-JavaScript




回答3:


Every transform function is described mathematically using a 4*4 matrix, To perform more than 1 function say, rotate and scale, then you need to multiply the 4*4 matrices created for each of them,

For details on Mathematical Description of Transform Functions please refer < http://www.w3.org/TR/css3-transforms/#Scale3dDefined>

For details on how to apply multiple transforms please refer Matrices, vectors, and matrix3d() section in http://dev.opera.com/articles/view/understanding-3d-transforms/

There is an order for your transforms based on the order in which you give each function doesnt hold any precedence, say scale(10) translate(200) would be different from ttranslate(200)scale(10),thats obvious as Matrix multiplication is NOT commutative in general AB ≠ BA



来源:https://stackoverflow.com/questions/18437039/canvashow-to-complete-translate-skew-rotate-in-just-one-transform-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!