当初做图形编辑器的时,技术选型选择了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,多花些时间也能做出来一个选择工具。 做一个选择工具,也是一个非常好的面试题。
有些功能看着简单,但真正去实现时,发现有无数个细节需要处理,实现,所以对技术保持敬畏吧,凡事不要想当然,多动手,多思考。避免闭门造车,蜻蜓点水。
下一篇文章 介绍我遇到的第二个困难点, 编辑器标尺的功能。