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

2022-09-23 10:28:42 浏览数 (1)

本文简介

点赞 关注 收藏 = 学会了

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

先看看效果:

常规配置

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

isDrawingMode 设为 true 就可以开启。

代码语言:javascript复制
<canvas id="c" width="500" height="400" style="border: 1px solid #ccc;"></canvas>

<script>
  // 初始化
  const canvas = new fabric.Canvas('c', {
    isDrawingMode: true
  })
</script>

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

代码语言:javascript复制
canvas.isDrawingMode = true

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

注册喷雾笔刷

喷雾笔刷叫 SprayBrush

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

代码语言:javascript复制
// 省略部分代码

canvas.freeDrawingBrush = new fabric.SprayBrush(canvas)

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

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

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

代码语言:javascript复制
// 省略部分代码

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

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

设置笔刷粗细

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.width = 200

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

设置喷雾密度

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

density 的默认值是 20。

代码语言:javascript复制
// 省略部分代码

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

density 设置得小点对比一下

代码语言:javascript复制
sprayBrush.width = 200
sprayBrush.density = 10

很直观的看到差距了。

设置喷点大小

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

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

代码语言:javascript复制
// 省略部分代码

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

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

设置喷点方差

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

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

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.width = 200
sprayBrush.dotWidthVariance = 10

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

防重叠

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

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.optimizeOverlapping = false

设置喷点的随机不透明度

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.randomOpacity = true

设置喷雾阴影

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.width = 200
sprayBrush.dotWidthVariance = 10

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

设置喷雾颜色

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

代码语言:javascript复制
// 省略部分代码

sprayBrush.color = 'pink'

事件

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

喷雾准备生成前和生成后

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

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

代码语言:javascript复制
// 省略部分代码

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

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

鼠标按下时 onMouseDown

代码语言:javascript复制
sprayBrush.onMouseDown = function(t) {
  this.sprayChunks.length = 0,
  this.canvas.clearContext(this.canvas.contextTop),
  this._setShadow(),
  this.addSprayChunk(t),
  this.render(this.sprayChunkPoints)
}

鼠标移动时 onMouseMove

代码语言:javascript复制
sprayBrush.onMouseMove = function(t) {
  !0 === this.limitedToCanvasSize &amp;&amp; this._isOutSideCanvas(t) || (this.addSprayChunk(t),
  this.render(this.sprayChunkPoints))
}

松开鼠标时 onMouseUp

代码语言:javascript复制
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 &amp;&amp; (e = this._getOptimizedRects(e));
  var c = new fabric.Group(e);
  this.shadow &amp;&amp; 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个案例练练手呗~

0 人点赞