I have some SVG elements and I would like to add the ability to resize using mouse. It works great when element doesn't have any transforms (matrix, rotate, scale etc).
If I remove transform (transform="matrix(1.1,1.1,1,0,0,0)") from the rect element - it works great.
My understanding is that I should use matrix.inverse() function and transform it so I get mouse coordinates in the element space, but everything I tried didn't work for me.
I need to correctly calculate the x, y difference between start drag point and current point, but it doesn't work.
var rect = document.getElementById('rect');
var grip = document.getElementById('grip');
function moveGrip() {
var baseMatrix = rect.getCTM(),
x = rect.width.baseVal.value rect.x.baseVal.value,
y = rect.height.baseVal.value rect.y.baseVal.value;
grip.cx.baseVal.value = x * baseMatrix.a y * baseMatrix.c baseMatrix.e;
grip.cy.baseVal.value = x * baseMatrix.b y * baseMatrix.d baseMatrix.f;
}
grip.addEventListener('mousedown', onGripMouseDown);
document.addEventListener('mousemove', onDocMouseMove);
var startDragPoint, startDragSize;
function onGripMouseDown(evt) {
startDragSize = {w: rect.width.baseVal.value, h: rect.height.baseVal.value};
startDragPoint = {x: evt.clientX, y: evt.clientY};
}
function onDocMouseMove(evt) {
if (evt.buttons & 1) {
// dragging
rect.width.baseVal.value = startDragSize.w evt.clientX - startDragPoint.x;
rect.height.baseVal.value = startDragSize.h evt.clientY - startDragPoint.y;
moveGrip();
}
}
moveGrip();
<svg width="500" height="400">
<rect id="rect" x="20" y="20" width="200" height="100"
transform="matrix(1.1,1.1,1,0,0,0)"
style="fill:none;stroke: #3a2dd0; stroke-width: 2px;"></rect>
<g>
<circle id="grip" r="3" stroke-width="1" stroke="green"></circle>
</g>
</svg>
CodePudding user response:
Probably, you'd need to apply the inverse matrix to delta-x,y as follows;
function onDocMouseMove(evt) {
if (evt.buttons & 1) {
// dragging
var invMatrix = rect.getCTM().inverse(),
x = evt.clientX - startDragPoint.x,
y = evt.clientY - startDragPoint.y;
rect.width.baseVal.value = startDragSize.w x * invMatrix.a y * invMatrix.c;
rect.height.baseVal.value = startDragSize.h x * invMatrix.b y * invMatrix.d;
moveGrip();
}
}