简介
MinAs 是一个运行在微信小程序的JavaScript 库,仅仅13kb左右,旨在让开发者能像使用 pixijs和Flash AS3 一样,在微信小程序的 Canvas 中优雅地使用精灵Sprite、补简动画Tween、逐帧动画精灵AnimatedSprite。同样也特别适合那些想在微信小程序中开发小游戏功能的项目,又或者你想做个游戏界面风格的应用小程序。
后续作者会推出使用这个库开发的简单的小游戏示例、ui库等。
git地址:https://gitee.com/wugemianfei/min-as
npm地址:https://www.npmjs.com/package/min-as
功能特性
仅仅 10 几 kb 左右,和那些动则几百 kb 的库相比,太适合寸土寸金的小程序了。
支持创建普通精灵(`Sprite`)和动画精灵(`AnimatedSprite`)。
提供资源加载器,方便加载图片和动画资源。
支持精灵的变换动画和事件处理。
支持简单的 Tween 补间动画。
安装与导入
小程序中使用
直接复制 min-as.umd.js 文件到小程序的文件夹中比如 utils 中,然后在微信小程序的 *.js 文件中引入。
import MinAs, { Sprite, AnimatedSprite } from './utils/min-as.umd.js'
uniapp 中使用
npm install min-as
import MinAs, { Sprite, AnimatedSprite } from 'min-as'
开始使用
uniapp 中使用
uniapp 完整代码,需要注意 canvas 的调用方式,demo 是 vue2 的写法,vue3 写法差不多。
<template>
<view class="content">
<canvas type="2d" id="myCanvas" class="gamecont" :disable-scroll="true" @touchstart="touchEvent"
@touchmove="touchEvent" @touchend="touchEvent" @touchcancel="touchEvent"></canvas>
</view>
</template>
<script>
import MinAs, { Sprite, AnimatedSprite } from "min-as"
let minAs = null
export default {
data() {
return {
title: 'Hello'
}
},
mounted() {
const info = uni.getSystemInfoSync()
const sw = info.screenWidth //获取屏幕宽高
const sh = info.windowHeight //获取屏幕宽高
const ratio = info.devicePixelRatio
//#ifdef MP-WEIXIN
wx.createSelectorQuery()
.select('#myCanvas')
.node(({ node: canvas }) => {
//新版 canvas 只能这么获取
const ctx = canvas.getContext('2d')
canvas.width = sw * ratio
canvas.height = sh * ratio
ctx.scale(ratio, ratio)
//初始化 minAs 实例
minAs = new MinAs()
minAs.init({ canvas })
//
const sprite = new Sprite({
x: 10,
y: 10,
width: 375,
height: 100,
backgroundColor: "#f20"
})
minAs.appendChild(sprite)
//开始渲染
minAs.render()
}).exec();
//#endif
},
methods: {
//#ifdef MP-WEIXIN
touchEvent(e) {
//小程序事件绑定至 minAs 实例
if (minAs) {
minAs.dispatchEvent(e)
}
}
//#endif
}
}
</script>
<style lang="scss" scoped>
.content {
width: 100vw;
height: 100vh;
.gamecont {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 0;
}
}
</style>
原生微信小程序中使用
微信 *.wxml 部分片段。
<canvas type="2d" id="myCanvas" bind:touchstart="touchEvent"
bind:touchmove="touchEvent" bind:touchend="touchEvent" bind:touchcancel="touchEvent"></canvas>
微信 *.js 部分片段。
import MinAs, { Sprite, AnimatedSprite } from 'min-as'
onReady() {
const query = wx.createSelectorQuery()
query.select('#myCanvas')
.fields({ node: true, size: true })
.exec((res) => {
const minAs = new MinAs()
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
//开始初始化 minAs
minAs.init({ canvas })
//定义红色精灵
const sprite = new Sprite({ x: 100, y: 100, width: 100, height: 100, backgroundColor: 'red' })
//监听事件,如果无效请检查是否绑定了 touchEvent 事件
sprite.on("touchstart", (e) => {
console.log("红色精灵被点击:", e)
}
minAs.appendChild(sprite)
minAs.render()
//初始化结束
})
},
touchEvent(e) {
//非常重要,将微信小程序事件传递给 minAs
if (this.minAs) {
this.minAs.dispatchEvent(e)
}
}
补间动画
MinAs 支持使用 Tween 进行补间动画。以下是如何创建和使用 Tween 的示例 js 片段:
// 假设我们有一个精灵对象 sprite, 需要将它移动到 (300, 300) 位置, 并在 2 秒内完成, 运动曲线减速"Out"
const sprite = new Sprite({ x: 0, y: 0, width: 100, height: 100, backgroundColor: 'red' })
const tween = minAs.transition(sprite, {
x: 300,
y: 300,
duration: 2,
timing:"Out"
onEnd: () => {
console.log("动画结束")
}
})
// 假设我们有一个精灵对象 sprite, 需要将它移动到 (300, 300) 位置, 然后再运行到(400, 400)位置,一直往复运动"
const sprite = new Sprite({ x: 0, y: 0, width: 100, height: 100, backgroundColor:'green' })
const tweenCtr = minAs.transitionList(sprite, [
{ x: 300, y: 300, duration: 2, timing:"Out" },
{ x: 400, y: 400, duration: 2, timing:"Out" }
], {
loop: true,
onEnd: () => {
console.log("动画结束")
}
})
MinAs 只是封装简单的匀速、加速、减速、先加速再减速。如果需要更高级更精细的运动,推荐直接使用 tween.js 库进行操作。
逐帧动画
MinAs 支持逐帧动画,允许开发者创建逐帧动画精灵。以下是如何创建和使用逐帧动画的示例:
const urls = {
laoshu: "https://**********demodata/laoshu.json",
}
//如果想修改 json 默认图片地址,还可以自定义贴图地址
// const urls = {
// laoshu2: {
// url: "https://**********demodata/laoshu.json",
// metaImage: "https://*********/**.png"
// }
// }
minAs.assetsLoad(urls).then(keys=> {
const anSprite = new AnimatedSprite({
x: 400,
y: 200,
width: 48,
height: 48,
backgroundColor: "#f20",
currentFrame: 3,
json: minAs.getAssets('laoshu')
})
minAs.appendChild(anSprite)
//运行动画
//anSprite.play()
})
制作逐帧动画过程
直接下载免费制作 工具 ShoeBox,当然其他工具也行
按照 doc 文件夹中的 3 张图片操作,即可得到最后要的 json 文件和纹理贴图。
API 说明
`MinAs` 类
`init(options)`:初始化 MinAs 实例,传入包含 `canvas` 的配置对象。
参数类型描述
optionsObject初始化数据,目前就一个参数{ canvas }。
options.canvaswx.Canvas微信小程序的 Canvas 节点对象。
`use(BasePlugin, options)`:加载自定义插件。
参数类型描述
BasePluginBasePlugin插件实例(详细请看自定义插件部分)
optionsObject| undefined自定义传递给插件数据
`destroy()`: 销毁 MinAs 实例(全局销毁)。
`dispatchEvent(e)`:绑定 wx.Canvas 事件。
参数类型描述
ewx.Event微信小程序的事件对象。
`on(eventName, callback)`:注册事件。
参数类型描述
eventNameString不要使用内置名称: "touchstart", "touchmove", "touchend", "touchcancel"
callbackFunction回调函数,返回事件 e 对象
`off(eventName, callback)`: 移除事件。
参数类型描述
eventNameString不要使用内置名称:"touchstart", "touchmove", "touchend", "touchcancel"
callbackFunction回调函数,返回事件 e 对象
`emit(eventName, ...args)`:触发事件。
参数类型描述
eventNameString不要使用内置名称:"touchstart", "touchmove", "touchend", "touchcancel"
argsany任意数据
`render(callback)`:开始渲染。
参数类型描述
callbackFunction| undefined持续调用
`appendChild(sprite)`:将精灵添加到渲染列表。
参数类型描述
spriteSprite精灵对象
`removeChild(sprite)`:移除子精灵。
参数类型描述
spriteSprite精灵对象
`removeAll()`:移除所有子精灵。
`assetsLoad(urls, progressCallback)`:加载资源。
参数类型描述
`urls`String| Array | Object当为 string 类型时候加载一个,Array 加载多个。(单个数据可以直接使用 string 类型,也可以写成{url: string}这样的 object 结构)
`progressCallback`Function| undefined加载进度,当 urls 为数组时才有意义,返回加载百分比 number。
返回值
返回值类型描述
resPromise回一个 Promise,完成后返回加载的资源键名或者键名列表
`getAssets(key)`:根据键名获取已加载的资源。
参数类型描述
keyString| undefined资源建名称
返回值
返回值类型描述
keyString| Array当 key 为 string 返回当前资源的内容,key 为空或者不存在时候返回全部资源列表
`transition(sprite, options)`:内置 tween 过渡方法。
参数类型描述
spriteSprite精灵实例
optionsObject过渡配置参数
options.durationnumbet\undefind
options.timing"Linear", "In", "Out", "InOut"运动函数名称,默认 Linear
options.onUpdateFunction| undefind运动结束回调,返回运动的 srpite 精灵
options.onEndFunction| undefind运动结束回调,返回 srpite 精灵
options.[..res]anysprite 精灵中需要变化到的任意 number 属性,比如精灵的 x,y,scaleX,scaleY,width,height,angle,opacity
返回值
返回值类型描述
tweenTween返回一个 tween 运动对象
tween.resumeFunction恢复动画
tween.pauseFunction暂停动画
tween.stopFunction停止动画
`transitionList(sprite, optionslist, options)`:内置 tween 过渡方法列表,多个 transition 组成的运动列表。
参数类型描述
spriteSprite精灵实例
optionslistArray多个 transition 配置参数的集合,会按照顺序一个完成再执行下一个,持续下去
options.loopBoolean| undefind是否循环 ,默认 true
options.onUpdateFunction| undefind运动结束回调,返回运动的 srpite 精灵
options.onChangeFunction| undefind运动切换的时候回调,返回运动的 srpite 精灵和下标 index
options.onEndFunction| undefind运动结束回调,返回 srpite 精灵, 当 loop 为 true 才有意义
返回值
返回值类型描述
tweenCtrObject返回一个控制运动的对象
tweenCtr.resumeFunction恢复动画
tweenCtr.pauseFunction暂停动画
tweenCtr.stopFunction停止动画
`Sprite` 类
构造函数接受一个配置对象,支持以下属性:
`x`:精灵的 x 坐标。默认 0
`y`:精灵的 y 坐标。默认 0
`width`:精灵的宽度。默认 0
`height`:精灵的高度。默认 0
`scaleX`:精灵的水平缩放比例。默认 1
`scaleY`:精灵的垂直缩放比例。默认 1
`backgroundColor`:精灵的背景颜色。默认 ""
`texture`:精灵的纹理(图片)。默认 ""
`angle`:精灵的旋转角度。默认 0
`opacity`:精灵的透明度。默认 1
`hotPolygon`:元素的热点多边形, 用于事件碰撞检测。默认最小外接矩形[[0, 0], [width, 0], [width, height], [0, height]]。如果是异形需要精准点击检查,这里可以自己定义热区数组
const sprite = new Sprite({
x: 0,
y: 0,
width: 200,
height: 200,
hotPolygon: [
[100, 0], [138, 72], [200, 72], [146, 116],
[162, 180], [100, 146], [38, 180], [54, 116], [0, 72], [62, 72]
],
showHotPolygon: true,
backgroundColor: 'red',
})
`showHotPolygon`:是否显示热区多边形。默认 false,主要用来调试时候看热区位置和大小
`visible`:精灵的可见性。默认 true
`onDraw`:绘制回调函数 Function,返回精灵实例,用于自定义绘制逻辑。默认空
方法:
`on(eventName, callback)`:监听事件。
参数类型描述
eventName"touchstart", "touchmove", "touchend", "touchcancel"监听事件
callbackFunction回调函数,返回事件 e 对象
`appendChild(sprite)`:将精灵添加到渲染列表。
参数类型描述
spriteSprite精灵对象
`removeChild(sprite)`:移除子精灵。
参数类型描述
spriteSprite精灵对象
`removeAll()`:移除所有子精灵。
`removeFromParent()`:将此对象从其当前父对象中移除。
`toFront()`:将精灵层级置顶。
`toBack()`:将精灵层级置底。
`getIndex()`:获取当前精灵层级。
`setIndex(index)`:将精灵层级到指定位置。
`AnimatedSprite` 类
继承自 `Sprite`,构造函数额外支持以下属性:
`currentFrame`:初始帧索引。默认 0
`loop`:是否循环播放。默认 true
`animationSpeed`:帧率 number, 默认 15(帧/秒)
`json`:动画配置 JSON。来自 ShoeBox 导出的帧动画标准 json 文件,详细请看下面帧动画部分。
方法:
`play(frame)`:播放动画,可指定播放帧。
参数类型描述
frameNumber| undefind为空时候从头播放,不为空从指定帧播放
`pause()`:暂停动画。
`stop(frame)`:停止动画,可指定停止帧。
参数类型描述
spriteNumber| undefind为空时停在最后一帧,不为空停在指定帧
自定义插件
MinAs 提供了一个插件机制,允许开发者自定义插件以扩展其功能。以下是如何创建和使用自定义插件的步骤:
你可以直接复制项目中的 plugin 文件夹到你的任意位置,然后引入文件,使用 minAs.use 加载插件
假设我们开发的插件叫 DemoPlugin,我们先定义类然后 extends BasePlugin 继承一下这个基础类,然后就可以使用 minAs 内部的一些方法
如果需要将插件的方法挂在到 minAs 对象上去,只要在 apis 数组中写上方法名称即可
比如你写了个方法叫 demoMethod,你需要 static apis = ["demoMethod"], 然后就可以在外部使用 minAs.demoMethod
//引入插件
import DemoPlugin from './plugin/DemoPlugin.js'
//挂载插件
minAs.use(DemoPlugin, {})
//使用插件方法
minAs.demoMethod()