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 的代码。
希望有人能帮忙,非常感谢
我找到了解决办法。
每当旋转一个形状时,您应该平移鼠标指针和形状,就好像它们没有旋转一样,正常缩放然后平移回来并在最后旋转。我的问题是我在翻译回来之前试图旋转!
如果您使用此方法,顺序应该是变换(旋转平移比例),因为您放置的最后一个是最先发生的!
我正在为一个我想从事的项目使用 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 的代码。
希望有人能帮忙,非常感谢
我找到了解决办法。
每当旋转一个形状时,您应该平移鼠标指针和形状,就好像它们没有旋转一样,正常缩放然后平移回来并在最后旋转。我的问题是我在翻译回来之前试图旋转!
如果您使用此方法,顺序应该是变换(旋转平移比例),因为您放置的最后一个是最先发生的!