手冊(cè)簡(jiǎn)介

【開源】微信小程序、小游戲以及 Web 通用 Canvas 渲染引擎

手冊(cè)說明

【開源】微信小程序、小游戲以及 Web 通用 Canvas 渲染引擎 - Cax

Cax

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

特性

  • Learn Once, Write Anywhere(小程序、小游戲、PC Web、Mobile Web)
  • 支持小程序、小游戲以及 Web 瀏覽器渲染
  • 小程序、小游戲和 Web 擁有相同簡(jiǎn)潔輕巧的 API
  • 高性能的渲染架構(gòu)
  • 超輕量級(jí)的代碼體積
  • 松耦合的渲染架構(gòu)
  • 支持 Canvas 元素管理
  • 支持 Canvas 元素事件體系
  • 圖靈完畢的 group 嵌套體系
  • 內(nèi)置 tween 運(yùn)動(dòng)能力
  • 內(nèi)置文本、位圖、序列幀、繪圖對(duì)象和多種矢量繪制對(duì)象

一分鐘入門小程序 cax 使用

到 GitHub 下載 cax 自定義組件,然后小程序引入 cax 自定義組件:

└── cax
    ├── cax.js
    ├── cax.json  
    ├── cax.wxml  
    ├── cax.wxss
    └── index.js

在 page 或者 component 里聲明依賴:

{
  "usingComponents": {
    "cax":"../cax/cax"
  }
}

在的 wxml 里引入 cax 標(biāo)簽:

<cax id="myCanvas"></cax>

在 js 里渲染邏輯:

import cax from '../cax/index'

Page({
  onLoad: function () {
    //比 web 里使用 cax 多傳遞 this,this 代表 Page 或 Component 的實(shí)例
    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')
})

一分鐘入門小游戲 cax 使用

到 GitHub 下載 cax 小游戲示例,目錄結(jié)構(gòu)如下:

const stage = new cax.Stage()

和小程序以及 Web 不同的是,小游戲創(chuàng)建 Stage 不需要傳任何參數(shù)。

一分鐘入門 Web cax 使用

通過 npm 或者 CDN 獲取:

npm i cax
import cax from 'cax'

const stage = new cax.Stage(200, 200, '#renderTo')
const rect = new cax.Rect(100, 100, {
  fillStyle: 'black'
})

stage.add(rect)
stage.update()

除了 Stage 構(gòu)造函數(shù)比小程序第四個(gè)參數(shù) this,其他使用方式都一樣。

內(nèi)置對(duì)象

Group

用于分組, group 也可以嵌套 group,父容器的屬性會(huì)疊加在子屬性上, 比如:

  • 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 方法進(jìn)行元素的增加和刪除。先 add 的會(huì)先繪制,所有后 add 的會(huì)蓋在先 add 的上面。

Bitmap

const bitmap = new cax.Bitmap(img)
stage.add(bitmap)
stage.update()

如果只傳 url 而不是 Image 對(duì)象的實(shí)例,需要這樣:

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

這里需要注意小程序需要配置 downloadFile 需要配置合法域名才能正常加載到圖片。

可以設(shè)置圖片裁剪顯示區(qū)域,和其他 transform 屬性:

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

Sprite

序列幀動(dòng)畫組件,可以把任意圖片的任意區(qū)域組合成一串動(dòng)畫。

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 () {

    }
});

Text

文本對(duì)象

const text = new cax.Text('Hello World', {
  font: '20px Arial',
  color: '#ff7700',
  baseline: 'top'
})

Graphics

繪圖對(duì)象,用于使用基本的連綴方式的 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)

Shape

與 Graphics 不同的是, Shape 一般擁有有限的寬高,所以可以使用離屏 Canvas 進(jìn)行緩存。下面這些屬于 Shape。

Rect

const rect = new cax.Rect(200, 100, {
  fillStyle: 'black'
})

Circel

const circel = new cax.Circel(10)

Ellipse

const ellipse = new cax.Ellipse(10)

注意:從技術(shù)上小游戲和 Web 可以離屏 Canvas,小程序不行,因?yàn)樾〕绦虿恢С謩?dòng)態(tài)創(chuàng)建離屏 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豎直縮放
rotation旋轉(zhuǎn)
skewX歪斜 X
skewY歪斜 Y
originX旋轉(zhuǎn)基點(diǎn) X
originY旋轉(zhuǎn)基點(diǎn) Y

Alpha

屬性名描述
alpha元素的透明度

注意這里父子都設(shè)置了 alpha 會(huì)進(jìn)行乘法疊加。

compositeOperation

屬性名描述
compositeOperation源圖像繪制到目標(biāo)圖像上的疊加模式

注意這里如果自身沒有定義 compositeOperation 會(huì)進(jìn)行向上查找,找到最近的定義了 compositeOperation 的父容器作為自己的 compositeOperation。

Cursor

屬性名描述
cursor鼠標(biāo)移上去的形狀

事件

小程序事件

事件名描述
tap手指觸摸后馬上離開
touchstart手指觸摸動(dòng)作開始
touchmove手指觸摸后移動(dòng)
touchend手指觸摸動(dòng)作結(jié)束
drag拖拽

Web 事件

事件名描述
click元素上發(fā)生點(diǎn)擊時(shí)觸發(fā)
mousedown當(dāng)元素上按下鼠標(biāo)按鈕時(shí)觸發(fā)
mousemove當(dāng)鼠標(biāo)指針移動(dòng)到元素上時(shí)觸發(fā)
mouseup當(dāng)在元素上釋放鼠標(biāo)按鈕時(shí)觸發(fā)
mouseover當(dāng)鼠標(biāo)指針移動(dòng)到元素上時(shí)觸發(fā)
mouseout當(dāng)鼠標(biāo)指針移出元素時(shí)觸發(fā)
tap手指觸摸后馬上離開
touchstart手指觸摸動(dòng)作開始
touchmove手指觸摸后移動(dòng)
touchend手指觸摸動(dòng)作結(jié)束
drag拖拽

自定義對(duì)象

自定義 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!"
})

一般情況下,稍微復(fù)雜組合體都建議使用繼承自 Group,這樣利于擴(kuò)展也方便管理自身內(nèi)部的元件??梢钥吹叫∮螒虻?DEMO 里的 Player、Bullet、Enemy、Background 全都是繼承自 Group。

License

MIT


在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)