Fabric.js 喷雾笔刷 从入门到放肆


theme: smartblue

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第18篇文章,点击查看活动详情


本文简介

点赞 + 关注 + 收藏 = 学会了

喷雾笔刷 SprayBrushfabric.js 提供的一个很好玩的工具,而且 fabric.js 也封装好了很多非常方便的属性让我们配置,用起来非常简单的。

先看看效果:

常规配置

喷雾笔刷作为一款笔刷工具,要使用它首先要让画布开启“绘画模式”。

isDrawingMode 设为 true 就可以开启。

Fabric.js 喷雾笔刷 从入门到放肆_第1张图片

```html

```

如果不在画布初始化时开启绘画模式,也可以之后再开启

js canvas.isDrawingMode = true

如果想切换回普通模式,只需把 isDrawingMode 改回 false 即可。

注册喷雾笔刷

喷雾笔刷叫 SprayBrush

注册喷雾笔刷时需要把初始化的画布传进去,然后再赋值给 canvas.freeDrawingBrush

Fabric.js 喷雾笔刷 从入门到放肆_第2张图片

```js // 省略部分代码

canvas.freeDrawingBrush = new fabric.SprayBrush(canvas)

// 更推荐的写法 let sprayBrush = new fabric.SprayBrush(canvas) canvas.freeDrawingBrush = sprayBrush ```

我更推荐把 sprayBrush 保存到一个变量里,这样比较方便之后配置各种效果。

除了上面这种写法,也可以这样写:

```js // 省略部分代码

let sprayBrush = new fabric.SprayBrush() sprayBrush.initialize(canvas) canvas.freeDrawingBrush = sprayBrush ```

initialize()SprayBrush 初始化的一个方法,里面接收的参数是当前的画布 canvas

设置笔刷粗细

为了方便其他属性演示,所以先把笔刷的宽度设置大点。

Fabric.js 喷雾笔刷 从入门到放肆_第3张图片

```js // 省略部分代码

sprayBrush.width = 200 ```

width 属性就是用来设置画笔粗细的,数值越大画笔就越粗。

设置喷雾密度

可以使用 density 属性设置喷雾密度,数值越大密度就越大。

density 的默认值是 20。

```js // 省略部分代码

sprayBrush.width = 200 sprayBrush.density = 100 // 设置喷雾密度 ```

density 设置得小点对比一下

js sprayBrush.width = 200 sprayBrush.density = 10

Fabric.js 喷雾笔刷 从入门到放肆_第4张图片

很直观的看到差距了。

设置喷点大小

“喷点” 就是喷雾中的每一个点,设置喷点宽度的属性名叫 dotWidth

dotWidth 默认值是 1。数值越大,喷点就越大。

Fabric.js 喷雾笔刷 从入门到放肆_第5张图片

```js // 省略部分代码

sprayBrush.width = 200 // 设置喷雾宽度

sprayBrush.dotWidth = 10 // 设置喷点大小 ```

设置喷点方差

可以使用 dotWidthVariance 属性设置喷点的方差。

dotWidthVariance 可以在规定范围内随机生成大小不一的喷点。

dotWidthVariance 的默认值是1。数值越大,喷点随机大小就越大。

Fabric.js 喷雾笔刷 从入门到放肆_第6张图片

```js // 省略部分代码

sprayBrush.width = 200 sprayBrush.dotWidthVariance = 10 ```

设置了 dotWidthVariance 后,dotWidth 的意义就不大了。

防重叠

喷雾笔刷默认是会删除重叠的点,官方文档说这是处于性能考虑的原因。

如果不希望删除重叠的点,可以将 optimizeOverlapping 设为 false

```js // 省略部分代码

sprayBrush.optimizeOverlapping = false ```

设置喷点的随机不透明度

可以通过 randomOpacity 属性设置喷点的不透明度是否随机。

```js // 省略部分代码

sprayBrush.randomOpacity = true ```

设置喷雾阴影

在喷雾笔刷的文档里没提到阴影,但既然基础笔刷可以设置阴影,喷雾笔刷同样也可以设置阴影的。

```js // 省略部分代码

sprayBrush.width = 200 sprayBrush.dotWidthVariance = 10

// 设置阴影效果 sprayBrush.shadow = new fabric.Shadow({ blur: 10, offsetX: 10, offsetY: 10, color: '#30e3ca' }) ```

设置喷雾颜色

喷雾笔刷可以通过 color 设置喷雾颜色的,但官方文档好像忘了写这个属性了。

Fabric.js 喷雾笔刷 从入门到放肆_第7张图片

```js // 省略部分代码

sprayBrush.color = 'pink' ```

事件

前面讲到 initialize() 方法可以初始化画笔,除此之外喷雾笔刷还有其他事件方法。

喷雾准备生成前和生成后

喷雾也是一种路径,所以可以监听 canvas 的路径生成时的周期。

在喷雾准备生成前,可以监听 before:path:created ;喷雾生成后,可以监听 path:created

```js // 省略部分代码

// 准备生成前 canvas.on('before:path:created', opt => { console.log(opt.path) })

// 生成后 canvas.on('path:created', opt => { console.log(opt.path) }) ```

鼠标按下时 onMouseDown

js sprayBrush.onMouseDown = function(t) { this.sprayChunks.length = 0, this.canvas.clearContext(this.canvas.contextTop), this._setShadow(), this.addSprayChunk(t), this.render(this.sprayChunkPoints) }

