做为一个pixi.js,p5.js等图形库的使用者,我以为他们的上手成本体如今:git
1.你得先去学习它们库的语法与层级/事件概念。github
2.在没读源码前它们就是一个黑盒,出了奇怪的bug难以去定位,网上的中文经验也不多,要想把它们使用好须要时间去积累经验。canvas
3.不少时候我仅仅只是想去实现并不复杂的canvas互动效果,却要引用一个很是大的库。api
这个库就是为了解决这些矛盾,它的特色是:app
下面是这个库的使用实例dom
let app = new Moa.App(document.querySelector(".stage"));
let rect = app.Obj(200, 200, 100, 100, ctx => {
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 100, 100);
});
rect.on("mouseenter", function(e) {
this.draw = ctx => {
ctx.fillStyle = "#c0ebff";
ctx.fillRect(0, 0, 100, 100);
};
});
app.run()
复制代码
draw
函数完成视图的变换。对于一个熟悉原生canvas语法的人来讲几乎没有上手成本。
在这个库中,全部可视的东西都是由绘图对象Obj
组成,咱们调用app.Obj
便可新生成一个绘图对象,它的参数分别是此对象的起始坐标x
,此对象的起始坐标y
,此对象的碰撞区域宽度width
,此对象的碰撞区域高度height
,此对象的绘图函数draw
,以及一个可选参数此对象的层级zIndex
。函数
在上面的例子中,有这样一段代码学习
ctx => {
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 100, 100);
}
复制代码
这个回调函数会被注册为此Obj
的绘图函数draw
,而在实际调用时,这个ctx并非canvas.getContext('2d')
获得的ctx,而是它的变异,它全部方法必要的坐标都变成了相对坐标。ui
下面展现了一段将这个对象变为可拖拽对象的代码this
let ifDrag = false;
const p = {
x: undefined,
y: undefined
};
rect.on("mousedown", function(e) {
ifDrag = true;
p.x = e.x;
p.y = e.y;
});
rect.on("mouseup", function(e) {
ifDrag = false;
});
rect.on("mousemove", function(e) {
if (ifDrag) {
this.x += e.x - p.x;
this.y += e.y - p.y;
p.x = e.x;
p.y = e.y;
}
});
复制代码
支持["click", "mousemove", "mouseup", "mousedown", "mouseover", "mouseenter", "mouseleave"]
注意这里只有调用了Obj.on("eventname", cb)
的Obj
才会被加入下面的层级比较中,若是历来没有调用过on
方法,那么这个Obj在层级中是一个可穿透的对象。
这个库中的层级分为三个层级,低层级,普通层级,高层级。没有设置zIndex默认为普通层级。
好比这样创造一个Obj
let rect = app.Obj(200, 200, 100, 100, ctx => {
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 100, 100);
}, 1);
复制代码
最后多了一个参数1
做为zIndex
,若果它大于0,则会被推入高层级,undefined
则会推入普通层级,小于0则会推入低层级。渲染时会先根据zIndex渲染低层级,再根据普通层级的生成顺序渲染普通层级,最后再根据zIndex渲染高层级。
事件也一样遵循和渲染同样的前后顺序,两个Obj
重叠,只会触发层级最高的那一个的事件。
完善中,bug不知道还有多少,欢迎issue。