Cax

小程序、小游戏以及 Web 通用 Canvas 渲染引擎

微信小游戏

特性

Learn Once, Write Anywhere(小程序、小游戏、PC Web、Mobile Web)

Write Once, Run Anywhere(小程序、小游戏、Web只需要修改new Stage传入参数即可)

支持小程序、小游戏以及 Web 浏览器渲染

小程序、小游戏和 Web 拥有相同简洁轻巧的 API

高性能且松耦合的渲染架构

超轻量级的代码体积

支持 Canvas 元素管理

支持 Canvas 元素事件体系

图灵完备的 group 嵌套体系

内置 to2to 的跨平台运动引擎

支持可以变形的 clip 裁剪体系

内置文本、位图、序列帧、绘图对象和多种矢量绘制对象

支持 SVG Path 渲染

支持几乎全部的 CSS 滤镜和其他常用滤镜

内置图片加载器

一分钟入门小程序 cax 使用

到 GitHub 下载 cax 自定义组件,然后小程序引入 cax 自定义组件:

└── cax

├── cax.js

├── cax.json

├── cax.wxml

├── cax.wxss

└── index.js

在 page 或者 component 里声明依赖:

{

"usingComponents":{

"cax":"../cax/cax"

}

}

在的 wxml 里引入 cax 标签:

在 js 里渲染逻辑:

import cax from '../cax/index'

Page({

onLoad: function () {

//比 web 里使用 cax 多传递 this,this 代表 Page 或 Component 的实例

const stage = new cax.Stage(200, 200, 'myCanvas', this)

const rect = new cax.Rect(100, 100, {

fillStyle: 'black'

})

rect.originX = 50

rect.originY = 50

rect.x = 100

rect.y = 100

rect.rotation = 30

rect.on('tap', () => {

console.log('tap')

})

stage.add(rect)

stage.update()

}

})

效果如下所示:

除了 tap 事件,也可以帮 rect 绑定其他触摸事件:

rect.on('touchstart', () => {

console.log('touchstart')

})

rect.on('touchmove', () => {

console.log('touchmove')

})

rect.on('touchend', () => {

console.log('touchend')

})

主要,小程序事件触发是根据元素的矩形区域,所以需要设置 width 和 height 才能绑定触发事件。

一分钟入门小游戏 cax 使用

到 GitHub 下载 cax 小游戏示例,目录结构和运行效果如下:

const stage = new cax.Stage()

和小程序以及 Web 不同的是,小游戏创建 Stage 不需要传任何参数。

一分钟入门 Web cax 使用

通过 npm 或者 CDN 获取:

npm i cax

使用方法:

import cax from 'cax'

const stage = new cax.Stage(200, 200, 'body')

cax.loadImgs({

imgs: ['./wepay-diy.jpg'],

complete: (imgs) => {

const img = imgs[0]

const bitmap = new cax.Bitmap(img)

bitmap.x = stage.width / 2

bitmap.y = stage.height / 2

bitmap.rotation = -10

bitmap.originX = img.width / 2

bitmap.originY = img.height / 2

bitmap.filter('blur(10px)')

stage.add(bitmap)

stage.update()

}

})

除了 Stage 构造函数比小程序第四个参数 this,其他使用方式都一样。执行上面代码你将看到如下效果:

内置对象

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 cax.Group()

const rect = new cax.Rect(100, 100, {

fillStyle: 'black'

})

group.add(rect)

stage.add(group)

stage.update()

group 拥有常用的 add 和 remove 方法进行元素的增加和删除。先 add 的会先绘制,所有后 add 的会盖在先 add 的上面。

Group 方法

add

添加对象

groupObj.add (child)

remove

移除对象

groupObj.remove (child)

empty

清空子对象

groupObj.empty ()

replace

使用一个对象替代子对象

groupObj.replace (current, pre)

Stage

最大的顶层容器,继承自 Group,所以 Group 拥有的方法它全都有。

Stage 方法

update

任何元素添加到舞台上是看不到的,你必须执行 update 方法。

stage.update()

任何元素属性的修改请执行 stage.update() 来更新舞台,或者放在定时器里:

cax.tick(stage.update.bind(stage))

scaleEventPoint

当 canvas 的宽高 和 canvas 的像素不对应的时候,事件触发位置是不准确的,你可以使用 scaleEventPoint 方法使事件校正准确。

//canvas 宽高是像素的一半

stage.scaleEventPoint(0.5, 0.5)

Stage 属性

disableMoveDetection

是否禁用鼠标或触摸移动的事件检测。

stage.disableMoveDetection = true

这里需要注意,Web 的 disableMoveDetection 默认是 false,微信小游戏默认是 true。所以微信小游戏想要监听 touchmove 和 drag 事件的话需要在创建完 Stage 之后执行下面代码开启监听:

