一文详解前端开源的canvas工具库Fabric.js
作者:许于宝的博客
Fabric.js是一个功能强大且操作简单的Javascript HTML5 canvas 工具库,这篇文章主要介绍了前端开源canvas工具库Fabric.js的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
Fabric.js 是一个功能强大的 HTML5 Canvas 库,它通过面向对象的方式简化了 Canvas 操作,为开发者提供了丰富的图形操作功能和直观的 API 接口。
一、核心特性
1. 基础能力
- 完整的对象模型:将画布元素抽象为对象(矩形、圆形、路径等)
- 交互式操作:内置支持拖拽、旋转、缩放等交互
- 丰富的图形类型:支持路径、图像、文本、组等
- 动画系统:提供流畅的动画支持
- 滤镜效果:内置多种图像滤镜
- 序列化/反序列化:支持 JSON 导入导出
2. 高级功能
- 自由绘制:铅笔、喷枪等绘画工具
- SVG 支持:解析和渲染 SVG
- 事件系统:完善的鼠标/触摸事件
- 裁剪和蒙版:支持复杂裁剪操作
- 自定义扩展:可扩展新的对象类型和功能
二、基本架构
1. 核心类结构
2. 对象继承体系
fabric.Object
:所有图形基类fabric.Rect
:矩形fabric.Circle
:圆形fabric.Triangle
:三角形fabric.Text
:文本fabric.Image
:图像fabric.Path
:路径fabric.Group
:对象组fabric.ActiveSelection
:活动选择组
三、核心 API 详解
1. 画布初始化
// 创建画布实例 const canvas = new fabric.Canvas('canvas-id', { width: 800, // 画布宽度 height: 600, // 画布高度 backgroundColor: '#f5f5f5', // 背景色 selection: true, // 是否启用选择 preserveObjectStacking: true // 保持对象堆叠顺序 });
2. 基本图形创建
// 创建矩形 const rect = new fabric.Rect({ left: 100, top: 100, width: 200, height: 100, fill: 'red', angle: 45, stroke: 'black', strokeWidth: 2 }); // 创建圆形 const circle = new fabric.Circle({ radius: 50, fill: 'blue', left: 300, top: 200 }); // 添加对象到画布 canvas.add(rect, circle); canvas.renderAll(); // 渲染更新
3. 交互功能
// 对象选择事件 canvas.on('selection:created', (e) => { console.log('选中对象:', e.selected); }); // 对象移动事件 canvas.on('object:moving', (e) => { console.log('移动对象:', e.target); }); // 对象缩放事件 canvas.on('object:scaling', (e) => { console.log('缩放对象:', e.target); });
四、高级功能实现
1. 自由绘制实现
// 启用自由绘制 canvas.isDrawingMode = true; // 配置画笔 canvas.freeDrawingBrush = new fabric.PencilBrush(canvas); canvas.freeDrawingBrush.width = 5; canvas.freeDrawingBrush.color = '#000000'; // 绘制完成事件 canvas.on('path:created', (e) => { console.log('绘制路径:', e.path); });
2. 动画系统
// 简单动画 rect.animate('angle', 360, { duration: 1000, onChange: canvas.renderAll.bind(canvas), easing: fabric.util.ease.easeInOutQuad }); // 复杂动画 fabric.util.animate({ startValue: 0, endValue: 100, duration: 500, onChange: (value) => { circle.set('left', value); canvas.renderAll(); }, onComplete: () => { console.log('动画完成'); } });
3. 滤镜应用
// 创建图像对象 fabric.Image.fromURL('image.jpg', (img) => { // 添加滤镜 img.filters.push( new fabric.Image.filters.Grayscale(), new fabric.Image.filters.Brightness({ brightness: 0.2 }) ); img.applyFilters(); canvas.add(img); });
五、性能优化技巧
1. 渲染优化
// 批量操作时暂停渲染 canvas.renderOnAddRemove = false; // 执行多个操作... canvas.renderOnAddRemove = true; canvas.renderAll(); // 使用 requestAnimationFrame function animate() { requestAnimationFrame(() => { // 更新对象属性 canvas.renderAll(); animate(); }); }
2. 内存管理
// 移除对象时彻底销毁 canvas.remove(object); object = null; // 清理画布 canvas.dispose();
3. 大数据量优化
// 使用对象缓存 object.set({ objectCaching: true, dirty: false }); // 按需渲染 canvas.onlyRenderOnRequest = true; canvas.requestRenderAll();
六、扩展开发
1. 自定义对象
// 创建自定义箭头对象 fabric.Arrow = fabric.util.createClass(fabric.Line, { type: 'arrow', initialize: function(points, options) { options || (options = {}); this.callSuper('initialize', points, options); }, _render: function(ctx) { this.callSuper('_render', ctx); // 绘制箭头头部 ctx.save(); const xDiff = this.x2 - this.x1; const yDiff = this.y2 - this.y1; const angle = Math.atan2(yDiff, xDiff); ctx.translate(this.x2, this.y2); ctx.rotate(angle); ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(-10, -5); ctx.lineTo(-10, 5); ctx.closePath(); ctx.fillStyle = this.stroke; ctx.fill(); ctx.restore(); } }); // 添加到画布 const arrow = new fabric.Arrow([50, 50, 200, 200], { stroke: 'red', strokeWidth: 3 }); canvas.add(arrow);
2. 自定义控件
// 添加自定义控制点 fabric.Object.prototype.controls.customControl = new fabric.Control({ x: 0.5, y: -0.5, actionHandler: function(eventData, transform, x, y) { // 自定义处理逻辑 }, render: function(ctx, left, top, styleOverride, fabricObject) { // 自定义渲染 }, cornerSize: 15 });
七、实际应用场景
1. 图形编辑器实现
// 工具栏功能实现 document.getElementById('btn-rect').addEventListener('click', () => { const rect = new fabric.Rect({ width: 100, height: 100, fill: '#ff0000' }); canvas.add(rect); }); // 属性面板绑定 document.getElementById('color-picker').addEventListener('change', (e) => { const active = canvas.getActiveObject(); if (active) { active.set('fill', e.target.value); canvas.renderAll(); } });
2. 图像标注系统
// 标注工具 let drawingMode = 'rect'; let currentAnnotation = null; canvas.on('mouse:down', (o) => { if (drawingMode === 'rect') { currentAnnotation = new fabric.Rect({ left: o.absolutePointer.x, top: o.absolutePointer.y, width: 0, height: 0, fill: 'rgba(255,0,0,0.2)', stroke: 'red', strokeWidth: 1, selectable: true }); canvas.add(currentAnnotation); } }); canvas.on('mouse:move', (o) => { if (currentAnnotation) { currentAnnotation.set({ width: o.absolutePointer.x - currentAnnotation.left, height: o.absolutePointer.y - currentAnnotation.top }); canvas.renderAll(); } });
3. 流程图设计器
// 连接线实现 class Connector extends fabric.Line { constructor(from, to, options) { super([from.left, from.top, to.left, to.top], options); this.from = from; this.to = to; this.set({ stroke: '#666', strokeWidth: 2, selectable: false, evented: false }); } update() { this.set({ x1: this.from.left + this.from.width/2, y1: this.from.top + this.from.height/2, x2: this.to.left + this.to.width/2, y2: this.to.top + this.to.height/2 }); } } // 自动更新连接线 canvas.on('object:moving', () => { canvas.forEachObject(obj => { if (obj instanceof Connector) { obj.update(); } }); });
Fabric.js 是一个功能全面且灵活的 Canvas 库,通过其丰富的 API 和事件系统,开发者可以构建从简单的图形编辑器到复杂的可视化应用的各类 Canvas 应用。它的面向对象设计模式使得操作 Canvas 元素就像操作 DOM 元素一样直观,同时提供了专业级的图形处理能力。
总结
到此这篇关于前端开源canvas工具库Fabric.js的文章就介绍到这了,更多相关开源canvas工具库Fabric.js内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!