Я играю с svgs и матрицами для проекта, над которым я бы хотел поработать, и пытаюсь реализовать бесплатное преобразование с помощью vanilla javascript. На данный момент я могу выполнять все преобразования с использованием JavaScript и этой библиотеки https://www.npmjs.com/package/transformation-matrix#transform, чтобы помочь мне разобраться с матрицами.
Мой код на данный момент работает только с прямоугольными элементами, но я предполагаю, что большая часть кода будет полезна для других элементов с некоторыми изменениями.
Проблема возникает, когда я пытаюсь масштабировать повернутый прямоугольник.
В моем коде, когда я нажимаю на элемент, я указываю ему путь вокруг элемента, некоторые круги, которые представляют направление, в котором можно масштабировать прямоугольник, 1 для центра и 1 для вращения.
Как я уже сказал, у меня нет проблем с каким-либо преобразованием, будь то перевод повернутой / масштабированной фигуры или что-то еще, единственное, что я не могу понять, как это сделать, - как масштабировать повернутую фигуру. форма, сохраняя свое вращение.
Если у прямоугольника 0 вращений, в зависимости от того, в каком направлении я решу масштабировать, я просто смешиваю перевод и масштаб после того, как получу новую ширину / высоту на основе указателя мыши. Это прекрасно работает и как задумано.
Если у прямоугольника есть вращение, это ломается, и я подумал, может быть, используя евклидово расстояние между точкой, от которой я масштабируюсь, и указателем мыши будет работать, но это не так. так что я немного растерялся.
const elem = document.getElementById('rect2');
const x = elem.x.baseVal.value;
const y = elem.y.baseVal.value;
const width = elem.width.baseVal.value;
const height = elem.height.baseVal.value;
// this is a function that return the mouse coords on the canvas-
// svg
const m = this.getCanvasMousePos(e);
if(type === 'bottom-center'){
const newH = (m.y - y) / height;
const s = scale(1,newH);
const form = toSVG(s);
elem.setAttribute('transform', form);
}else if (type === 'top-center'){
const newH = (y+height - m.y) / height;
const s = scale(1,newH);
const t = translate(0,m.y-y)
const comp = compose(t,s);
const form = toSVG(comp);
elem.setAttribute('transform', form);
}else if (type === 'middle-left') {
const newW = (x+width - m.x) / width;
const s = scale(newW,1);
const t = translate(m.x-x, 0);
const comp = compose(t,s)
const form = toSVG(comp);
elem.setAttribute('transform', form);
}else if (type === 'middle-right') {
const newW = (m.x - x) / width;
const s = scale(newW,1);
const form = toSVG(s);
elem.setAttribute('transform', form);
}else if (type === 'bottom-right') {
const newW = (m.x - x) / width;
const newH = (m.y - y) / height;
const s = scale(newW,newH);
const form = toSVG(s);
elem.setAttribute('transform', form);
}else if (type === 'bottom-left'){
const newW = ((x + width) - m.x) / width;
const newH = (m.y - y) / height;
const t = translate(m.x - x,0);
const s = scale(newW,newH);
const comp = compose(t,s)
const form = toSVG(comp);
elem.setAttribute('transform', form);
}else if (type === 'top-left') {
const newW = ((x + width) - m.x) / width;
const newH = ((y + height) - m.y) / height;
const t = translate(m.x-x,m.y-y);
const s = scale(newW,newH);
const comp = compose(t,s)
const form = toSVG(comp);
elem.setAttribute('transform', form);
}else if (type === 'top-right') {
const newW = (m.x - x) / width;
const newH = ((y + height) - m.y) / height;
const t = translate(0,m.y-y);
const s = scale(newW,newH);
const comp = compose(t,s)
const form = toSVG(comp);
elem.setAttribute('transform', form);
};
Это код для неповоротных svgs.
Надеюсь, кто-то может помочь, большое спасибо