我像下面这样解决了这个问题,我很想听到更好的解决方案。
这包括在旋转和缩放操作后找到新的顶点和中心。
以下所有代码块都应在每个缩放事件和旋转事件之后进行评估。
这可能是手柄的拖动事件。
heightOfRectangle 和 WidthOfRectangle 应该是缩放后的值。
例如。如果您当前的比例为 1.3,那么 heightOfRectangle 应该是您的 initial rectangle's height*1.3
rotationAngle 应该是之前应用的所有旋转角度的总和,以弧度表示。
alpha 是Math.atan2(heightOfRectangle,WidthOfRectangle);
r 是 Math.sqrt(Math.pow(WidthOfRectangle,2)+Math.pow(heightOfRectangle,2))/2
换句话说,斜边由构成矩形的两个直角三角形共享;
假设您克服了变换原点问题并且可以缩放
来自不同手柄的矩形防止变换原点跳跃,活动手柄是您拖动的手柄
而对面是变换原点所在的位置。
例如,如果您从左上角的手柄拖动,原点应该位于
在右下手柄位置。
activeHandle 是您拖动的句柄。
tl 用于左上角,o 用于原点 br 用于右下角等等..
tc 表示我的代码的顶部中心,我在其中拖动以进行旋转。
它只是意味着从原点事件旋转。
以old 开头的值应该是您在此轮换之前的最后一个句柄位置。
以new 开头的值将是此轮换后的新句柄位置。
rx是旋转x的缩写
ry是旋转y的缩写
您仍然可以在此处查看笔,问题已解决。
https://codepen.io/anon/pen/LLEedg?editors=0010
您可以在第 251 行查看updateControlPoints 函数。
var cosRot = Math.cos(rotationAngle);
var sinRot = Math.sin(rotationAngle);
if (activeHandle === 'tc') {
var cosAMinusRot = Math.cos(alpha - rotationAngle);
var sinAMinusRot = Math.sin(alpha - rotationAngle);
var cosAPlusRot = Math.cos(alpha + rotationAngle);
var sinAPlusRot = Math.sin(alpha + rotationAngle);
var cos90APlusRot = Math.cos(Math.PI / 2 - alpha + rotationAngle);
var sin90APlusRot = Math.sin(Math.PI / 2 - alpha + rotationAngle);
var ox = old_ox; //means current ox
var oy = old_oy; //means current oy
//tl
var new_x = -r * cosAPlusRot + ox
var new_y = -r * sinAPlusRot + oy
new_tl.rx = new_x;
new_tl.ry = new_y;
//tr
new_x = +r * sin90APlusRot + ox
new_y = -r * cos90APlusRot + oy
new_tr.rx = new_x;
new_tr.ry = new_y;
//bl
new_x = -r * cosAMinusRot + ox
new_y = +r * sinAMinusRot + oy
new_bl.rx = new_x;
new_bl.ry = new_y;
//br
new_x = +r * cosAPlusRot + ox
new_y = +r * sinAPlusRot + oy
new_br.rx = new_x;
new_br.ry = new_y;
}
else if (activeHandle === 'tl') {
var cosAPlusRot = Math.cos(alpha + rotationAngle);
var sinAPlusRot = Math.sin(alpha + rotationAngle);
new_tl.rx = old_br.rx - 2 * r * cosAPlusRot;
new_tl.ry = old_br.ry - 2 * r * sinAPlusRot;
new_bl.rx = old_br.rx - WidthOfRectangle * cosRot;
new_bl.ry = old_br.ry - WidthOfRectangle * sinRot;
new_tr.rx = old_br.rx + HeightOfRectangle * sinRot;
new_tr.ry = old_br.ry - HeightOfRectangle * cosRot;
new_ox = old_br.rx - r * cosAPlusRot;
new_oy = old_br.ry - r * sinAPlusRot;
} else if (activeHandle === 'tr') {
var cos180APlusRot = Math.cos(Math.PI - alpha + rotationAngle);
var sin180APlusRot = Math.sin(Math.PI - alpha + rotationAngle);
new_tl.rx = old_bl.rx + HeightOfRectangle * sinRot;
new_tl.ry = old_bl.ry - HeightOfRectangle * cosRot;
new_br.rx = old_bl.rx + WidthOfRectangle * cosRot;
new_br.ry = old_bl.ry + WidthOfRectangle * sinRot;
new_tr.rx = old_bl.rx - 2 * r * cos180APlusRot;
new_tr.ry = old_bl.ry - 2 * r * sin180APlusRot;
new_ox = old_bl.rx - r * cos180APlusRot;
new_oy = old_bl.ry - r * sin180APlusRot;
} else if (activeHandle === 'bl') {
var cosAPlus90MinusRot = Math.cos(alpha + Math.PI / 2 - rotationAngle);
var sinAPlus90MinusRot = Math.sin(alpha + Math.PI / 2 - rotationAngle);
new_bl.rx = old_tr.rx - 2 * r * sinAPlus90MinusRot;
new_bl.ry = old_tr.ry - 2 * r * cosAPlus90MinusRot;
new_br.rx = old_tr.rx - HeightOfRectangle * sinRot;
new_br.ry = old_tr.ry + HeightOfRectangle * cosRot;
new_tl.rx = old_tr.rx - WidthOfRectangle * cosRot;
new_tl.ry = old_tr.ry - WidthOfRectangle * sinRot;
new_ox = old_tr.rx - r * sinAPlus90MinusRot;
new_oy = old_tr.ry - r * cosAPlus90MinusRot;
} else if (activeHandle === 'br') {
var cosAPlusRot = Math.cos(alpha + rotationAngle);
var sinAPlusRot = Math.sin(alpha + rotationAngle);
new_bl.rx = old_tl.rx - HeightOfRectangle * sinRot;
new_bl.ry = old_tl.ry + HeightOfRectangle * cosRot;
new_br.rx = old_tl.rx + 2 * r * cosAPlusRot;
new_br.ry = old_tl.ry + 2 * r * sinAPlusRot;
new_tr.rx = old_tl.rx + WidthOfRectangle * cosRot;
new_tr.ry = old_tl.ry + WidthOfRectangle * sinRot;
new_ox = old_tl.rx + r * cosAPlusRot;
new_oy = old_tl.ry + r * sinAPlusRot;
}