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

NameDescribe
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

  • 帧动画