Fabric.js 学习笔记
导语
在 HTML 上想要绘制基本的简单形状的时候,通常都会使用 Canvas 进行操作。纵然 Canvas 原生API已经可以做许多事情,但在绘制复杂图形和一些特定情况需要改变图片的时候,原生的API十分复杂。
而 Fabric.js 就是解决这个问题的。
工作中的项目需要用到 Fabric.js 对用户进行个性化设置,因此,在这里对 Fabric.js 进行一些简单的记录。
安装
yarn add fabric -S# ornpm i fabric -S
也可以下载最新的 JS 文件,通过 Script标签 引入。为方便记录,以下内容全部都是使用原生的html进行演示。
使用
前面已经说了,Fabric.js 是基于Canvas的,因此,需要有一个Canvas画布。
<!-- html --><canvas id="canvas" width="900" height="900"></canvas>
实例
让Fabric.js与html上的画布联系起来,也就是创建一个fabric实例。
// 创建一个fabric实例let canvas = new fabric.Canvas("canvas");
基本形状
Fabric 提供了 7 种基本形状:
- fabric.Rect (矩形)
- fabric.triangle (三角形)
- fabric.Polygon (多边形)
- fabric.Circle (圆)
- fabric.Ellipse (椭圆)
- fabric.Line (线)
- fabric.Polyline (多条线绘制成图形)
创建图形主要分为三步:
- 创建fabric实例
- 创建图形对象
- 将图形对象添加到实例上
矩形
// 创建一个fabric实例let canvas = new fabric.Canvas("canvas");
// 创建矩形对象let rect = new fabric.Rect({ left: 200, // 距离左边距离 top: 200, // 距离上边的距离 fill: "green", // 填充的颜色 width: 200, // 矩形宽度 height: 200, // 矩形高度})
// 将矩形添加到实例上canvas.add(rect);
三角形
// 创建一个fabric实例let canvas = new fabric.Canvas("canvas");
// 创建一个三角形对象let triangle = new fabric.Triangle({ left: 200, // 距离左边的距离 top: 0, // 距离上边的距离 fill: "blue", //填充的颜色 width: 100, // 宽度 height: 100, // 高度});
// 将三角形添加到canvas画布上canvas.add(triangle);
圆形
// 创建一个fabric实例let canvas = new fabric.Canvas("canvas");
// 创建一个圆形对象let circle = new fabric.Circle({ left: 0, // 距离左边的距离 top: 0, // 距离上边的距离 fill: "red", // 填充的颜色 radius: 50, // 圆的半径});
// 将圆形添加到canvas画布上canvas.add(circle);
图形属性
| 属性 | 值 | 解释 | 备注 |
|---|---|---|---|
| height | Number | 对象的高度 | 默认值:0 |
| width | Number | 对象的宽度 | 默认值:0 |
| left | Number | 对象左边位置(X坐标) |
默认以Object中点进行计算。 可以设置originx={left|center|right}。默认0 |
| top | Number | 对象上边位置(Y坐标) | 与Left类似 |
| angle | Number | 顺时针旋转角度(以角为单位) | 默认值:0 |
| backgroundColor | String | 背景颜色 | |
| borderColor | String | 激活状态时,控制器边框颜色 | 默认值:rgba(102,153,255,0.75) |
| cornerColor | String | 激活状态时,四角的颜色 | 默认值:rgba(102,153,255,0.5) |
| cornerStrokeColor | String | 激活状态时,控制器点的颜色 | |
| cornerSize | Number | 激活状态时,控制器点的大小 | 默认值:12 |
| cornerStyle | String | 激活状态时,控制器点的央视 | 可改为“circle” |
| fill | String | 对象填充的颜色 | |
| visible | Boolean | 对象是否显示 | 默认值:True。否则不会在Canvas上渲染 |
绘制图像
URL绘制img 标签绘制
绘制图像主要分为三步:
- 创建fabric实例
- 创建图像对象
- 将图像对象添加到实例上
// 创建一个fabric实例let canvas = new fabric.Canvas("canvas");
// 通过url绘制图片fabric.Image.fromURL( "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg", (img) => { img.scale(0.5); canvas.add(img); });
// 或可以通过标签绘制let img = document.getElementById("img");let image = new fabric.Image(img, { left: 100, top: 100, opacity: 0.8,});
// 将圆形添加到canvas画布上canvas.add(image);
图像属性
| 属性 | 值 | 解释 | 备注 |
|---|---|---|---|
| height | Number | 对象的高度 | 默认值:0 |
| width | Number | 对象的宽度 | 默认值:0 |
| left | Number | 对象左边位置(X坐标) |
默认以Object中点进行计算。 可以设置originx={left|center|right}。默认0 |
| top | Number | 对象上边位置(Y坐标) | 与Left类似 |
| angle | Number | 顺时针旋转角度(以角为单位) | 默认值:0 |
| backgroundColor | String | 背景颜色 | |
| borderColor | String | 激活状态时,控制器边框颜色 | 默认值:rgba(102,153,255,0.75) |
| cornerColor | String | 激活状态时,四角的颜色 | 默认值:rgba(102,153,255,0.5) |
| cornerStrokeColor | String | 激活状态时,控制器点的颜色 | |
| cornerSize | Number | 激活状态时,控制器点的大小 | 默认值:12 |
| cornerStyle | String | 激活状态时,控制器点的央视 | 可改为“circle” |
| fill | String | 对象填充的颜色 | |
| visible | Boolean | 对象是否显示 | 默认值:True。否则不会在Canvas上渲染 |
动画
使用
// 新建一个 fabric 实例let canvas = new fabric.Canvas("canvas");
// 新建一个矩形对象let rect = new fabric.Rect({ left: 400, //距离左边的距离 top: 200, //距离上边的距离 fill: "green", //填充的颜色 width: 200, //宽度 height: 200, //高度});
// 移动动画rect.animate('left', rect.left === 25 ? 275 : 25, { duration: 1000, onChange: canvas.renderAll.bind(canvas), onComplete: function() { console.log("播放结束!"); }, easing: fabric.util.ease.easeInCubic});
// 将矩形添加到canvas画布上canvas.add(rect);
参数说明
| 参数 | 值 | 说明 | 备注 |
|---|---|---|---|
| 动画属性 | String | 可选择任意对象的自带属性 如:left, top, angle, width, height, visible等 |
必选 |
| 动画的最终状态情况 | 语句 | 动画修改的最终状态 | 必选 |
| 动画的细节 | Object | 可以指定动画的细节:持续时间,回调,动效等 | 非必选 |
根据第二个参数的值,可以将动画分为绝对动画和相对动画。
// 绝对动画:将第二个参数设置为绝对值rect.animate("left", 100, { onChange: canvas.renderAll.bind(canvas), duration: 1000,});
// 相对动画:将第二个参数通过设置 +=,-= 等来决定动画的最终效果rect.animate("left", "+=100", { onChange: canvas.renderAll.bind(canvas), duration: 1000,});
rect.set({ angle: 45 });rect.animate("angle", "-=90", { onChange: canvas.renderAll.bind(canvas), duration: 2000,});
动效
第三个参数主要有
- duration 默认为 500ms。可以用来改变动画的持续时间。
- from 允许指定动画属性的起始值(如果我们不希望使用当前值)。
- onChange 在每帧变化时重新渲染,可看到动画效果
- onComplete 动画结束之后的回调。
- easing 动效函数。可取的值是fabric.util.ease包下,有easeOutBounce, easeInCubic , easeOutCubic, easeInElastic, easeOutElastic, easeInBounce 和 easeOutExpo.
rect.animate("left", 100, { onChange: canvas.renderAll.bind(canvas), duration: 1000, easing: fabric.util.ease.easeOutBounce,});
颜色
无论你是使用十六进制,RGB 或 RGBA 颜色,Fabric 都能处理的很好
定义颜色
new fabric.Color("#f55");new fabric.Color("#aa3123");new fabric.Color("356333");new fabric.Color("rgb(100,50,100)");new fabric.Color("rgba(100, 200, 30, 0.5)");复制代码
颜色转换
new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)"new fabric.Color('rgb(100,100,100)').toHex(); // "646464"new fabric.Color('fff').toHex(); // "FFFFFF"复制代码
我们还可以用另一种颜色叠加,或将其转换为灰度版本。
let redish = new fabric.Color("#f55");let greenish = new fabric.Color("#5f5");redish.overlayWith(greenish).toHex(); // "AAAA55"redish.toGrayscale().toHex(); // "A1A1A1"复制代码
渐变
Fabric 通过 setGradient 方法支持渐变,在所有对象上定义。调用 setGradient(‘fill’, { … })就像设置一个对象的“fill”值一样。
let circle = new fabric.Circle({ left: 100, top: 100, radius: 50});
circle.setGradient("fill", { // 渐变开始的位置 x1: 0, y1: 0, // 渐变结束的位置 x2: circle.width, y2: 0, //渐变的颜色 colorStops: { // 渐变的范围(0,0.1,0.3,0.5,0.75,1)0-1之间都可以 0: "red", 0.2: "orange", 0.4: "yellow", 0.6: "green", 0.8: "blue", 1: "purple" },});
文本
fabric.Text 对象对于文本,提供了比 canvas 更丰富的功能,包括:
- 支持多行 Multiline support 不幸的是,原生文本方法忽略了新建一行。
- 文本对齐 Text alignment 左,中,右。使用多行文本时很有用。
- 文本背景 Text background 背景也支持文本对齐。
- 文字装饰 Text decoration 下划线,上划线,贯穿线。
- 行高 Line Height 在使用多行文本时有用。
- 字符间距 Char spacing 使文本更紧凑或更间隔。
- 子范围 Subranges 将颜色和属性应用到文本对象的子对象中。
- 多字节 Multibyte 支持表情符号。
- 交互式画布编辑 On canvas editing 可以直接在画布上键入文本。
let text = new fabric.Text( 莫西莫西\n我是路飞~\n一个要成为海贼王的男人!", { left: 0, top: 200, fontFamily: "Comic Sans", //字体 fontSize: 50, //字号 fontWeight: 800, //字体粗细,可以使用关键字(“normal”,“bold”)或数字(100,200,400,600,800) shadow: "green 3px 3px 2px", //文字阴影,颜色,水平偏移,垂直偏移和模糊大小。 underline: true, //下划线 linethrough: true, //删除线 overline: true, //上划线 fontStyle: "italic", //字体风格,normal(正常)或italic(斜体) stroke: "#c3bfbf", //描边的颜色 strokeWidth: 1, //描边的宽度 textAlign: "center", //文本对齐方式 lineHeight: 1.5, //行高 textBackgroundColor: "#91A8D0", //文本背景颜色 });canvas.add(text);

