Fabric.js制作子类别
2018-11-27 23:23:10
1378次阅读
0个评论
我们知道 Fabricjs 是以物件為主的设计理念,其实原本预设的物件就也有继承的概念了,像是 IText 是继承於 Text 类别。
今天就来练习如何去创建自己的类别吧,并继承子类别的方法。
利用 fabric.util.createClass
可以使用 Fabricjs 所提供的 fabric.util.createClass 方法,来建立一个新的类别,并且指定继承的类别。
建立类别
透过 fabric.util.createClass 建立新的类别。
建立类别后我们想要使用 canvas.add() 加入我们刚刚创造的物件。
会发现错误
TypeError: t._set is not a function
这是因為 canvas.add() 时会用到原本预设 Fabricjs 建立的方法,而我们透过 fabric.util.createClass 所建立的类别并没有这些方法,导致 add 失败。
那我们该要如何解决这个问题呢?
透过继承原本 Fabricjs 提供的类别
fabric.util.createClass 可加入要继承哪个类别的参数。
我们只要在一开始指定创造类别时指定要继承哪个类别就可以了。
这样一来我们的 MyRect 就能继承 fabric.Rect 囉,这样使用 canvas.add() 就不是问题了。
但我们还想要让自己的物件更有特色,该要怎麼做呢?
改变原本的方法
我们可以透过改变原有 fabricjs 类别的 _render() 方法,来改变物件被 Render 出来的样子。
并且透过 callSuper() 这个方法来呼叫父类别原有的 _render() 方法,这样就不用自己重新画出原本的图形囉。
例如今天我们做出一个矩形上能够有字体。
这边可取得 ctx 来让我们能够使用原生 canvas 原生 api,使用上的弹性非常大!
但这裡的 text 是写死的,我们来试著修改 initialize 方法,透过在 new 时传入物件,就像我们新增一个矩形那样。
如下面那样,自订属性,并且把长宽都固定在 100
给定预设值和使用自订属性
我们传入一个 options 物件,并且先呼叫父类别的 initialize 方法,把原本该有的像是 heigth、width ... 方法给加上去。
再来使用给定预设值被且匯入,到类别中。
而在 _render 函数中,我们就可以使用我们刚刚所定义的自订属性 text、textColor 囉!
在来我们就能够使用 canvas.add() 新增我们所 new 出来的物件囉。
结果
本日小结
了解如何透过继承建立 fabricjs 的类别。
以及建立类别时的一些需要注意到的小地方:
更改 _render 函数来变化绘製出来的图形。
更改 initialize 函数,来自订属性和设定预设值。
使用 this.callSuper('fn') 预先来呼叫父类别的方法,省我们重复再做一次的麻烦。
今天就来练习如何去创建自己的类别吧,并继承子类别的方法。
利用 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