JS原生animate动画函数之动画联动
位置:
首页 >
前端三套件[ 发布时间: 2024.6.8 作者: 马黑 阅读: 163 ]
上面的演示,图片是火星牌高科技产品,我们姑且称之为转动器。它的运转需要其下方供电设备提供能源,就是电池。电池以绿色表示电量,每一次充满电可供火星转动器旋转 60000 毫秒即 1 分钟(相当于现实生活中的1年)。转动器工作时可以随时暂停和启动,缺电时停止工作。电池电能耗尽后,单击电池可给电池充电,秒冲。
转动器和电池是各自独立的动画单元,但彼此间有联动:电池电能耗尽,转动器会以缓动方式停止转动;电池一旦充满电,整体设备立刻投入工作;转动器暂停时,电池没有消耗,反之电量按预设功耗衰减。
此外,如前已经提到,转动器动画有缓动效果:电池满电状态时转动速度逐渐加快直至正常速度停止加速、电池即将耗尽电能时逐渐减速直至停止。
演示实例使用到动画的 onfinish 事件和 currentTime 属性。onfinish 事件针对非 Infinity(不停歇)运行的动画,因为只有 iterations(迭代属性,在此意为重复)设置为不是永动的情况下才会有结束的时候;currentTime 属性是动画运行的当前时间,可以利用它来判断电池的电能消耗是否已经到了某个临界从而触发转动器的减速机制。还有一个我们前面用过的属性 playState,动画运行状态,除了暂停状态(paused)、播放状态(running)外,我们的实例中还用到了结束状态(finished)。当然,使用动画运行的结束状态来判断电池是否耗完电能不是唯一的方法,例中我们在别处做同样的判断,使用的是代表电池的元素的 offsetWidth(宽度)是否大于 0 做依据。
演示实例完整代码:
<script>
let timer = null; //定时器运行id
//旋转画描述 :一个周期旋转360度
const rot = [
{transform: 'rotate(0)'},
{transform: 'rotate(360deg)'}
];
//旋转动画属性列表 :周期时长3秒、永动
const rotAttr = {
duration: 3000,
iterations: Infinity,
};
//电量消耗动画描述 :宽度从 100% 变为 0
const powergone = [
{width: '100%'},
{width: '0'}
];
//电量消耗动画属性列表 :结束时保持最后动画状态、1分钟运行周期、运行一次
const powergoneAttr = {
fill: 'forwards',
duration: 60000,
iterations: 1
};
//运行动画并获取操作入口
const h7Ani = h7.animate(rot, rotAttr); //转动器
const chargeAni = charge.animate(powergone, powergoneAttr); //电池
//转动器开始转动速率
h7Ani.playbackRate = 0.1;
//电池耗尽事件
chargeAni.onfinish = () => {
h7Ani.pause();
pa.title = '单击充电';
h7.title = '缺电';
};
//转动器速率控制函数
const controller = () => {
//开始转动时慢速
let val = Math.round(h7Ani.playbackRate * 100) / 100;
if(val < 1 && chargeAni.currentTime < 60000) h7Ani.playbackRate = val * 1.2;
//电池即将耗尽时减速
if(chargeAni.currentTime >= 56000) h7Ani.playbackRate = val * 0.8;
};
timer = setInterval(controller, 500); //运行定时器
//电池父元素点击事件
pa.onclick = () => {
if(charge.offsetWidth > 0) return false;
h7Ani.playbackRate = 0.1;
h7Ani.play();
chargeAni.play();
pa.title = '放电中';
};
//转动器单击事件 :依据动画运行状态决定点击功能
h7.onclick = () => {
if(chargeAni.playState === 'finished') return false; //缺电时单击无效
if(h7Ani.playState === 'running') { //如果动画运行中 则
h7Ani.pause(); //暂停转动
chargeAni.pause(); //电池不损耗
clearInterval(timer); //清除定时器
h7.title = '启动';
}else{ //否则 则
h7Ani.play(); //继续旋转
chargeAni.play(); //继续耗电
timer = setInterval(controller, 500); //恢复定时器
h7.title = '暂停';
};
};
</script>
前一篇: JS原生animate动画函数之复合动画与缓动动画
下一篇: JS原生animate动画函数应用实例:文本转场效果
发表评论:
评论列表 [2条]
#2 | 悄然 于 2024-6-8 21:20 发布: 感觉这个联动状态好复杂啊。。点转动器暂停,电池停止损耗。。。电池用完后点电池,转动器也开始转动。它们之间互相影响。。这个安排太精细啦。。
#1 | 小希 于 2024-6-8 21:16 发布: 火星转动器一年充一次,且可秒充。。这个电池状态简直就是最最理想的状态。。