开源框架Vandf重大更新:增加挂接Canvas库的能力
1.概述
Vandf从1.3版开始增加了挂接例如Pixi.js、Konva、Febric等Canvas库的能力。而且可以通过模板映射能力,实现各Canvas库在Vandf中使用标准化。也就是说:在Vandf中实现的Canvas绘图,在不更改原有代码的基础上,通过模板映射,就能方便的切换Canvas库。项目参见 vandf - npm (npmjs.com)
2.感受下用Vandf写Canvas绘图代码
那我们就来看看绘制如下一幅图的实现代码:
- 定义组件
import Pixi from "../pixi"//导入自己编写的模板库
import {Van} from "vandf"//导入Vandf库
export default function test () {//测试函数
let app = Van.new('app')//创建一个挂载点组件实例
let pixi = app.kid('container')//创建一个pixi的canvas元素的组件实例
.tag('pixi')//模板中定义了canvas节点名称
.view(PixiView)//绑定组件视图模型
let circle = pixi.kid('circle')//创建一个circle组件实例
.tag('circle')//模板中定义了circle节点名称
.view(CircleView)//绑定组件视图模型
.model(CircleModel)//绑定用户数据模型
app.attach(document.querySelector('#app'))//讲app挂在到id为app的dom元素上。
}
- 定义模型
class PixiView {
create (instance) {
instance
.style('height',160)
.style('width', 160)
.style('antialias', true)
.style('background', '#1099bb')
}
}
class CircleView {
create (instance) {
instance
.style('stroke',0x00ee44)
.style('stroke-opacity',0.87)
.style('stroke-width',d => 6*d)
.style('fill','red')
.attr('x',(d,i)=>40 + i*40)
.attr('y',(d,i)=> 40 + i*40)
.attr('radius',d => d*20)
.on('pointerdown', e=> {
console.log('click circle',instance.datum, instance.index)
},true)
}
}
class CircleModel {
supply(){return [1,2,1]}
}
从上述代码可以看出,结构简单清晰,使用非常简单,整个使用与Vandf原有的使用风格完全一致,甚至可以做到与原svg的接口做到一致,这样可以把原svg的图改一个标签即可实现无缝切换,所以,这次的版本升级是值得拥有的。
3.实现模板
我们以Pixi.js库为例来实现模板代码:
- 导入开发模板所需要的库
import {Template,Namespace} from "vandf";
import * as PIXI from "pixi.js"
- 定义PIXI.Application的模板
class Pixi extends Template{
static pixi = Namespace
.get('pixi',"https://pixijs.com/2023/canvas")//获取名称空间,local名称、uri网址随便写
.set('pixi',this)//挂载本模板,挂载名称定义为pixi,任意命名。
addChildAt(insert, index) {//定义子元素插入到本实例的方法
let parent = this.element;
parent.stage.addChildAt(insert, index)
}
build () {//构建实例并插入到父组件中
let element = this.element
if(!element){//检查是否已创建,未创建则新建并插入到父元素中
this.element = element = new PIXI.Application(this.node.styles.items);
this.parent()?.addChildAt(element.view, this.node.childIndex)
}
}
}
- 定义Graphics的模板
Graphics是所有绘图元素的基类,主要使用提取图形元素的公共部分,本模板定义了注册事件的方法。
class PixiGraphic extends Template{
static addEventListener(instance, type, listener, options) {
//如果事件名称需要映射,可以在这里将type做一下映射处理即可
let element = instance.element
if(!element){return false}
element.eventMode = 'static';
element.cursor = 'pointer';// Shows hand cursor
element.on(type, listener, options)
return true;
}
}
- 定义圆形Circle的模板
class PixiCircle extends PixiGraphic {
static circle = Namespace
.get('pixi',"https://pixijs.com/2023/canvas")//获取名称空间,必须与根模板定义一致
.set('circle',this)//挂载本模板,挂载名称定义为circle。
build () {//构建方法
if(!this.element){
let styles = this.node.styles;
let attrs = this.node.attrs;
let index = this.node.childIndex
let lineStyle = styles.filte({//实现样式过滤和名称映射
'color' : 'stroke',
'width' : 'stroke-width',
'alpha' : 'stroke-opacity'
})
let circle = attrs.toArray(['x','y','radius'])//按制定名称和顺序提取参数
this.element = new PIXI.Graphics()
.lineStyle(lineStyle)//传递线型参数
.beginFill(styles.getValue('fill',true))//传递填充参数
.drawCircle(...circle)//将圆形属性展开为参数
.endFill()
this.parent()?.addChildAt(this.element, index)//将实例插入到父元素中
}
}
}