Svg 在鼠标拖动时缩放旋转的元素

Svg scaling rotated elements on mouse drag

我正在为一个我想从事的项目使用 svgs 和矩阵,我正在尝试使用 vanilla javascript 实现自由变换。截至目前,我可以使用 javascript 和此库 https://www.npmjs.com/package/transformation-matrix#transform 进行所有转换,以帮助我处理矩阵。 我现在的代码仅适用于 rect 元素,但我认为大部分代码都将用于其他元素并进行一些更改。

当我尝试缩放旋转的矩形时出现问题。 在我的代码中,当我点击一个元素时,我给它一个围绕元素的路径,一些圆圈代表你可以缩放矩形的方向,1 个代表中心,1 个代表旋转。

正如我所说,我对任何转换都没有任何问题,无论是转换 rotated/scaled 形状还是其他任何东西,我唯一不知道该怎么做的是缩放旋转的形状并保持其旋转。

如果一个矩形有 0 个旋转,根据我决定缩放的方向,我只是在根据鼠标指针获得新的 width/height 后混合平移和缩放。这很好用并且符合预期。 如果一个矩形有旋转,这会中断,我想也许使用我缩放的点和鼠标指针之间的欧几里德距离会起作用,但它不起作用。所以我有点迷失了。

        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);
        };

这是非旋转 svg 的代码。

希望有人能帮忙,非常感谢

我找到了解决办法。

每当旋转一个形状时,您应该平移鼠标指针和形状,就好像它们没有旋转一样,正常缩放然后平移回来并在最后旋转。我的问题是我在翻译回来之前试图旋转!

如果您使用此方法,顺序应该是变换(旋转平移比例),因为您放置的最后一个是最先发生的!