stage.disableMoveDetection = false

moveDetectionInterval

设置 touchmove 和 mousemove 检测的间隔

//每秒检测两次

stage.moveDetectionInterval = 500

Bitmap

const bitmap = new cax.Bitmap(img)

stage.add(bitmap)

stage.update()

如果只传 url 而不是 Image 对象的实例,需要这样:

const bitmap = new cax.Bitmap('./wepay.png', ()=>{

stage.update()

})

stage.add(bitmap)

这里需要注意小程序需要配置 downloadFile 需要配置合法域名才能正常加载到图片。

可以设置图片裁剪显示区域,和其他 transform 属性:

bitmap.rect = [0, 0, 170, 140]

bitmap.x = 200

Sprite

序列帧动画组件,可以把任意图片的任意区域组合成一串动画。

const sprite = new cax.Sprite({

framerate: 7,

imgs: ['./mario-sheet.png'],

frames: [

// x, y, width, height, originX, originY ,imageIndex

[0, 0, 32, 32],

[32 * 1, 0, 32, 32],

[32 * 2, 0, 32, 32],

[32 * 3, 0, 32, 32],

[32 * 4, 0, 32, 32],

[32 * 5, 0, 32, 32],

[32 * 6, 0, 32, 32],

[32 * 7, 0, 32, 32],

[32 * 8, 0, 32, 32],

[32 * 9, 0, 32, 32],

[32 * 10, 0, 32, 32],

[32 * 11, 0, 32, 32],

[32 * 12, 0, 32, 32],

[32 * 13, 0, 32, 32],

[32 * 14, 0, 32, 32]

],

animations: {

walk: {

frames: [0, 1]

},

happy: {

frames: [5, 6, 7, 8, 9]

},

win: {

frames: [12]

}

},

playOnce: false,

currentAnimation: "walk",

animationEnd: function () {

}

});

Sprite 方法

gotoAndPlay

跳到当前 animationName 并开始播放

spriteObj.gotoAndPlay(animationName)

gotoAndStop

跳到当前 animationName 并开始停止

spriteObj.gotoAndStop(animationName)

gotoAndPlayOnce

跳到当前 animationName 并开始播放,播完一轮销毁自己。常用于爆炸

spriteObj.gotoAndPlayOnce(animationName)

Text

文本对象

const text = new cax.Text('Hello World', {

font: '20px Arial',

color: '#ff7700',

baseline: 'top'

})

Text 方法

getWidth

获取文本宽度

textObj.getWidth()

Graphics

绘图对象,用于使用基本的连缀方式的 Canvas 指令绘制图形。

const graphics = new cax.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() 方法,不然路径叠加到你的浏览器不堪重负:

cax.setInterval(function(){

graphics

.clear()

.beginPath()

.arc(0, 0, 10, 0, Math.PI * 2)

.stroke()

}, 16)

Shape

与 Graphics 不同的是, Shape 一般拥有有限的宽高,所以可以使用离屏 Canvas 进行缓存。下面这些属于 Shape。

Rect

const rect = new cax.Rect(200, 100, {

fillStyle: 'black'

})

Circle

const circle = new cax.Circle(10)

Ellipse

const ellipse = new cax.Ellipse(120, 20)

注意:从技术上小游戏和 Web 可以离屏 Canvas,小程序不行,因为小程序不支持动态创建离屏 Canvas。

Element

Element 是多种元素的组合,如 Bitmap、Group、 Text、 Shape 等混合起来的图像。

Button

const button = new cax.Button({

width: 100,

height: 40,

text: "Click Me!"

})

属性

Transform

属性名

描述

x

水平偏移

y

竖直偏移

scaleX

水平缩放

scaleY

竖直缩放

scale

同时设置或读取 scaleX 和 scaleY

rotation

旋转

skewX

歪斜 X

skewY

歪斜 Y

originX

旋转基点 X

originY

旋转基点 Y

Alpha

属性名

描述

alpha

元素的透明度

注意这里父子都设置了 alpha 会进行乘法叠加。

compositeOperation

属性名

描述

compositeOperation

源图像绘制到目标图像上的叠加模式

注意这里如果自身没有定义 compositeOperation 会进行向上查找,找到最近的定义了 compositeOperation 的父容器作为自己的 compositeOperation。

Cursor

属性名

描述

cursor

鼠标移上去的形状

Fixed

属性名

描述

fixed

是否固定定位,默认是 false 设置成 true 不会叠加祖辈们的 transform 属性

Shadow

属性名

描述

shadow

阴影

使用方式:

obj.shadow = {

color: '#42B035',

offsetX: -5,

offsetY: 5,

blur: 10

}

