小程序、小遊戲以及 Web 通用 Canvas 渲染引擎html
到 GitHub 下載 cax 自定義組件,而後小程序引入 cax 自定義組件:git
└── cax
├── cax.js
├── cax.json
├── cax.wxml
├── cax.wxss
└── index.js
複製代碼
在 page 或者 component 裏聲明依賴:github
{
"usingComponents": {
"cax":"../cax/cax"
}
}
複製代碼
在的 wxml 裏引入 cax 標籤:web
<cax id="myCanvas"></cax>
複製代碼
在 js 裏渲染邏輯:npm
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()
}
})
複製代碼
效果以下所示:json
除了 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 獲取:bash
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 | 拖拽 |
cax 內置了 to 的能力以連綴的方式寫運動效果:
cax.To.get(bitmap)
.to()
.y(240, 2000, cax.easing.elasticInOut)
.rotation(240, 2000, cax.easing.elasticInOut)
.end(function () {
console.log(" task one has completed!")
})
.wait(500)
.to()
.rotation(0, 1400, cax.easing.elasticInOut)
.end(function () {
console.log(" task two has completed!")
})
.wait(500)
.to()
.scaleX(1, 1400, cax.easing.elasticInOut)
.scaleY(1, 1400, cax.easing.elasticInOut)
.end(function () {
console.log(" task three has completed!")
})
.start()
複製代碼
固然,也能夠經過 set 方法支持任意屬性的運動,如:
.set('y', 240, 2000, cax.easing.elasticInOut)
複製代碼
等同於
.y(240, 2000, cax.easing.elasticInOut)
複製代碼
自定義 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