共计 7145 个字符,预计需要花费 18 分钟才能阅读完成。
mini-programs-rc
github https://github.com/fyuanz/min…
npm https://www.npmjs.com/package…
欢送交换
个性
- 高性能且松耦合的渲染架构
- 超轻量级的代码体积
- 反对 Canvas 元素治理
- 反对 Canvas 元素事件体系
- 齐备的 group 嵌套体系
- 反对能够变形的 clip 裁剪体系
- 内置文本、位图、绘图对象和多种矢量绘制对象
- 内置图片加载器
快捷拜访
- 一分钟入门应用
- 查看我的项目示例或二次开发
-
内置对象
-
Group
-
Group 办法
- add
- remove
- empty
- replace
-
-
Stage
-
Stage 办法
- update
- setHitCanvas
- getTextWidth
- loadImage
-
- Bitmap
-
Text
-
Text 办法
- getWidth
-
- Graphics
-
Shape
- Rect
- Circle
- Ellipse
-
-
属性
- Transform
- Alpha
- CompositeOperation
- Shadow
- Stage
-
办法
- destroy
- 事件
- 裁剪
-
自定义对象
- 自定义 Shape
- 自定义 Element
- 图片加载器
- 注意事项
- License
一分钟入门应用
下载本我的项目到本地,通过 npm 下载依赖,而后应用命令 npm run build
构建
拷贝 dist 目录下的 mian.js 到微信小程序我的项目中。
在 page 或者 component 中应用
在的 wxml 里申明 canvas 和申明点击事件判断的 canvas
小程序不反对虚构 canvas,点击事件判断由 hit-canvas 渲染判断
<view class="container">
<view class="container">
<canvas
bindtouchend="touchend"
bindtouchmove="touchmove"
bindtouchstart="touchstart"
class="canvas"
id="canvas"
style="width:{{width}}px;height:{{height}}px"
type="2d"
></canvas>
<!-- 暗藏 hit-canvas -->
<canvas
class="hit-canvas"
id="hitCanvas"
style="width:{{width}}px;height:{{height}}px"
type="2d"
></canvas>
</view>
</view>
在 wxss 中暗藏 class=”hit-canvas”
.hit-canvas {
position: fixed;
top: -999rpx;
left: -999rpx;
}
在 js 中引入并初始化我的项目
import mprc from 'main.js';
const {Stage, Group, Graphics, Rect, Circle} = mprc;
Page({
data: {
width: 375,
height: 300
},
onReady: async function () {const canvas = await this.getContainer('#canvas');
const stage = new Stage(canvas, this.data.width, this.data.height);
const hitCanvas = await this.getContainer('#hitCanvas');
stage.setHitCanvas(hitCanvas);
},
// 事件监听
touchstart: function (event) {stage.touchStartHandler(event);
},
touchmove: function (event) {stage.touchMoveHandler(event);
},
touchend: function (event) {stage.touchEndHandler(event);
},
// 获取 canvas 对象办法
getContainer(id) {return new Promise((resolve, reject) => {const query = wx.createSelectorQuery();
query
.select(id)
.fields({node: true, size: true})
.exec(res => {const canvas = res[0].node;
resolve(canvas);
});
});
}
});
初始化我的项目后绘制内容
// 汇合容器,设置透明度
const group = new Group();
group.x = 50;
group.y = 50;
group.alpha = 0.8;
// 绘制矩形图形,设置透明度,透明度会与汇合的透明度合并展现
const rect = new Rect(100, 200, {fillStyle: '#000000'});
rect.alpha = 0.2;
rect.hitBox = [0, 0, 100, 200];
// 设置裁剪,将会对举办裁剪
const clipPath = new Graphics();
clipPath.arc(50, 50, 50, 0, Math.PI * 2);
rect.clip(clipPath);
// 绘制圆形图形,设置拖拽事件
const circle = new Circle(50, {fillStyle: 'red'});
circle.on('drag', function (event) {
circle.x += event.dx;
circle.y += event.dy;
stage.update();});
// 将矩形和圆形图形放入汇合之中
group.add(circle);
group.add(rect);
// 将汇合放入根容器
stage.add(group);
// 更新渲染
stage.update();
查看我的项目示例或二次开发
npm run watch
用微信小程序编辑器导入该我的项目下的 weapp 文件。
内置对象
Group
用于分组,group 也能够嵌套 group,父容器的属性会叠加在子属性上, 例如:
- group 的 x 是 100, group 里的 bitmap 的 x 是 200,最初 bitmap 渲染到 stage 上的 x 是 300
- group 的 alpha 是 0.7, group 里的 bitmap 的 alpha 是 0.6, 最初 bitmap 渲染到 stage 上的 alpha 是 0.42
const group = new Group();
const rect = new Rect(100, 100, {fillStyle: 'black'});
group.add(rect);
stage.add(group);
stage.update();
group 领有罕用的 add 和 remove 办法进行元素的减少和删除。先 add 的会先绘制,所有后 add 的会盖在先 add 的下面。
Group 办法
add
增加对象
group.add(child);
remove
移除对象
group.remove(child);
empty
清空子对象
group.empty();
replace
应用一个对象代替子对象
group.replace(current, pre);
Stage
最大的顶层容器,继承自 Group,所以 Group 领有的办法它全都有。
Stage 办法
update
任何元素增加到 Stage 上是看不到的,须要执行 update 办法。
任何元素属性的批改请执行 stage.update() 来更新渲染。
stage.update();
setHitCanvas
设置模仿虚构 canvas,承受一个参数 canvas 对象,用于计算像素级的 touch 事件指标。
getTextWidth
获取要渲染文字的宽度,两个参数,第一个参数是 text: String
,待绘制的文字,第二个参数是font:String
,设置的文字的款式。
loadImage
Stage 内置图片加载器,承受一个参数url: string
,返回一个 Promise 对象。
Promise 执行后果是 Image 对象,用于 bitmap 绘制。
const stage = new Stage(canvas, 200, 200);
const imgObj2 = await stage.loadImage('../logo.png');
const bitmap = new Bitmap(imgObj2);
stage.add(bitmap);
stage.updata();
Bitmap
Bitmap 承受一个参数,Image 对象的实例,不能应用 url 或者本地门路,bitmap 为同步,无回调办法。
const bitmap = new Bitmap(img);
stage.add(bitmap);
stage.update()
能够设置图片裁剪显示区域,和其余 transform 属性:
const bitmap = new Bitmap(img);
bitmap.x=50;
stage.add(bitmap);
const clipPath = new Graphics();
clipPath.rect(0, 0, 100, 200);
clipPath.x = 0;
clipPath.y = 50;
bitmap.clip(clipPath);
stage.add(bitmap);
stage.update()
Text
文本对象
const text = new Text(item.key, {
font: `normal normal 20px Arial`,
color: '#000000',
baseline: 'bottom'
});
Text 办法
getWidth
获取文本宽度
textObj.getWidth();
Graphics
绘图对象,用于应用根本的连缀形式的 Canvas 指令绘制图形。
const graphics = new Graphics();
graphics
.beginPath()
.arc(0, 0, 10, 0, Math.PI * 2)
.closePath()
.fillStyle('#f4862c')
.fill()
.strokeStyle('black')
.stroke();
graphics.x = 100;
graphics.y = 200;
stage.add(graphics);
特地留神,如果你在某个循环中执行 graphics 连缀绘制操作,请务必加上 clear() 办法,不然门路叠加到你的浏览器不堪重负:
setInterval(function () {
graphics
.clear()
.beginPath()
.arc(0, 0, 10, 0, Math.PI * 2)
.stroke();}, 16);
Shape
Rect
const rect = new Rect(200, 100, {fillStyle: 'black'});
Circle
const circle = new Circle(10);
Ellipse
const ellipse = new Ellipse(120, 20);
属性
Transform
属性名 | 形容 |
---|---|
x | 程度偏移 |
y | 竖直偏移 |
scaleX | 程度缩放 |
scaleY | 竖直缩放 |
scale | 同时设置或读取 scaleX 和 scaleY |
rotation | 旋转 |
skewX | 歪斜 X |
skewY | 歪斜 Y |
regX | 旋转基点 X |
regY | 旋转基点 Y |
Alpha
属性名 | 形容 |
---|---|
alpha | 元素的透明度 |
如果父子都设置了 alpha 会进行乘法叠加。
compositeOperation
属性名 | 形容 |
---|---|
compositeOperation | 源图像绘制到指标图像上的叠加模式 |
留神这里如果本身没有定义 compositeOperation 会进行向上查找,找到最近的定义了 compositeOperation 的父容器作为本人的 compositeOperation。
Shadow
属性名 | 形容 |
---|---|
shadow | 暗影 |
应用形式:
obj.shadow = {
color: '#42B035',
offsetX: -5,
offsetY: 5,
blur: 10
};
Stage
Name | Describe |
---|---|
stage | 或者本人所在的 stage |
应用形式:
obj.stage;
办法
destroy
销毁本人
obj.destroy();
留神:Group 销毁会销毁组中所有对象
事件
事件名 | 形容 |
---|---|
tap | 手指触摸后马上来到 |
touchstart | 手指触摸动作开始 |
touchmove | 手指触摸后挪动 |
touchend | 手指触摸动作完结 |
drag | 拖拽 |
事件触发准确到像素级。如果要应用元素的矩形区域为点击区域,则须要设置设置元素的 hitBox。
裁剪
const stage = new Stage(600, 400, 'body');
const bitmap = new Bitmap(imgObj2);
const clipPath = new Graphics();
clipPath.arc(40, 40, 25, 0, Math.PI * 2);
bitmap.clip(clipPath);
stage.add(bitmap);
应用上面的代码能够失去同样的成果:
const stage = new Stage(600, 400, 'body');
const bitmap = new Bitmap(imgObj2);
const clipPath = new Graphics();
clipPath.x = 40;
clipPath.y = 40;
clipPath.arc(0, 0, 25, 0, Math.PI * 2);
bitmap.clip(clipPath);
stage.add(bitmap);
裁剪区域同样反对所有 transform 属性(x,y,scaleX,scaleY,rotation,skewX,skewY,regX,regY)。
自定义对象
自定义 Shape
自定义 Shape 继承自 Shape:
class Sector extends Shape {constructor(r, from, to, option) {super();
this.option = option || {};
this.r = r;
this.from = from;
this.to = to;
}
draw() {this.beginPath()
.moveTo(0, 0)
.arc(0, 0, this.r, this.from, this.to)
.closePath()
.fillStyle(this.option.fillStyle)
.fill()
.strokeStyle(this.option.strokeStyle)
.lineWidth(this.option.lineWidth)
.stroke();}
}
应用 Shape:
const sector = new Sector(10, 0, Math.PI/6, {
fillStyle: 'red'
lineWidth: 2
})
stage.add(sector)
stage.update()
自定义 Element
自定义 Element 继承自 Group:
class Button extends Group {constructor (option) {super()
this.width = option.width
this.roundedRect = new RoundedRect(option.width, option.height, option.r)
this.text = new Text(option.text, {
font: option.font,
color: option.color
})
this.text.x = option.width / 2 - this.text.getWidth() / 2 * this.text.scaleX
this.text.y = option.height / 2 - 10 + 5 * this.text.scaleY
this.add(this.roundedRect, this.text)
}
}
export default Button
应用:
const button = new Button({
width: 100,
height: 40,
text: 'Click Me!'
});
个别状况下,略微简单组合体都倡议应用继承自 Group,这样利于扩大也方便管理本身外部的元件。
图片加载器
图片加载器返回 Promise
const {loadImage} = mprc;
// canvas 参数为获取的 canvas 2d 对象实例
const imgObj = await loadImage('../logo.png', canvas);
// stage 的图片加载办法
const stage = new Stage(canvas, 200, 200);
const imgObj2 = await stage.loadImage('../logo.png');
const bitmap = new bitMap(imgObj2);
stage.add(bitmap);
stage.updata();
注意事项
该我的项目参考了小程序、小游戏以及 Web 通用 Canvas 渲染引擎 Cax 和 spritejs。对 Cax 和 spritejs 开发者表示感谢。
- Cax 是跨平台我的项目,但仅反对小程序旧版本 canvas(微信已放弃保护)。本我的项目仅反对微信小程序 canvas2d,(根底库 2.9.0 以上版本)
- 我的项目的一些办法和属性与 Cax 类似,但有些不同,应用时请留神辨别
- 该我的项目初始化传入参数为 canvas 对象而不是 ID,所以应获取 canvas 对象后初始化,具体请查看示例代码
-
暂不反对的性能
- 不反对 Fixed 属性
- 不反对帧动画
- 不反对 SVG Path 渲染
- 不反对滤镜性能
我的项目轻量,应用简略,可用于对文字、图片、图形等绘制。适宜海报、拼图、图表展现等我的项目开发。
对手势相干事件有良好的反对,内置拖拽性能,反对矩形边界和像素级边界两种抉择形式。
我的项目对 canvas 的初始化采纳显示设置宽高和通过缩放适应像素密度,显示高清。
对于较为简单的我的项目,倡议通过类开发组件,即每一组件是一个类,类中蕴含本人的布局和更新办法,这样能够开发出高度复用的组件,后续也便于保护。
To do
- 帧动画