Fabric.js制作子类别

2018-11-27 23:23:10
1294次阅读
0个评论
我们知道 Fabricjs 是以物件為主的设计理念,其实原本预设的物件就也有继承的概念了,像是 IText 是继承於 Text 类别。

今天就来练习如何去创建自己的类别吧,并继承子类别的方法。

利用 fabric.util.createClass

可以使用 Fabricjs 所提供的 fabric.util.createClass 方法,来建立一个新的类别,并且指定继承的类别。

建立类别

透过 fabric.util.createClass 建立新的类别。

const MyRect = new fabric.util.createClass({
  initialize (height, width) {
    this.height = height || 100
    this.width = width || 100
    console.log(height, width)
  },
  getArea () {
    return this.height * this.width
  }
})
console.log(MyRect)
const rect = new MyRect(100, 100)
console.log(rect.getArea()) // 10000

建立类别后我们想要使用 canvas.add() 加入我们刚刚创造的物件。

canvas.add(rect) // error

会发现错误

TypeError: t._set is not a function
这是因為 canvas.add() 时会用到原本预设 Fabricjs 建立的方法,而我们透过 fabric.util.createClass 所建立的类别并没有这些方法,导致 add 失败。

那我们该要如何解决这个问题呢?

透过继承原本 Fabricjs 提供的类别

fabric.util.createClass 可加入要继承哪个类别的参数。

我们只要在一开始指定创造类别时指定要继承哪个类别就可以了。

const MyRect = new fabric.util.createClass(fabric.Rect, {
    ...
})

这样一来我们的 MyRect 就能继承 fabric.Rect 囉,这样使用 canvas.add() 就不是问题了。

但我们还想要让自己的物件更有特色,该要怎麼做呢?

改变原本的方法

我们可以透过改变原有 fabricjs 类别的 _render() 方法,来改变物件被 Render 出来的样子。

并且透过 callSuper() 这个方法来呼叫父类别原有的 _render() 方法,这样就不用自己重新画出原本的图形囉。

fabric.util.createClass(fabric.Rect, {
  ...
  // 更改原有的 _render 方法
  _render (ctx) {
    // 先画出原本的图形
    this.callSuper('_render', ctx)
  }

例如今天我们做出一个矩形上能够有字体。

const MyRect = new fabric.util.createClass(fabric.Rect, {
  ...
  _render (ctx) {
    // 先印出原有的矩形
    // 再增加自己想要的形状
    this.callSuper('_render', ctx)
    ctx.font = '30px Arial'
    ctx.fillStyle = 'black'
    ctx.textAlign = 'center'
    ctx.fillText('Hello', 0, 10)
  }
})

这边可取得 ctx 来让我们能够使用原生 canvas 原生 api,使用上的弹性非常大!

但这裡的 text 是写死的,我们来试著修改 initialize 方法,透过在 new 时传入物件,就像我们新增一个矩形那样。

如下面那样,自订属性,并且把长宽都固定在 100

// 想要像这样
// 长宽不指定会有预设值 100
new MyRect({
  text: 'Hello',
  textColor: 'black'
})

给定预设值和使用自订属性

我们传入一个 options 物件,并且先呼叫父类别的 initialize 方法,把原本该有的像是 heigth、width ... 方法给加上去。

再来使用给定预设值被且匯入,到类别中。

而在 _render 函数中,我们就可以使用我们刚刚所定义的自订属性 text、textColor 囉!

const MyRect = new fabric.util.createClass(fabric.Rect, {
  initialize (options) {
    // 使用原方法匯入属性
    this.callSuper('initialize', options)
    // 并且给定预设值
    const def = {
      width: 100,
      height: 100,
      text: 'NONO',
      textColor: 'white'
    }
    Object.assign(this, def, options)
  },
  // 更改原有的 _render 方法
  _render (ctx) {
    this.callSuper('_render', ctx)
    ctx.font = '30px Arial'
    ctx.fillStyle = this.textColor
    ctx.textAlign = 'center'
    ctx.fillText(this.text, 0, 10)
  }
})

在来我们就能够使用 canvas.add() 新增我们所 new 出来的物件囉。

const rect = new MyRect({
  text: 'OH',
  textColor: 'red'
})
canvas.add(rect)

结果


本日小结

了解如何透过继承建立 fabricjs 的类别。

以及建立类别时的一些需要注意到的小地方:

更改 _render 函数来变化绘製出来的图形。
更改 initialize 函数,来自订属性和设定预设值。
使用 this.callSuper('fn') 预先来呼叫父类别的方法,省我们重复再做一次的麻烦。
收藏00

登录 后评论。没有帐号? 注册 一个。