css动画添加间隔

前言

因项目需要,需要在元素上实现动画重复播放,并且需要自定义动画间隔。 一开始想到的是animation-delay,但这个只有在第一次动画开始的时候才生效

在网上找了很多方法,最终的方法基本都是改动画规则,比如

css 复制代码
@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事件完成时重新触发动画就行

javascript 复制代码
// 下面是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-statepause,那么延迟设置为 -1s 时,动画就停留 1s 时的状态。然后使用js结合一个timer就可以计算在每个时刻动画的状态。

直接看demo,先设置animation-play-state:paused暂停动画,然后调用setAnimateInterval执行

html 复制代码
<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>
相关推荐
不好听6133 小时前
从一行 JSX 到屏幕像素:前端开发者必须懂的浏览器渲染管线
前端
恒拓高科WorkPlus3 小时前
企业级内网即时通讯建设模型:BeeWorks内网IM四层架构
前端
前端小李子4 小时前
前端环境变量裸奔?我用 EnvShield 给它穿了件防弹衣
前端
youtootech4 小时前
HarmonyOS《柚兔学伴》项目实战25-我的页面、Web 嵌入与项目总结
前端·华为·harmonyos
小林ixn5 小时前
从零到一理解 React 父子组件通信:手写一个 Todo 应用带你彻底搞懂单向数据流
前端·javascript·react.js
醇氧6 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
qetfw8 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
甲维斯8 小时前
我要开始吹牛逼了!Kimi K3 “宇宙无敌”!
前端·人工智能
a1117768 小时前
微光小屋-前端养成小游戏 开源项目
前端