前言
因项目需要,需要在元素上实现动画重复播放,并且需要自定义动画间隔。
一开始想到的是animation-delay
,但这个只有在第一次动画开始的时候才生效
在网上找了很多方法,最终的方法基本都是改动画规则,比如
@keyframes move{
/* 此处从75%开始 */
75%{ transform: translateX(0px);}
100%{ transform: translateX(100px);}
}
例如设置animation-duration
总动画设为4秒,然后前75%也就是3秒都没变化(0-75%),之后的25%也就是1秒做动画,相当于就实现了每间隔3秒
但这个满足不了我的需求,我们使用的是animate.css库,不方便直接去修改keyframes
下面是用js实现的俩种方式:
监听animationend
事件
当 CSS 动画播放时,可能会发生三个事件:
animationstart
– 当 CSS 动画开始时触发animationiteration
– 当 CSS 动画重复时触发animationend
– 当 CSS 动画完成时触发
所以我们只需要监听animationend
事件完成时重新触发动画就行
// 下面是html
<div id="test" class="animate__animated animate__bounce">Example</div>
// js
let testDom = document.getElementById('test')
let intervalTime = 6
testDom.addEventListener('animationend', function(event) {
// 移除再添加动画样式 重新触发动画
testDom.classList.remove('animate__bounce')
setTimeout(()=>{
testDom.classList.add('animate__bounce')
},intervalTime * 1000)
});
结合animation-play-state
设置 animation-delay
为负值
animation-delay
其实是可以设置为负值的,设置负值的动画会立即执行,负值设置多少,动画跳过多少秒进入动画周期。
比如设置 -1s
时,动画就会从 1s
开始执行。此时如果我们再加上animation-play-state
为pause
,那么延迟设置为 -1s
时,动画就停留 1s
时的状态。然后使用js结合一个timer就可以计算在每个时刻动画的状态。
直接看demo,先设置animation-play-state:paused
暂停动画,然后调用setAnimateInterval
执行
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
<style>
#test {
animation-play-state:paused;
}
</style>
</head>
<body>
<h1 id="test" class="animate__animated animate__rubberBand">This is a simple animation!</h1>
<script>
const testDom = document.getElementById('test')
function setAnimateInterval(target, intervalTime) {
// 单位转毫秒
intervalTime = intervalTime * 1000
// 获取动画时间
let durationTime = window.getComputedStyle(target).getPropertyValue('animation-duration');
// 去掉单位转换为数字
durationTime = new Number(durationTime.replaceAll('s','')) * 1000
// 设置动画时间
const startTime = new Date().getTime();
window.requestAnimationFrame(function animate() {
const currentTime = new Date().getTime();
const time = (currentTime - startTime) % (intervalTime + durationTime)
// 判断是处于动画时间内还是间隔时间内
if (time <= durationTime) {
const percent = time / durationTime;
target.style.animationDelay = `-${percent}s`;
}
window.requestAnimationFrame(animate);
});
}
setAnimateInterval(testDom, 6)
</script>
</body>
</html>
原文链接:https://juejin.cn/post/7358028068769316915 作者:方寸不乱步稳行