Stage

Name

Describe

stage

或者自己所在的 stage

使用方式:

obj.stage

方法

destroy

销毁自己

obj.destroy()

事件

小程序事件

事件名

描述

tap

手指触摸后马上离开

touchstart

手指触摸动作开始

touchmove

手指触摸后移动

touchend

手指触摸动作结束

drag

拖拽

Web 事件

事件名

描述

click

元素上发生点击时触发

mousedown

当元素上按下鼠标按钮时触发

mousemove

当鼠标指针移动到元素上时触发

mouseup

当在元素上释放鼠标按钮时触发

mouseover

当鼠标指针移动到元素上时触发

mouseout

当鼠标指针移出元素时触发

tap

手指触摸后马上离开

touchstart

手指触摸动作开始

touchmove

手指触摸后移动

touchend

手指触摸动作结束

drag

拖拽

运动

cax 内置了 to 的能力以连缀的方式写运动效果:

const easing = cax.To.easing.elasticInOut

cax.To.get(bitmap)

.to({ y: 340, rotation: 240 }, 2000, easing)

.begin(() => {

console.log("Task one has began!")

})

.progress(() => {

console.log("Task one is progressing!")

})

.end(() => {

console.log("Task one has completed!")

})

.wait(500)

.to()

.rotation(0, 1400, easing)

.begin(() => {

console.log("Task two has began!")

})

.progress(() => {

console.log("Task two is progressing!")

})

.end(() => {

console.log("Task two has completed!")

})

.start();

to 和 to 之间的是并行

to 和 wait 之前的是串行

to 和 to 之间的 与 下一个 to 和 to 之间的是串行

有点绕,但是很直观,慢慢体会。

当然,也可以通过 set 方法支持任意属性的运动,如:

.set('y', 240, 2000, cax.easing.elasticInOut)

等同于

.y(240, 2000, cax.easing.elasticInOut)

如果想要循环播放的话可以使用 cycle 方法:

cax.To.get(bitmap)

.to()

.y(340, 2000, cax.easing.elasticInOut)

.to

.y(0, 2000, cax.easing.elasticInOut)

.cycle()

.start()

这里需要注意,和 tween.js 不同,cax 把 easing 命名全改成了一个单词的驼峰命名。如 Cubic.In 变成了 cubicIn。

裁剪

const stage = new cax.Stage(600, 400, 'body')

const bitmap = new cax.Bitmap('./wepay-diy.jpg', () => {

stage.update()

})

const clipPath = new cax.Graphics()

clipPath.arc(40, 40, 25, 0, Math.PI * 2)

bitmap.clip(clipPath)

stage.add(bitmap)

使用下面的代码可以得到同样的效果:

const clipPath = new cax.Graphics()

clipPath.x = 40

clipPath.y = 40

clipPath.arc(0, 0, 25, 0, Math.PI * 2)

所以,裁剪区域也是支持所有 transform 属性(x,y,scaleX,scaleY,rotation,skewX,skewY,originX,originY)。

自定义对象

自定义 Shape

自定义 Shape 继承自 cax.Shape:

class Sector extends cax.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 继承自 cax.Group:

