sprite2
v1.2.1
Published
Create a clean & powerful JavaScript developing environment, with ES6+ support.
Downloads
3
Readme
sprite2 轻量级的 canvas 绘图库
像操作 DOM 元素一样操作 canvas 中的“精灵”
特性
- 支持 attr 属性设置精灵样式
- 支持 web animations api 精灵动画
- 支持精灵的 canvas 滤镜
- 支持精灵的 mouse 和 touch 事件
- 优化的渲染性能
Usage
在浏览器中使用
<script src="https://s2.ssl.qhres.com/!ee023456/sprite2-1.2.1.js"></script>
快速上手
示例
const birdsJsonUrl = 'https://s5.ssl.qhres.com/static/5f6911b7b91c88da.json'
const birdsRes = 'https://p.ssl.qhimg.com/d/inn/c886d09f/birds.png'
;(async function(){
const paper = sprite2.Paper2D('#paper')
paper.setResolution(800, 800) // 设置 Paper 的实际分辨率
const cacheMap = new Map()
class Bird extends sprite2.Sprite {
constructor(){
super('bird1.png')
}
//共用缓存,提高性能
get cache() {
const key = JSON.stringify(this.textures) + this.attr('scale')
if(cacheMap.has(key)) {
return cacheMap.get(key)
}
}
set cache(context) {
if(context == null){
cacheMap.clear()
return
}
const key = JSON.stringify(this.textures) + this.attr('scale')
if(!cacheMap.has(key)) {
cacheMap.set(key, context)
}
}
}
await paper.preload(
[birdsRes, birdsJsonUrl] // 预加载资源,支持雪碧图
)
const bglayer = paper.layer('bg'), // 背景层
// 前景层
// 每次最多渲染 50 个 sprite,并且不代理事件,提升性能
fglayer = paper.layer('fg', {
handleEvent: false,
evaluateFPS: true,
renderMode: 'repaintAll',
})
const axisZero = [400, 400]
const circle = new sprite2.Sprite()
circle.attr({
anchor: [0.5, 0.5],
size: [800, 800],
pos: axisZero,
bgcolor: '#139',
opacity: 0.5,
borderRadius: 400,
})
bglayer.appendChild(circle)
function pointAdd(p1, p2 = [0, 0]){
return [p1[0] + p2[0], p1[1] + p2[1]].map(Math.round)
}
function pointSub(p1, p2 = [0, 0]){
return [p1[0] - p2[0], p1[1] - p2[1]].map(Math.round)
}
function sleep(time){
return new Promise(resolve => setTimeout(resolve, time))
}
async function randomAnimate(bird){
const birdPoint = bird.attr('pos')
const randomArc = Math.random() * 2 * Math.PI
const randomPoint = pointAdd([350 * Math.cos(randomArc),
350 * Math.sin(randomArc)], axisZero)
const dist = pointSub(randomPoint, birdPoint)
const distance = Math.round(Math.sqrt(dist[0] * dist[0] + dist[1] * dist[1]))
const flip = dist[0] < 0 ? -1 : 1
const duration = 5 * distance + 100
bird.attr('scale', [flip, 1]) //scale 放在外面,触发缓存
bird.animate([
{textures: 'bird1.png'},
{textures: 'bird2.png'},
{textures: 'bird3.png'},
], {
duration: 300,
direction: 'alternate',
iterations: Infinity,
})
const anim = bird.animate([
{pos: birdPoint},
{pos: randomPoint}
], {
duration,
endDelay: 500,
fill: 'both'
})
await anim.finished
}
let birdCount = 0
async function addBird(){
spriteCount.innerHTML = ++birdCount
const bird = new Bird()
bird.attr({
anchor: [0.5, 0.5],
pos: axisZero,
transform: {
rotate: 0,
}
})
fglayer.appendChild(bird)
//noprotect
do{
await randomAnimate(bird)
}while(1)
}
addBird()
circle.on('click', evt => {
addBird()
})
//显示 fps ,注意,因为本框架采用的是非定时渲染,即只有 sprite 有更新时才渲染
//所以所有精灵不运动的时候 fps 也会降下来
setInterval(() => {
fps.innerHTML = fglayer.fps
}, 1000)
window.fglayer = fglayer
window.paper = paper
})()