CssSprite,方便对逐帧动画(连续的sprite图片)在DOM中进行渲染,控制动画播放。
有过createjs经验的开发者应比较熟悉createjs.SpriteSheet和createjs.Sprite,通过这两个类可以方便在canvas实现逐帧动画,但createjs只能针对canvas操作。如果我们用sprite做为背景图片,通过改变background-position来播放动画怎么可以快速实现?CssSprite正是实现了createjs.Sprite和createjs.SpriteSheet的方法和属性,直接对DOM进行Sprite控制。
如果你熟悉createjs.Sprite和createjs.SpriteSheet,可以轻松运用CssSprite,因为两者API极为相似。没有createjs或canvas经验的开发者也可以轻松学习运用CssSprite。
CssSprite功能强大,(因为实现了createjs.Sprite API)支持三种渲染模式,background-position(sprite图片),background-image(单独图片),img标签(单独图片)。具体用法请参考example中的示例。
- 3d-adidas.html
- game.html
- pig/index.html
- render-background-position.html
- render-background-position2.html
- render-base64.html
- render-img.html
npm run build
CssSprite(options)
frame (currentFrame) 播放头直接停在某帧,不常用。推荐使用gotoAndStop(frameIndexOrAnimation)方法
gotoAndPlay (frameIndexOrAnimation) 跳到某帧并播放
gotoAndStop (frameIndexOrAnimation)跳到某帧停止播放,如果你不想用内部的计时器,如自定义缓动播放某帧,非常有用
play (frameIndexOrAnimation) 和gotoAndPlay一样,这个更多的是不传参数,恢复播放功能
stop () 停止播放
fps (fps) 动态更新帧频,如fps = 10,则每秒播放10帧
createAnimations (begin,end) 快速生成开始与结束的连续动画数组的一个帮助方法
target 指向目标DOM元素
frameIndex 可以获取和设置当前的frameIndex索引
currentAnimation 获取当前动画
currentAnimationName 获取当前动画名
//frames定义为object对象,没有createjs.SpriteSheet的regX和regY
frames: {width:64, height:64, count:20, spacing:0, margin:0}
//frames定义为数组,二维数组参数分别对应x,y,width,height
//createjs.SpriteSheet的imageIndex, regX, regY定义会被忽略
frames: [[82,0,80,83],[164,255,79,83],[82,340,80,83]
//frames定义为数组,二维数组参数分别对应x,y
frames: [[82,0],[164,255],[82,340],[0,85],[82,425]
//动画名后面直接是数组
//注意不支持createjs.SpriteSheep用数组来定义start, end, next, speed。
//每一帧要单独定义,如果是连续的自然数索引,推荐用CssSprite.createAnimations(0,length-1)方法
animations: {
runRight: [0,8,9,10,11,12,13,14],
runLeft: [15,1,2,3,4,5,6,7]
}
//动画名后面直接是object对象,用法基本和createjs.SpriteSheet一致
//speed是当前fps的倍数,next是下个animations动画名
animations: {
runRight: {
frames:[0,8,9,10,11,12,13,14],
speed:0.5,//0.5倍速度,相对于当前fps
next:'runLeft'
},
runLeft: {
frames:[15,1,2,3,4,5,6,7],
speed:2,//2倍速度,相对于当前fps
next:'runRight'
}
}
//下面是循环执行名为full的animations
animations:{
full:{
frames:CssSprite.createAnimations(0,73),
next:'full'
}
}
var sprite = new CssSprite({target:'.sprite'});
function move() {
//直接赋值,不要担心frameIndex超过totalIndex,如果大于totalIndex会把frameIndex更新为0
sprite.frameIndex++;
//注意不要直接用sprite.gotoAndStop(sprite.frameIndex++),如果对frameIndex赋值后,请重新获取一次sprite.frameIndex
sprite.gotoAndStop(sprite.frameIndex);
}
如果你的动画是先快后慢这样的缓动需求,可以直接跳过系统内部的定时器。根据自己需求灵活运用gotoAndStop可以动态播放每帧。如可以用AlloyTouch结合来播放动画
var sprite = new CssSprite({target:'.sprite'});
var num = {frameIndex:0};
new AlloyTouch({
touch:'body',//反馈触摸的dom
target: num, //运动的对象
property: "frameIndex", //被运动的属性
min: 0, //不必需,运动属性的最小值,越界会回弹
max: 200, //不必需,滚动属性的最大值,越界会回弹
change:function(value){
sprite.gotoAndStop(value);
}
}
你可以先定义sprite元素的背景图片,frame的width,height。CssSprite默认就可以自动计算各个frame的backgroundPosition位置了。如果你的sprite图片不是各个frame都铺满的话,请写上frames.count属性
如果你用到createjs的preload.js来加载连续图片组合成序列帧动画,因为加载成功后已经生成成了img元素,CssSprite直接用img标签来渲染。如果图片非常多,用backgroundPosition需要非常大的图片,性能会有非常大的影响。这时可以用img方式做成单张图,可以高效渲染。
如果序列帧不想做成sprite图片,可以把单个图片直接转成base64,base64加载完后,CssSprite自动判断用backgroundImage直接渲染相应序列帧的base64图片。
- 导入视频文件到PhotoShop:
- 打开PhotoShop软件
- 文件-> 新建
- 填写“宽度”和“高度”为视频的宽高像素
- 文件-> 导入 -> 视频帧到图片
- 导出序列图片
- 文件-> 导出-> 将图层导出到文件
- 选择目标位置,不要勾选裁切图层
- 图片批量命名
# 先按你的路片路径和文件名规则修改 /bin/rename.js
node ./bin/rename.js
如上步骤就完成了视频文件导出为序列图片,此时图片较多,后面的动画一般用到img标签渲染。注意,一定要用loader预加载所有图片再渲染动画。用法参考render-img.html
# [yourImageDir]替换成你的图片文件夹,相对于./bin/路径
node ./bin/makeSprite.js -s [yourImageDir]
- 新建Movie Clip元件
- 完成Movie Clip动画制作
- 打开Libray,选中当前的Movie Clip元件
- 右健-> Generate Sprite Sheet
- Data format选用easeljs
- 点Export按钮
- 得到图片和js数据文件
而后就是用CssSprite完成动画。此时我们一般用backgroundPosition渲染,把上面得到的js数据文件中的frames数组copy到frames中。用法参考pig/index.html
如果用background-position(sprite图片)渲染,控制不同动画元素的显示和隐藏,我们首先想到用display:none/block进行切换,但这种方式在部分ios app为uiWebview的环境中,会出现闪动现象。改为opacity:0/1进行切换可以解决闪动问题。
所有代码采用 MIT License 开源。