I got this function working pretty well now (below) for rotation (it detects angle correctly etc). Now my struggle is to make scaling to work in such a way that the shape becomes super small the closer the user is to the initial center of the shape.
Basically right now when player move their touch/mouse to the center of the shape at some point scaling just stops (as we reached the center) ;/
Any advice what should be tuned? I am pretty sure it relates to these vars: - this.activeShape.scale.height (currently I take top most point of shape's bounding box; - this.activeShape.scale.point (this is currently the same as rotation point - center of shape's bounding box).
mainSVG.rotateMove = function(event) {
this.eventObj = this.isTouchSupported? event.touches[0] : event;
this.moveCoordsCache = this.globalToLocalCoordinates(this.eventObj.clientX, this.eventObj.clientY);
let rdx = this.moveCoordsCache.x - this.activeShape.rotation.center.x;
let rdy = this.moveCoordsCache.y - this.activeShape.rotation.center.y;
let theta = Math.atan2(rdy, rdx) * 180 / Math.PI + 90;
if (rdx < 0 && rdy < 0) { theta += 360 };
theta -= 180;
let sdx = this.activeShape.scale.point.x - this.moveCoordsCache.x;
let sdy = this.activeShape.scale.point.y - this.moveCoordsCache.y;
let distanceToMouse = Math.sqrt(sdx * sdx + sdy * sdy);
let transform = "translate(" + this.activeShape.rotation.center.x + "," + this.activeShape.rotation.center.y + ") rotate(" + theta + ") scale(" + distanceToMouse / this.activeShape.scale.height + ") translate(" + (-this.activeShape.rotation.center.x) + "," + (-this.activeShape.rotation.center.y) + ")";
this.domCtrl.write(()=>{
this.activeShape.setAttribute("transform", transform);
});
here is codepen I did to recreate. It is almost working as I want except that it keeps a bit of flicks here and there which I am not sure how to fix. Like I don't get what should be the scale height I think. Maybe it should be dynamic?
The only issue i see with your example is that the shape jumps a little and becomes smaller when you start dragging the rotator.
In your transform, you calculate the scale as distanceToMouse / scaleHeight
. Therefore, scaleHeight
should be the initial "distance to mouse", and not the height of the item
group as in your example.
var rectBox = rectangle.getBBox(),
rotBox = rotator.getBBox();
rotateAndScaleAround = {
x: rectBox.x + rectBox.width/2,
y: rectBox.y + rectBox.height/2
};
scaleHeight = (rotBox.y + rotBox.height/2) - rotateAndScaleAround.y;
Updated pen: https://codepen.io/Sphinxxxx/pen/EbgooY