fabric.js开发图片编辑器的细节实现

简介: 如何用vue和fabric.js快速开发一款编辑器,并利用fabric.js的api提供标准编辑器的能力。

之前写过一篇笔记,《使用fabric.js 快速开发一个图片编辑器》,简单介绍了如何用vue和fabric.js快速开发一款编辑器。

当时的版本比较粗糙,只能说是一个基础版的Demo,很多细节不够完善,参考了稿定设计和创客贴的设计编辑器,优化了很多必要的细节,也算是fabric.js的进阶用法,整理成笔记分享出来。

项目地址:https://github.com/nihaojob/vue-fabric-editor

预览地址:https://nihaojob.github.io/vue-fabric-editor/

正文

1、架构演进

最早的设计是将 fabric.js创建的canvas对象通过provide传递给子组件使用,功能代码封装到vue组件中。前期基础功能尚能满足,但后期迭代时发现无法复用功能代码,如复制功能原来以按钮的形式存在,代码全部在复制组件中,在后期迭代中要在快捷键和右键菜单中增加复制功能,没办法复用;

所以在原来的基础上,封装出Editor对象,将通用方法挂载到Editor对象上实现复用。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/bf36aa6ba093d0d603d68482d201f0c78d2b1f2c/src/core/index.js#L19

2、辅助线

辅助线是很常见的必要功能,官方提供了辅助线方法,在官方仓库中,只需要引入方法即可。

实现代码:https://github.com/fabricjs/fabric.js/blob/master/lib/aligning_guidelines.js

3、控制条样式

稿定设计和创客贴的元素控制条看起来都很精致,而fabric.js自带的控制条较为简陋,可以通过自定义样式方法把控制条修饰的稍微美观一些。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/main/src/core/initControls.js

4、右键菜单

fabric.js并没有自带右键菜单的功能,但可以监听到右键菜单事件,我们可以通过监听方法来实现右键菜单功能。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/bf36aa6ba093d0d603d68482d201f0c78d2b1f2c/src/components/mouseMenu.vue#L72

5、快捷键功能

快捷键可以提高操作效率,比如组合/拆分组合、复制、删除等,只需要将快捷键事件和Editor的功能方法做绑定即可快速实现快捷键功能。

快捷键监听有现成的工具库hotkeys-js,只需要绑定事件即可。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/main/src/core/initHotKeys.js

6、锁定图层

锁定元素可以让元素不可编辑,比如下图中的白色背景元素,设置大小和位置后就不希望再选中和它,可以设置图层锁定,这样编辑上方元素时就会干扰到下方元素。

使用selectable属性控制元素不可选中,需要注意的点是,当我们遍历所有元素时,要对锁定元素单独处理。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/bf36aa6ba093d0d603d68482d201f0c78d2b1f2c/src/components/lock.vue#L41

7、画布大小调整

最早的版本的画布大小调整就是对fabric.js的canvas大小做调整,这样做有2个问题,一是没办法将画布大小保存到json文件中,另外一个问题是缩小放画布时,缩小后画布颜色和背景颜色一致,无法区分画布的边界,效果较差。

最后的实现思路是,使用矩形元素模拟画布区域,fabric.js的canvas大小根据视口DOM的宽高自适应,通过调整矩形元素属性来设置画布到大小和颜色,其他元素通过属相面板修改属性。这样就解决了上边的2个问题。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/main/src/core/initWorkspace.js

8、元素画布超出区域

参考稿定设计和创客贴的编辑器,都有一个细节,就是当元素拖出画布区域后,看不到元素但可以展示控制条,由于画布是通过矩形模拟出来的,通过clipPath可以便捷的实现。

实现代码:https://github.com/nihaojob/vue-fabric-editor/commit/8512e3293f991dc8b2633669c4feb1514dca9a02

9、拖拽到画布

将基础元素添加到画布有两种方式,一种是点击元素,会添加到画布中央,另一种是直接拖拽元素到画布,可以将元素添加到指定位置,使用拖拽事件实现。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/bf36aa6ba093d0d603d68482d201f0c78d2b1f2c/src/components/tools.vue#L163

10、渐变配置

渐变在背景、字体颜色上很常用,fabric.js有提供渐变的配置方法,我们只需要按照纯色、渐变2种方式设置颜色即可,功能已实现,细节需要优化,没有合并到main分支。

实现代码:https://github.com/nihaojob/vue-fabric-editor/blob/f85fede86b37be0a22362cd68c346cab19ef507e/src/components/attribute.vue#L493

结尾

开源过程中遇到很多志同道合的开发者,为项目提供思路、代码、PR ,让项目从0涨到了600star,感谢大家的帮助,希望能够继续迭代,打磨成像稿定设计和创客贴一样好用的开源图形编辑器。

目前的版本仍在继续迭代,很多细节还不完善,基础功能还在补充,比如滤镜设置、图片替换、图片裁剪、字体样式模板等,还有一些文档、vue3升级、单元测试的工作。

在开发的过程中我的收获也很大,如果你也比较感兴趣,是fabric.js的爱好者或者自己也在开发类似的项目,欢迎加入交流群,期待你的Issue和PR,一起打造一款好用的设计编辑器。

