图形编辑器基于Paper.js教程20:有关图形编辑器中,选择工具的研究

背景

当初做图形编辑器的时,技术选型选择了paperjs这个库,这也意味着很多东西需要自己写,其中最基础,最常用的功能就是选择工具,鼠标点击一个元素,将该元素选择。这是人们对选择工具最简单的理解。但是当你真正要去实现这样一个功能时,你就会发现,妈呀,这也太多细节了吧。做图形编辑器,很多人选择了fabricjs,因为这个库包含了非常多的基本常用工具,其中就是选择工具。没办法,当初选了paperjs这条不归路,很多东西都需要自己搭建,一点一点实现。在做图形编辑器时,选择工具的开发是我遇到的第一个困难,没有选择工具,后面的删除,移动,缩放,编辑元素,根本无从谈起。
下面就让我们一起来看一下如何开发一个选择工具。

选择工具基本定义

要做选择工具,就要先定义出来选择工具的功能范围和职责。
你可以打开ps,或者figma,或者其他的图形化软件工具,不管是在线的还是客户端。
当前你选中了选择工具后,那么下一次点击画布时,就会判断你的点击点是否在一个元素上,包括内部,线框上。当你点击元素时,那么该元素就会被选择,被选中的元素通常会显示该元素的位置,尺寸,等基本信息,有些特殊元素还有其他的编辑功能,比如图片。

当你点击画布后,不放开鼠标,并拖动鼠标,那么就会进入一个框选状态,起点与光标点组成一个矩形,将矩形中,或与矩形相交的元素 选中。

一种是单选,一种是多选。

无论单选或多选,选中后,都会出现选中框,以及在选中框的很多操作点。
如下图:
在这里插入图片描述
蓝色边框是选中框,它是所有选中元素的外接矩形,在它的线框上有9个点,以及顶部一个点。
每个点都有自己的交互。我们统一称它们为操作点,
当你的鼠标选中了某一个操作点后,那么恭喜你,现在进入了利用鼠标修改元素位置,尺寸的模式,比如,你的鼠标点击了顶部的操作点,然后拖动它,你就能让选中的元素跟着选择。
其他的操作点,向上,向下,向左,向右,拉伸。还有四个顶点的等比例缩放,以对角点为中心进行缩放。拖动中心点或者元素的线框可以直接移动元素。

在判断选中元素时,还有一些细节,那就是,当你选中的是群组中的某一个元素后,需要将该群组选中,而不是仅仅选中当前的元素。比如导入的svg后,或者被编组的多个字体,多个元素。

在某些库里,元素内部不填充也是可以点击的,比如fabricjs的元素,但是在paperjs中,元素没有被填充,你点击元素内部是无法被选中的。

另外paperjs 的选中,鼠标命中元素,是使用hitTest方法来实现的。官方有类似的案例 http://paperjs.org/examples/hit-testing/

当你选中多个元素时,再次点击选中框的空白处,大多人期望的是,能够移动选中的元素,这个时候就需要判断当前的点击点,是不是在框选矩形中。

还有就是当你框选几个元素后,再次点击框选中的某个元素的线框,这个时候是要选中该元素还是维持框选的状态。点击之后,拖动元素哪?是拖动框选元素,还是单单拖动单个元素?

另外就是在选中元素被移动,被缩放时,框选也需要进行实时调整,调整大小和位置。

就这些细节 实现起来,够不够你喝一壶?

再加一些细节,就是选中元素上的操作点,在视图缩放,扩大或者缩小时,操作点的大小要保持物理上的不变。

另外在每次操作后,都需要添加个操作记录,这样就能够撤销,恢复啦。

总体在选择工具的实现李,有这些对象需要管理。

  • 选中的元素
  • 操作点
  • 选中元素外接矩形的管理
  • 框选状态的管理
  • 鼠标按下,拖拽,鼠标放开

总体代码 700行左右。

工具 对外保留的方法有这些
activateTool,
clearSelect,
clearHandle,
resetHandleZoom,
moveItem,
trueScaleItems,
updateItemPosition,
deleteSelectedItems,
updateSelectBounds,

移动,缩放这些方法在修改元素尺寸,位置时可以复用。

后面有时间的话在好好封装一下吧,比如把操作点的逻辑拆出去。
一个人做的比较慢,但所幸要求没那么急。
还有更多核心和基础的功能没有开发。

在做paperjs的选择工具时,我也搜索了很多相关的资料和开源项目。但目前没有一个是比较完善的。
也算是为paperjs的生态做一点小小的贡献吧。如果有人需要这个工具类,可以私信找我。

选择工具的体验地址 https://toocaastudio.com/

做项目受到很多开源项目的帮助,有时也回馈一下社区。

这是我做图形编辑器时遇到的第一个难点,但还好,paperjs的底层比较完善,所以利用提供的底api,多花些时间也能做出来一个选择工具。 做一个选择工具,也是一个非常好的面试题。

有些功能看着简单,但真正去实现时,发现有无数个细节需要处理,实现,所以对技术保持敬畏吧,凡事不要想当然,多动手,多思考。避免闭门造车,蜻蜓点水。

下一篇文章 介绍我遇到的第二个困难点, 编辑器标尺的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿我格子衫来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值