|a c e| |b d g| |0 0 1|Третья строка матрицы для двумерных преобразований всегда одна и та же: 0 0 1. Поэтому ее не учитывают при задании преобразования посредством атрибута вида transform="matrix(a,b,c,d,e,g)" (только 6, а не 9 параметров).
translate (перемещение на x и y px) — matrix(1,0,0,1,x,y) rotate (поворот на угол a) — matrix(cos(a),sin(a),-sin(a),cos(a),0,0) scale (масштабирование с коэффициентами kx и ky) — matrix(kx,0,0,ky,0,0) skewX (наклон вдоль X на угол a) — matrix(1,0,tg(a),1,0,0) skewY (наклон вдоль Y на угол a) — matrix(1,tg(a),0,1,0,0) тождественное преобразование, которое ничего не изменяет — matrix(1,0,0,1,0,0)
Сложное преобразование получается как последовательность элементарных преобразований. Оно описывается матрицей, являющейся результатом произведения матриц, соответствующих элементарным преобразованиям. Матричная запись преобразований компактна, но с трудом поддается интуиции или семантической интерпретации. Вместе с тем, многие типичные преобразования можно понять, выполнив экспериментально произведение нескольких элементарных преобразований подряд и заметив, как формируется результирующая матрица относительно исходной. Так например, легко заметить, что:
function pmatrix(a1,b1,c1,d1,e1,g1,a2,b2,c2,d2,e2,g2){ /* Параметры: значения параметров 1-го и 2-го преобразований Возвращает строку вида "matrix(a,b,c,d,e,g)", являющуюся результатом произведения двух матриц */ return "matrix("+(a1*a2+c1*b2)+","+ (b1*a2+d1*b2)+","+ (a1*c2+c1*d2)+","+ (b1*c2+d1*d2)+","+ (a1*e2+c1*g2+e1)+","+ (b1*e2+d1*g2+g1)+")" } function pmatrix2(s1,s2){ /*Параметры: строки вида "matrix(a,b,c,d,e,g)" Возвращает строку вида "matrix(a,b,c,d,e,g)", являющуюся результатом произведения двух матриц */ var sep;// разделитель ,бывают "," и пробел if (s1.indexOf(",")==-1) {sep=' '} else {sep="," }; var l=s1.length var s1=s1.substring(7,s1.length-1); // содержимое скобок s1=s1.split(","); // делаем массив var s2=s2.substring(7,s2.length-1); // содержимое скобок if (s2.indexOf(",")==-1) {sep=" "} else {sep=","}; s2=s2.split(","); // делаем массив return "matrix("+(s1[0]*s2[0]+s1[2]*s2[1])+","+ (s1[1]*s2[0]+s1[3]*s2[1])+","+ (s1[0]*s2[2]+s1[2]*s2[3])+","+ (s1[1]*s2[2]+s1[3]*s2[3])+","+ (s1[0]*s2[4]+s1[2]*s2[5]+s1[4]*1)+","+ (s1[1]*s2[4]+s1[3]*s2[5]+s1[5]*1)+")"; }Далее в примерах я буду использовать функцию pmatrix2(), как наиболее удобную для работы в SVG, когда необходимо с помощью скрипта изменять текущее положение объекта. Обратите внимание на возню с разделителем в коде этой функции. Дело в том, что параметры в matrix() можно разделять запятой или пробелом. Однако при установке атрибута transform="matrix(...)" некоторые браузеры (Opera, Safari, Chrome и IE) сохраняют его, используя пробелы при разделении параметров. Firefox сохраняет так,как записано.
var x=pmatrix2("matrix(1,0,1,1,0,0)","matrix(1,0,0,1,50,70)"); document.getElementById("mypicture").setAttribute("transform",x);Следующий код показывает растровую картинку и строку текста. В исходном состоянии картинка масштабирована с коэффициентом 0.6 и помещена в точку с координатами x=120px y=120px. Щелчок мышью на картинке с помощью функции pmatrix2() поворачивает ее на 30 градусов по часовой стрелке.
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="350" xmlns:xlink="http://www.w3.org/1999/xlink"> <script type="text/javascript"> <![CDATA[ function pmatrix2(s1,s2){ // код (см. выше) } function imgrotate(){ // поворачиваем на 30 град. var x=document.getElementById("myimg"); curattr=x.getAttribute("transform"); x.setAttribute("transform", pmatrix2(curattr,"matrix(0.867,0.5,-0.5,0.867,0,0)")); } ]]> </script> <image id="myimg" transform="matrix(0.6 0 0 0.6 120 120)" x="0" y="0" width="300" height="209" xlink:href="korabl16.jpg" onclick="imgrotate()" /> <text x="10" y="300"> Щелчок на картинке поворачивает ее на 30 градусов </text> </svg>
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="350" xmlns:xlink="http://www.w3.org/1999/xlink"> <script type="text/javascript"> <![CDATA[ function pmatrix2(s1,s2){ // код (см. выше) } <script type="text/javascript"> <![CDATA[ function imgflip(){ // отражаем относительно вертикали var x=document.getElementById("myimg"); var curattr=x.getAttribute("transform"); x.setAttribute("transform", pmatrix2(curattr,"matrix(-1 0 0 1 300 0)")) } ]]> </script> < image id="myimg" transform="matrix(0.7 0 0 0.7 20 20)" x="0" y="0" width="300" height="209" xlink:href="korabl16.jpg" onclick="imgflip()" /> < text x="5" y="200"> Щелчок на картинке отражает ее относительно вертикали </text> </svg>Примечание
В CSS3 для аналогичных трансформаций имеется параметр transform.