SVG масштабирование вращающихся элементов при перетаскивании мышью - PullRequest
0 голосов
/ 25 июня 2019

Я играю с 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.

Надеюсь, кто-то может помочь, большое спасибо

1 Ответ

0 голосов
/ 27 июня 2019

Я нашел решение.

Всякий раз, когда фигура поворачивается, вы должны перевести указатель мыши и фигуру так, как если бы они не вращались, обычно выполняйте масштабирование, а затем переводите назад и вращайте в конце.Моя проблема заключалась в том, что я пытался повернуть перед переводом назад!

Если вы используете этот метод, порядок должен быть преобразован (повернуть масштаб перевода), потому что последний, который вы добавили, произойдет первым!

...