致谢:

  • June 多次深夜为项目贡献代码,提供快捷键、右键菜单等功能。
  • xiaozeo 宝妈百忙中为项目提交代码,让属性面板更美观。
  • icleitoncosta 异国他乡的开发者朋友,提供了国际化功能。
  • asang28 为项目提供了vue3版本代码。
  • 晗萧℡ 会自己写编辑器的设计师,多次为项目提供代码示例。
  • RHS 为项目提供缩放思路、标尺代码。
  • 放牛哥 为项目提供代码和实现思路。
  • 冯志辉 一直在关注我们,为我们加油打气。
  • ...

篇幅有限,不再一一列举名单,感谢大家的支持与帮助,希望vue-fabric-editor在未来的日子里不负期望,和大家一起越变越好。

相关文章
|
20天前
|
开发框架 JavaScript 安全
js开发:请解释什么是Express框架,以及它在项目中的作用。
Express是Node.js的Web开发框架,简化路由管理,支持HTTP请求处理。它采用中间件系统增强功能,如日志和错误处理,集成多种模板引擎(EJS、Jade、Pug)用于HTML渲染,并提供安全中间件提升应用安全性。其可扩展性允许选用合适插件扩展功能,加速开发进程。
|
21天前
|
缓存 JavaScript 前端开发
js开发:请解释什么是Webpack,以及它在项目中的作用。
Webpack是开源的JavaScript模块打包器,用于前端项目构建,整合并优化JavaScript、CSS、图片等资源。它实现模块打包、代码分割以提升加载速度,同时进行资源优化和缓存。借助插件机制扩展功能,并支持热更新,加速开发流程。
15 4
|
21天前
|
缓存 JavaScript 数据安全/隐私保护
js开发:请解释什么是ES6的Proxy,以及它的用途。
`ES6`的`Proxy`对象用于创建一个代理,能拦截并自定义目标对象的访问和操作,应用于数据绑定、访问控制、函数调用的拦截与修改以及异步操作处理。
17 3
|
21天前
|
JavaScript
js开发:请解释什么是ES6的类(class),并说明它与传统构造函数的区别。
ES6的类提供了一种更简洁的面向对象编程方式,对比传统的构造函数,具有更好的可读性和可维护性。类使用`class`定义,`constructor`定义构造方法,`extends`实现继承,并可直接定义静态方法。示例展示了如何创建`Person`类、`Student`子类以及它们的方法调用。
20 2
|
22天前
|
自然语言处理 JavaScript 网络架构
js开发:请解释什么是ES6的箭头函数,以及它与传统函数的区别。
ES6的箭头函数以`=>`定义,简化了函数写法,具有简洁语法和词法作用域的`this`。它无`arguments`对象,不能用作构造函数,不支持`Generator`,且不改变`this`、`super`、`new.target`绑定。适用于简短表达式,常用于异步编程和高阶函数。
17 5
|
22天前
|
JavaScript 安全 前端开发
js开发:请解释什么是XSS攻击和CSRF攻击,并说明如何防范这些攻击。
XSS和CSRF是两种常见的Web安全威胁。XSS攻击通过注入恶意脚本盗取用户信息或控制账户,防范措施包括输入验证、内容编码、HTTPOnly Cookie和CSP。CSRF攻击则诱使用户执行未经授权操作,防范手段有CSRF Tokens、双重验证、Referer检查和SameSite Cookie属性。开发者应采取这些防御措施并定期进行安全审计以增强应用安全性。
18 0
|
22天前
|
JavaScript 前端开发 算法
js开发:请解释什么是虚拟DOM(virtual DOM),以及它在React中的应用。
虚拟DOM是React等前端框架的关键技术,它以轻量级JavaScript对象树形式抽象表示实际DOM。当状态改变,React不直接操作DOM,而是先构建新虚拟DOM树。通过高效diff算法比较新旧树,找到最小变更集,仅更新必要部分,提高DOM操作效率,降低性能损耗。虚拟DOM的抽象特性还支持跨平台应用,如React Native。总之,虚拟DOM优化了状态变化时的DOM更新,提升性能和用户体验。
19 0
|
21天前
|
Web App开发 JavaScript 前端开发
js开发:请解释什么是Node.js,以及它的应用场景。
Node.js是基于V8的JavaScript运行时,用于服务器端编程。它的事件驱动、非阻塞I/O模型使其在高并发实时应用中表现出色,如Web服务器、实时聊天、API服务、微服务、工具和跨平台桌面应用(使用Electron)。适用于高性能和实时需求场景。
18 4
|
21天前
|
JavaScript 前端开发 编译器
js开发: 请解释什么是Babel,以及它在项目中的作用。
**Babel是JavaScript编译器,将ES6+代码转为向后兼容版本,确保在旧环境运行。它在前端构建中不可或缺,提供语法转换、插件机制、灵活配置及丰富的生态系统,支持代码兼容性和自定义编译任务。**
17 6
|
21天前
|
JavaScript 前端开发
js开发:请解释什么是ES6的async/await,以及它如何解决回调地狱问题。
ES6的`async/await`是基于Promise的异步编程工具,能以同步风格编写异步代码,提高代码可读性。它缓解了回调地狱问题,通过将异步操作封装为Promise,避免回调嵌套。错误处理更直观,类似同步的try...catch。