前端开源的canvas工具库Fabric.js
/ 创建自定义箭头对象},// 绘制箭头头部ctx.save();ctx.fill();});// 添加到画布});// 添加自定义控制点x: 0.5,y: -0.5,// 自定义处理逻辑},// 自定义渲染},});
·
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 元素一样直观,同时提供了专业级的图形处理能力。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)