小程序、小遊戲以及 Web 通用 Canvas 渲染引擎
內置對象html
屬性web
事件npm
自定義對象json
到 GitHub 下載 cax 自定義組件,而後小程序引入 cax 自定義組件:小程序
└── cax ├── cax.js ├── cax.json ├── cax.wxml ├── cax.wxss └── index.js
在 page 或者 component 裏聲明依賴:瀏覽器
{ "usingComponents": { "cax":"../cax/cax" } }
在的 wxml 裏引入 cax 標籤:緩存
<cax id="myCanvas"></cax>
在 js 裏渲染邏輯:bash
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') })
到 GitHub 下載 cax 小遊戲示例,目錄結構以下:
const stage = new cax.Stage()
和小程序以及 Web 不一樣的是,小遊戲建立 Stage 不須要傳任何參數。
經過 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 構造函數比小程序第四個參數 this
,其餘使用方式都同樣。
用於分組, group 也能夠嵌套 group,父容器的屬性會疊加在子屬性上, 好比:
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 的上面。
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
序列幀動畫組件,能夠把任意圖片的任意區域組合成一串動畫。
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 () { } });
文本對象
const text = new cax.Text('Hello World', { font: '20px Arial', color: '#ff7700', baseline: 'top' })
繪圖對象,用於使用基本的連綴方式的 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 不一樣的是, Shape 通常擁有有限的寬高,因此可使用離屏 Canvas 進行緩存。下面這些屬於 Shape。
const rect = new cax.Rect(200, 100, { fillStyle: 'black' })
const circel = new cax.Circel(10)
const ellipse = new cax.Ellipse(10)
注意:從技術上小遊戲和 Web 能夠離屏 Canvas,小程序不行,由於小程序不支持動態建立離屏 Canvas。
Element 是多種元素的組合,如 Bitmap、Group、 Text、 Shape 等混合起來的圖像。
const button = new cax.Button({ width: 100, height: 40, text: "Click Me!" })
屬性名 | 描述 |
---|---|
x | 水平偏移 |
y | 豎直偏移 |
scaleX | 水平縮放 |
scaleY | 豎直縮放 |
rotation | 旋轉 |
skewX | 歪斜 X |
skewY | 歪斜 Y |
originX | 旋轉基點 X |
originY | 旋轉基點 Y |
屬性名 | 描述 |
---|---|
alpha | 元素的透明度 |
注意這裏父子都設置了 alpha 會進行乘法疊加。
屬性名 | 描述 |
---|---|
compositeOperation | 源圖像繪製到目標圖像上的疊加模式 |
注意這裏若是自身沒有定義 compositeOperation 會進行向上查找,找到最近的定義了 compositeOperation 的父容器做爲本身的 compositeOperation。
屬性名 | 描述 |
---|---|
cursor | 鼠標移上去的形狀 |
事件名 | 描述 |
---|---|
tap | 手指觸摸後立刻離開 |
touchstart | 手指觸摸動做開始 |
touchmove | 手指觸摸後移動 |
touchend | 手指觸摸動做結束 |
drag | 拖拽 |
事件名 | 描述 |
---|---|
click | 元素上發生點擊時觸發 |
mousedown | 當元素上按下鼠標按鈕時觸發 |
mousemove | 當鼠標指針移動到元素上時觸發 |
mouseup | 當在元素上釋放鼠標按鈕時觸發 |
mouseover | 當鼠標指針移動到元素上時觸發 |
mouseout | 當鼠標指針移出元素時觸發 |
tap | 手指觸摸後立刻離開 |
touchstart | 手指觸摸動做開始 |
touchmove | 手指觸摸後移動 |
touchend | 手指觸摸動做結束 |
drag | 拖拽 |
自定義 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 繼承自 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。
MIT