图形编辑器:旋转选中的元素

开发 前端
元素有一个包围盒(Bounding Box),是能包裹元素的最小矩形。当然大一点也行,但必须能包裹元素。

大家好,我是前端西瓜哥。

最近更文比较少,是因为本人在做个人开源项目,用 Canvas 做一个设计工具,做个乞丐版 figma。期间遇到了不少问题,在这里记录一下。

今天开始会恢复高频更新的,一两天一更。内容主要会围绕我打造的设计工具遇到的一些问题和解决方案,也会有其他主题。

项目地址:

https://github.com/F-star/suika

线上体验:

https://blog.fstars.wang/app/suika/

元素和它的包围盒(bBox)

元素指的是一些图形,比如矩形、椭圆。

为了方便描述,后面都会用矩形作为例子。

元素有一个包围盒(Bounding Box),是能包裹元素的最小矩形。当然大一点也行,但必须能包裹元素。

const bBox = {
x: 100,
y: 100,
width: 30,
height: 40
}

x 和 y 代表包围盒的位置,width 和 height 代表盒子的尺寸。

另外元素一个 rotation 属性,表示元素以其中心位置(即包围盒的正中心)的旋转弧度。

bBox 是考虑旋转的(最外层的矩形):

图片

bBox

还有一种不考虑旋转,我暂且称其为 bBoxWithoutRotation。它会忽视 rotation 的存在,得到一个旋转前的 bBox。我们使用它配合渲染层(ctx.rotate(angle)),绘制一个进行了旋转的盒子。

图片

bBoxWithoutRotation

选中元素

选中的元素需要分两种情况讨论,一种是选中单个元素,一种是选中多个元素。

对于单个元素,要绘制 bBoxWithoutRotation。原因是只有一个元素,也就一个旋转角度,旋转起来更能表现这个元素的情况。见下图:

图片

对于多个元素,情况则不同了,因为不同的元素有不同的旋转角度,所以要计算所有元素的 bBox,然后取出其中最小的 x、y 和最大的 x、y,组成包围所有元素的选中框:

图片

旋转元素

旋转元素同样分两种情况讨论:旋转单个元素,以及旋转多个元素。

先讲解 旋转单个元素。我们看看效果:

图片

旋转单个元素

首先,从图形的中点连接光标位置,得到一个向量。我们的旋转角度就是这个向量和向上向量(即 [0, -1])的夹角。

图片

求向量角度

这里我们可以用 点积公式 来计算这个夹角。

计算好这个夹角,将其赋值给选中的元素的 rotation 属性,然后进行渲染,让渲染引擎根据新的角度进行绘制。

然后是 旋转多个元素。效果:

图片

旋转多个元素

旋转多个元素则复杂一些。

我们需要改变每个元素的旋转角度 rotation,以及 x、y 值。

这里我们需要知道一个很重要的信息:元素上所有的点的旋转结果坐标,都是根据大包围盒中心旋转 rotation 得到的。

首先是 rotation,旋转中心是这个大 bBox 的中心。

我们从元素的中点画一个向上的向量,这个向量是跟随着多元素旋转角度改变的。

所以,和单元素直接赋值不同,多元素旋转情况下,拖拽中产生的旋转角度需要作为增量,加在每个旋转前的元素起始角度上,即:

element.rotation = prevElementRotation + dRotation;

然后是计算每个元素 新的 x 和 y 值。

也很简单,对旋转前的中点 cx 和 cy,使用旋转算法,计算出新的 cx 和 cy ,然后减去宽高/2即可。

需要实现的算法

在这个过程中你需要实现的算法有:

  1. 求向量夹角,需要用点积公式。
  2. 旋转算法,需要考虑旋转中心。
  3. 计算 bBox,其实就是将 bBox 转换为 4 个边角的坐标,然后取最小的 x、y 和最大的 x、y 重新组合成一个 box。

然后其他就是繁琐的交互逻辑了。

结尾

至此,我们就实现了元素的旋转逻辑。晚点我会再出一篇缩放元素的文章。

责任编辑:姜华 来源: 前端西瓜哥
相关推荐

2023-08-31 11:32:57

图形编辑器contain

2024-01-03 08:43:17

图形编辑器旋转控制点缩放控制点

2023-10-19 10:12:34

图形编辑器开发缩放图形

2023-02-01 09:21:59

图形编辑器标尺

2023-04-07 08:02:30

图形编辑器对齐功能

2023-09-26 07:39:21

2023-04-10 08:45:44

图形编辑器排列移动功能

2023-09-07 08:24:35

图形编辑器开发绘制图形工具

2023-02-06 16:59:57

Canvas编辑器

2023-10-08 08:11:40

图形编辑器快捷键操作

2023-02-02 14:07:00

图形编辑器Canvas

2023-09-11 09:02:31

图形编辑器模块间的通信

2023-05-09 08:15:32

图形编辑器撤销重做功能

2024-01-08 08:30:05

光标图形编辑器开发游标

2023-02-09 07:02:30

图形编辑器修改图形

2023-08-28 08:10:50

Hex图形编辑器

2023-03-03 10:24:51

2023-10-10 16:04:30

图形编辑器格式转换

2023-06-12 08:22:56

图形编辑器工具

2023-07-31 08:46:07

图形编辑器图形自动对齐
点赞
收藏

51CTO技术栈公众号