SVG матричная декомпозиция - PullRequest
       64

SVG матричная декомпозиция

7 голосов
/ 02 января 2012

В svg у нас есть метод element.getCTM(), который возвращает SVGMatrix как:

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

Я хочу вычислить sx, sy и угол поворота из этой матрицы.

1 Ответ

10 голосов
/ 02 января 2012

Есть много, чтобы прочитать и узнать на эту тему.Я дам простой ответ, но имейте в виду, что если вы пытаетесь создать игру или анимацию, это НЕ способ сделать это.

a == sx и d == sy, так что вы получите доступвот так:

var r, ctm, sx, sy, rotation;

r   = document.querySelector('rect'); // access the first rect element
ctm = r.getCTM();
sx  = ctm.a;
sy  = ctm.d;

Теперь для вращения a == cos(angle) и b == sin(angle).Асин и Акос не могут в одиночку дать вам полный угол, но вместе они могут.Вы хотите использовать atan начиная с tan = sin/cos, и именно для такого рода задач вы действительно хотите использовать atan2:

RAD2DEG = 180 / Math.PI;
rotation = Math.atan2( ctm.b, ctm.a ) * RAD2DEG;

Если вы изучаете обратные тригонометрические функции и единичный кружок вы поймете, почему это работает.

Вот незаменимый ресурс W3C по преобразованиям SVG: http://www.w3.org/TR/SVG/coords.html. Прокрутите немного вниз, и вы сможете больше узнать о том, что яВыше упоминалось.

ОБНОВЛЕНИЕ, пример использования, как программно делать анимацию.Храните преобразования отдельно, а при их обновлении перезаписывайте / обновляйте преобразование элемента SVG.

var SVG, domElement, ...

// setup
SVG        = document.querySelector( 'svg' );
domElement = SVG.querySelector( 'rect' );
transform  = SVG.createSVGTransform();
matrix     = SVG.createSVGMatrix();
position   = SVG.createSVGPoint();
rotation   = 0;
scale      = 1;

// do every update, continuous use
matrix.a = scale;
matrix.d = scale;
matrix.e = position.x;
matrix.f = position.y;

transform.setMatrix( matrix.rotate( rotation ) );
domElement.transform.baseVal.initialize( transform ); // clear then put
...