javascript - 缩放旋转的矩形并找到新的控制点和中心

标签 javascript svg matrix css-transforms

我要分享的代码笔链接中的这段代码有点复杂和密集,所以我实际上要求的不是代码而是建议。

https://codepen.io/anon/pen/LLEedg?editors=0010

它是关于缩放旋转的矩形并找到新缩放的矩形的顶点坐标。

当我旋转矩形时,我将其中心平移到视口(viewport)的 0,0 并进行旋转。然后我翻译回原来的地方。有用。

然后我进行缩放,将 transform-origin 移动到矩形的右下角。为了避免跳跃,我补偿了缩放量以及旋转 Action 应用于控制点的平移。最后,当我将变换原点移动到矩形的旋转左下角时,我没有看到任何跳跃。我用新的控制点计算一个新的边界框(不是旋转的坐标,而是缩放的版本。)

之后,我使用相同的方法使用新的 transform-origin 进行缩放。这次我采用新的缩放但未旋转的新边界框,并使用相同的方法进行旋转以找到新的缩放和旋转的控制点坐标。

我希望它们完全位于图像顶点,但它们有点偏离。

可能是从旋转控制点的原点进行缩放并且没有正确补偿。

重现我分享的代码笔链接中的问题。

首先向左旋转任意数量。

然后通过将左上角的 handle 向左拖动来进行缩放。

小黑点应该正好落在绿色 handle 的中心。

小黑点是我计算出的新控制点坐标, 红色描边矩形是新的边界框,它在 0,0 处旋转并平移回来以计算新的控制点。红色填充的蓝色目标是图像的变换原点。带有绿色填充的黄色目标是句柄的 transform-origin ,我故意不更新它以避免混淆。具有较大半径且不透明度的蓝色填充圆是小黑点新计算的中心。

最佳答案

我解决了这个问题,如下所示,我很想听到更好的解决方案。

这包括在旋转和缩放操作后找到新的顶点和中心。

应在每次缩放事件和旋转事件后评估以下所有代码块。

这可能是 handle 的拖动事件。

heightOfRectangleWidthOfRectangle 应该是缩放后的值。

例如。如果您当前的比例为 1.3,则 heightOfRectangle 应该是您的初始矩形的高度*1.3

rotationAngle 应该是之前应用的所有旋转 Angular 总和(以弧度为单位)。

alphaMath.atan2(heightOfRectangle,WidthOfRectangle)

rMath.sqrt(Math.pow(WidthOfRectangle,2)+Math.pow(heightOfRectangle,2))/2 换句话说,由两个直 Angular 三 Angular 形共享的斜边构成了矩形;

假设您克服了变换原点问题并且可以缩放 来自不同 handle 的矩形防止变换原点跳转,事件 handle 是您拖动的 handle 对面就是变换原点所在的位置。 例如,如果您从左上角 handle 拖动,则原点应位于 在右下 handle 位置。

activeHandle 是您拖动的 handle 。

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;



 }

关于javascript - 缩放旋转的矩形并找到新的控制点和中心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44498970/

相关文章:

python - 使用 Python 解析 SVG 文件路径

javascript - 如何使用 d3 根据颜色范围的值对 SVG 图像进行着色?

matlab - 精度 Matlab 的斜线矩阵运算符

java - Java 中的矩阵幂不准确

hadoop - 如何处理巨大的稀疏矩阵?

javascript - 滚动时在视口(viewport)上正确对齐 div

html - 带有内部边框的 svg 边框 Angular

javascript - 如何使用验证码?

javascript - 通过绑定(bind) 'ng-src' 获取元素不起作用,Protractor

javascript - AngularJS 等待标签加载到 DOM 中