Проблемы с трансформациями фигур в формате SVG
Здравствуйте!
Тему http://javascript.ru/forum/extjs/549...meshhenie.html я закрыл, так как нашел источник проблем. Описываю: Проблемы с трансформациями фигур в формате SVG (2D матричнычные преобразования) Проблема следующая. 1) Создаю квадрат с размерами 100 на 100 и координатами верхнего левого угла 100 на 200 (то есть ближайший угол к началу координат находится в точке 100 на 100). 2) Делаю перенос квадрата (-100, -100), то есть нижний левый угол совместился с началом координат. 3) И делаю поворот квадрата. По теории он должен повернуться вокруг начала координат. Но в SVG он поворачивается вокруг точки (-100, -100). То есть точка вращения тоже переносится. Я выяснил, что это происходит из-за того, что матрица трансформации перед тем как применяться к фигуре почему-то транспонируется. Это показано тут https://developer.mozilla.org/en-US/...bute/transform Там в разделе General Transformation показан пример линия (x1="10" y1="20" x2="30" y2="40") трансформируется матрицей matrix(1,2,3,4,5,6)*. В итоге вопрос, как выкрутиться из этой ситуации? Мне нужно, чтобы трансформации производились без транспонирования. _____ * Сразу поясняю, что matrix(1,2,3,4,5,6) в виде матрицы выглядит так: [[1,3,5],[2,4,6],[0,0,1]] (точное описание тут http://www.w3.org/TR/SVG/coords.html) |
Проблема решена. Оказывается точку, относительно которой производится масштабирование, нужно преобразовать следующим образом:
Берется текущая матрица, инвертируется и применяется к точке. Полученную точку и надо использовать. Теперь все работает! Если кому будет нужен код, то он примерно такой:
function getmouseX(e) {
return e.pageX - svg.getX();
}
function getmouseY(e) {
return e.pageY - svg.getY();
}
svg.getEl().on("mousewheel", function(e) {
scaleLevel += e.event.wheelDelta > 0 ? 1 : -1;
if (scaleLevel < scaleLevelMin) scaleLevel = scaleLevelMin;
if (scaleLevel > scaleLevelMax) scaleLevel = scaleLevelMax;
var scaleResult = Math.exp(scaleLevel / 5);
applyScale(scaleResult, getmouseX(e), getmouseY(e));
});
function applyScale(scale, x, y) {
var matrixResult = matrixPrevious;
var s = scale / scalePrevious;
var point = matrixResult.inverse().transformPoint([x, y]);
x = point[0]; y = point[1];
matrixResult.translate(x, y);
matrixResult.scale(s);
matrixResult.translate(-x, -y);
svg.getSurface().clearTransform();
svg.getSurface().matrix(matrixResult);
matrixPrevious = matrixResult;
scalePrevious = scale;
}
|
| Часовой пояс GMT +3, время: 04:42. |