class Button extends cax.Group {

constructor (option) {

super()

this.width = option.width

this.roundedRect = new cax.RoundedRect(option.width, option.height, option.r)

this.text = new cax.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 cax.Button({

width: 100,

height: 40,

text: "Click Me!"

})

一般情况下,稍微复杂组合体都建议使用继承自 Group,这样利于扩展也方便管理自身内部的元件。

小游戏的 DEMO 里的 Player、Bullet、Enemy、Background 全都是继承自 Group。

Wechart 的所有图表全都是继承自 Group。

图片加载器

cax.loadImg({

img: './a.png',

complete: function(img){

}

})

加载多张图片:

cax.loadImgs({

img: ['./a.png','./b.png'],

progress: function(progress){

console.log(progress) //0.5 and then 1

},

complete: function(imgs){

console.log(imgs[0]) //Image(a.png)

console.log(imgs[1]) //Image(b.png)

}

})

谁在使用?

微信交流群【2】

License

MIT

html5 2d小游戏,cax: HTML5 Canvas 2D Rendering Engine - 小程序、小游戏以及 Web 通用 Canvas 渲染引擎...相关推荐

  1. 【开源】微信小程序、小游戏以及 Web 通用 Canvas 渲染引擎 - Cax

    Cax 小程序.小游戏以及 Web 通用 Canvas 渲染引擎 Github → github.com/dntzhang/ca- 综合 DEMO | 运动 DEMO 小程序 DEMO 正在审核中敬请 ...

  2. html集成到小程序1011无标题,GitHub - billee1011/cax: 小程序、小游戏以及 Web 通用 Canvas 渲染引擎...

    Cax 小程序.小游戏以及 Web 通用 Canvas 渲染引擎 小程序 DEMO 正在审核中敬请期待 小游戏 DEMO 正在审核中敬请期待 特性 Learn Once, Write Anywhere ...

  3. 【开源】微信小程序、小游戏以及 Web 通用 Canvas 渲染引擎 - Cax 1

    Cax 小程序.小游戏以及 Web 通用 Canvas 渲染引擎 Github → https://github.com/dntzhang/cax 点我看看 DEMO 小程序 DEMO 正在审核中敬请 ...

  4. html5 lob,GitHub - LobbL/cax: HTML5 Canvas 2D Rendering Engine - 小程序、小游戏以及 Web 通用 Canvas 渲染引擎...

    English | 简体中文 Cax HTML5 Canvas 2D Rendering Engine Features Simple API, Lightweight and High perfor ...

  5. html5 2d小游戏,GitHub - pepsin/cax: HTML5 Canvas 2D Rendering Engine - 小程序、小游戏以及 Web 通用 Canvas 渲染引擎...

    English | 简体中文 Cax HTML5 Canvas 2D Rendering Engine Features Simple API, Lightweight and High perfor ...

  6. linux如何运行windows游戏,如何在Linux上运行Windows应用程序和游戏 互联网技术圈 互联网技术圈...

    在本教程中,我将向您介绍如何在Linux中运行Windows应用程序和游戏.您可能知道,Microsoft Windows使用DirectX来运行游戏.因此,在Windows平台上玩一些需要Direc ...

  7. linux上的windows游戏,PlayOnLinux - 在Linux上运行Windows应用程序和游戏

    在我们对这个博客以前的文章中,我们使用红酒程序安装和运行在Ubuntu和其他红帽的Linux发行版基于Windows应用程序. 没有可称为PlayOnLinux另一个开源软件,使用葡萄酒作为它的基础, ...

  8. 跨平台Web Canvas渲染引擎架构的设计与思考(内含实现方案)

    这篇文章主要从技术视角介绍下跨平台WebCanvas的架构设计以及一些关键模块的实现方案(以Android为主),限于作者水平,有不准确的地方欢迎指正或者讨论. 设计目标 标准化:Web Canvas ...

  9. 跨平台Web Canvas渲染引擎架构的设计与思考

    简介: 这篇文章主要从技术视角介绍下跨平台WebCanvas的架构设计以及一些关键模块的实现方案(以Android为主),限于作者水平,有不准确的地方欢迎指正或者讨论. 设计目标 标准化:Web Ca ...

最新文章

  1. 科学史上那些盛极一时的“著名理论”是如何被攻破的?
  2. Filemanager 的使用
  3. java android统计图_Android统计图表之柱状图(条形图)
  4. XXX 不是当前用户的有效责任,请联系您的系统管理员
  5. [10] AOP的注解配置
  6. Windows7下VS2008试用版到期的解决办法
  7. 矩阵连乘问题算法思想_AI自然语言处理算法岗常见面试题(一)
  8. 解决Lost connection to MySQL server at 'reading initial communication packet', 的方法
  9. fullcalendar内容如何默认展示一条其他的点击展示_LinkedIn广告全指南:如何从零开始成为Linkedin广告高手?...
  10. prettytensor 的使用
  11. xcodebuild命令行打包发布ipa
  12. CMD命令实现数字雨
  13. 粒子群算法 模拟退火算法
  14. C++ QT中国象棋双人单机对战代码总结
  15. 2019新版c智播客h马程序员H5全栈工程师培训项目实战
  16. 测试用例设计之正交试验
  17. 微信电脑端突然发送不了文件了
  18. IP0_Verilog实现基于双线性插值算法的图像放大IP设计
  19. 阿里云与华为USG防火墙IPSEC对接
  20. for in在python中什么意思_Python for 循环中 in 关键字含义是什么?

热门文章

  1. netcore vue elementui自动代码生成器
  2. C语言怎么编译成机器语言的,终于理解了编译是怎么回事!从C语言到机器语言的升华过程!...
  3. 服务器如何查看系统连接记录,查看服务器被连接记录
  4. 广告路由器开发(一)数据流
  5. MMDetection框架的anchor_generators.py解析与船数据解析
  6. 为什么重写equals一定要重写hashcode?
  7. IT运维管理指什么?如何建立有效的IT运维管理系统?
  8. 新版标准日本语初级_第三十六课
  9. 一元理发你来么?让客户无法拒绝的引流方案,让你快速盈利!
  10. 葛洲坝电力集团责任有限公司改变企业新句号