赞
踩
一个轻量级的微信小程序 Canvas (type="2d") 渲染引擎
高性能且松耦合的渲染架构
超轻量级的代码体积
支持 Canvas 元素管理
支持 Canvas 元素事件体系
完备的 group 嵌套体系
支持可以变形的 clip 裁剪体系
内置文本、位图、绘图对象和多种矢量绘制对象
内置图片加载器
下载本项目到本地,通过 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>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
在 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);
- });
- });
- }
- });
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
初始化项目后绘制内容
- // 集合容器,设置透明度
- 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();
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
npm run watch
用微信小程序编辑器导入该项目下的 weapp 文件。
用于分组,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(child);
移除对象
group.remove(child);
清空子对象
group.empty();
使用一个对象替代子对象
group.replace(current, pre);
最大的顶层容器,继承自 Group,所以 Group 拥有的方法它全都有。
任何元素添加到 Stage 上是看不到的,须要执行 update 方法。
任何元素属性的修改请执行 stage.update() 来更新渲染。
stage.update();
设置模拟虚拟 canvas,接受一个参数 canvas 对象,用于计算像素级的 touch 事件目标。
获取要渲染文字的宽度,两个参数,第一个参数是 text: String,待绘制的文字,第二个参数是font: String,设置的文字的样式。
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 接受一个参数,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()
文本对象
- const text = new Text(item.key, {
- font: `normal normal 20px Arial`,
- color: '#000000',
- baseline: 'bottom'
- });
获取文本宽度
textObj.getWidth();
绘图对象,用于使用基本的连缀方式的 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);
- const rect = new Rect(200, 100, {
- fillStyle: 'black'
- });
const circle = new Circle(10);
const ellipse = new Ellipse(120, 20);
属性名 | 描述 |
x | 水平偏移 |
y | 竖直偏移 |
scaleX | 水平缩放 |
scaleY | 竖直缩放 |
scale | 同时设置或读取 scaleX 和 scaleY |
rotation | 旋转 |
skewX | 歪斜 X |
skewY | 歪斜 Y |
regX | 旋转基点 X |
regY | 旋转基点 Y |
属性名 | 描述 |
alpha | 元素的透明度 |
如果父子都设置了 alpha 会进行乘法叠加。
属性名 | 描述 |
compositeOperation | 源图像绘制到目标图像上的叠加模式 |
注意这里如果自身没有定义 compositeOperation 会进行向上查找,找到最近的定义了 compositeOperation 的父容器作为自己的 compositeOperation。
属性名 | 描述 |
shadow | 阴影 |
使用方式:
- obj.shadow = {
- color: '#42B035',
- offsetX: -5,
- offsetY: 5,
- blur: 10
- };
Name | Describe |
stage | 或者自己所在的 stage |
使用方式:
obj.stage;
销毁自己
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:
- 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();
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
使用 Shape:
- const sector = new Sector(10, 0, Math.PI/6, {
- fillStyle: 'red'
- lineWidth: 2
- })
- stage.add(sector)
- stage.update()
自定义 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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
使用:
- 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 的初始化采用显示设置宽高和通过缩放适应像素密度,显示高清。
对于较为复杂的项目,建议通过类开发组件,即每一组件是一个类,类中包含自己的布局和更新方法,这样可以开发出高度复用的组件,后续也便于维护。
帧动画
MIT
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。