鼠标移动时 onMouseMove

js sprayBrush.onMouseMove = function(t) { !0 === this.limitedToCanvasSize && this._isOutSideCanvas(t) || (this.addSprayChunk(t), this.render(this.sprayChunkPoints)) }

松开鼠标时 onMouseUp

js sprayBrush.onMouseUp = function() { var t = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = !1; for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++) for (var n = this.sprayChunks[i], s = 0, o = n.length; s < o; s++) { var a = new fabric.Rect({ width: n[s].width, height: n[s].width, left: n[s].x + 1, top: n[s].y + 1, originX: "center", originY: "center", fill: this.color }); e.push(a) } this.optimizeOverlapping && (e = this._getOptimizedRects(e)); var c = new fabric.Group(e); this.shadow && c.set("shadow", new fabric.Shadow(this.shadow)), this.canvas.fire("before:path:created", { path: c }), this.canvas.add(c), this.canvas.fire("path:created", { path: c }), this.canvas.clearContext(this.canvas.contextTop), this._resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.requestRenderAll() }

注意上面的注释,找到 circle 那段就是本例的重点


以上就是喷雾的基础用法,如果都搞明白了,那就做2个案例练练手呗~

修改喷点图形

喷雾的生成其实关键是在 onMouseUp 事件。

我们看到官方的代码中,生成喷雾使用了 Reat 元素作为喷点

我有个大胆的想法,如果把 Rect 改成其他元素是否可以生成其他图形的喷雾呢?

于是我用了 圆形 Circle

Fabric.js 喷雾笔刷 从入门到放肆_第8张图片

```js // 省略部分代码

sprayBrush.onMouseUp = function() { var t = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = !1; for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++) for (let n = this.sprayChunks[i], s = 0, o = n.length; s < o; s++) {

// 改成圆形喷头 !!!!!!!!!!!!!!!!!
  const circle = new fabric.Circle({
    radius: n[s].width,
    top: n[s].y + 1,
    left: n[s].x + 1,
    originX: "center",
    originY: "center",
    fill: this.color
  })
  e.push(circle)
}

this.optimizeOverlapping && (e = this.getOptimizedRects(e)); let c = new fabric.Group(e); this.shadow && c.set("shadow", new fabric.Shadow(this.shadow)), this.canvas.fire("before:path:created", { path: c }), this.canvas.add(c), this.canvas.fire("path:created", { path: c }), this.canvas.clearContext(this.canvas.contextTop), this.resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.requestRenderAll() } ```

注意上面的代码注释,搜索 Circle 那行看看吧,这是修改喷点图形的关键点。

这个圆形喷雾是不是有点像 圆形笔刷 CircleBrush 的效果~

喷点除了改成圆形,还可以设置成其他图形,其他图形可以查看 Fabric.js 入门 - 基础图形 。

甚至还能自定义图形。

Fabric.js 喷雾笔刷 从入门到放肆_第9张图片

要实现这种自定义图形,可以查看 Fabric.js 自定义子类,创建属于自己的图形 ,然后在 onMouseUp() 事件中,把图形改成自己创建的那个即可。

随机色喷雾

理解了前面 “修改喷点图形” 的话,那要搞个随机色喷雾也是洒洒水啦~

只需把每个图形的 fill 设置成不一样就行了。

Fabric.js 喷雾笔刷 从入门到放肆_第10张图片

```js sprayBrush.onMouseUp = function() { var t = this.canvas.renderOnAddRemove; this.canvas.renderOnAddRemove = !1; for (var e = [], i = 0, r = this.sprayChunks.length; i < r; i++) for (let n = this.sprayChunks[i], s = 0, o = n.length; s < o; s++) {

// 每个点都生成自己的随机色(rgb)!!!!!!!!!!!!!!!
  let r = Math.floor(Math.random() * 255)
  let g = Math.floor(Math.random() * 255)
  let b = Math.floor(Math.random() * 255)

  let rect = new fabric.Rect({
    width: n[s].width,
    height: n[s].width,
    left: n[s].x + 1,
    top: n[s].y + 1,
    originX: "center",
    originY: "center",
    fill: `rgb(${r}, ${g}, ${b})` // 每个图形的填充色都不一样了!!!!!!!!!!!
  });
  e.push(rect)
}

this.optimizeOverlapping && (e = this.getOptimizedRects(e)); let c = new fabric.Group(e); this.shadow && c.set("shadow", new fabric.Shadow(this.shadow)), this.canvas.fire("before:path:created", { path: c }), this.canvas.add(c), this.canvas.fire("path:created", { path: c }), this.canvas.clearContext(this.canvas.contextTop), this.resetShadow(), this.canvas.renderOnAddRemove = t, this.canvas.requestRenderAll() } ```

好了,上面这个案例其实只是提供一个思路。这种随机色的配色是真的丑。。。

代码仓库

⭐ 喷雾笔刷

推荐阅读

《Fabric.js 从入门到_ _ _ _ _ _》

《Fabric.js 铅笔笔刷》

《Fabric.js 拖拽平移画布》

《Fabric.js 使用图片遮盖画布(前景图)》

点赞 + 关注 + 收藏 = 学会了

你可能感兴趣的:(javascript,fabric,前端,html,css)