I am creating an editor. I would like the basic functions on my objects which are rotate/resize and translate.
I've managed to do the three of them but the only problem is now my mouse position doesn't follow the control points (the problem gets even worst for the other control points not shown below)..
You'll find below an example for the right middle resize with a rotation angle of 30 degrees with no mouseY position, note that the mouse follows perfectly my control point when the rotation angle equals 0.
Is there a way easily solve this problem, am I going the wrong way?
Here's the jsfiddle link where you can change the rotate angle in the code to see by yourself JSiddle link. (Just click and drag the black control point to resize the object)
//convert value of range amin to amax to the range bmin to bmax;
function imap(value, amin, amax, bmin, bmax)
{
if ((amax - amin))
return (value - amin) * (bmax - bmin) / (amax - amin) + bmin;
return (0);
};
//get mouse coordinates from the SVG element
function getMouse(el, e)
{
var pt = el.createSVGPoint();
pt.x = e.clientX;
pt.y = e.clientY;
var cursorpt = pt.matrixTransform(el.getScreenCTM().inverse());
return({x: cursorpt.x, y: cursorpt.y})
};
var controlPoint = document.getElementById("c"); //My control point element
var mouseX;
var mouseXClicked = 0;
var scaleX = 1;
var scaleY = 1;
var scaleXClicked = 1;
var control = false; // sets if resizeRightMiddle() should be executed
var rectWidth = 100; //is normally tooken with a getBBox() function
var scale = document.getElementById("scale");
function resizeRightMiddle()
{
//convert difference between original mouse X postion on click and actual X mouse position into a scale factor
plusX = imap(mouseX - mouseXClicked, 0, rectWidth, 0, 1);
//add converted scale factor to the original x scale value
resX = scaleXClicked + plusX;
scale.setAttribute('transform', 'scale(' + resX + ',' + scaleY + ')');
scaleX = resX;
}
var svg = document.getElementById("main");
// save Scale and X mouse coordinate on click
svg.addEventListener("mousedown", function(e){
var coord = getMouse(svg, e);
mouseXClicked = coord.x;
scaleXClicked = scaleX;
});
svg.addEventListener("mousemove", function(e){
//get mouse coordinates
var coord = getMouse(svg, e);
mouseX = coord.x;
// resize if control element has been clicked
if (control)
resizeRightMiddle();
});
// desactivate resize
svg.addEventListener("mouseup", function(e){
control = false;
});
//activate resize
controlPoint.addEventListener("mousedown", function(){
control = true;
});
svg {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<div>
<svg id="main" width="1000" height="300">
<g transform="translate(66, 56)">
<g id="rotate" transform-origin="center" transform="rotate(30)">
<g id="scale">
<path fill="red" stroke="red" d="M 0 0 L 0 100 L 100 100 L 100 0Z" />
<rect id="c" fill="black" stroke="black" x=95 y=45 width=10 height=10 />
</g>
</g>
</g>
</svg>
</div>