如何保持CSS抖动动画速度同时延长动画间隔?
实现固定抖动时长、可调整间隔的无限循环按钮抖动效果
方案一:纯CSS双动画实现
把抖动动作和间隔延迟拆成两个独立动画,既保证抖动过程的时长固定,又能灵活调整间隔:
wiggle-action专门负责抖动过程,固定时长0.6s(对应原动画4s周期的15%时长),只执行一次完整抖动。wiggle-delay负责控制抖动的触发时机,通过占位属性实现间隔延迟,总时长等于「抖动时长 + 间隔时长」。
CSS 代码
/* 固定时长的抖动动作 */ @keyframes wiggle-action { 0% { transform: rotate(0); } 20% { transform: rotate(10deg); } 40% { transform: rotate(-10deg); } 60% { transform: rotate(10deg); } 80% { transform: rotate(-10deg); } 100% { transform: rotate(0); } } /* 控制间隔的动画,总时长=抖动时长+间隔时长 */ @keyframes wiggle-delay { 0%, 15% { animation-name: wiggle-action; animation-duration: 0.6s; animation-timing-function: linear; animation-iteration-count: 1; } 15.1%, 100% { animation-name: none; } } .wiggle-btn { width: 120px; padding: 8px 16px; cursor: pointer; animation: wiggle-delay 4s linear infinite; /* 默认总时长4s,间隔=4s-0.6s=3.4s */ }
调整间隔的方法
通过JS读取输入框的间隔值,动态修改wiggle-delay的动画总时长:
假设输入的间隔为gap秒,总动画时长设为 0.6 + gap 秒即可,直接修改按钮的animation-duration属性。
方案二:JS + CSS 结合(setInterval 实现)
用JS控制抖动触发时机,CSS只负责固定时长的抖动动画,间隔完全由setInterval控制,灵活性更高。
CSS 代码
@keyframes wiggle { 0% { transform: rotate(0); } 3% { transform: rotate(10deg); } 6% { transform: rotate(-10deg); } 9% { transform: rotate(10deg); } 12% { transform: rotate(-10deg); } 15% { transform: rotate(0); } } .wiggle-btn { width: 120px; padding: 8px 16px; cursor: pointer; } /* 抖动状态类 */ .wiggle-active { animation: wiggle 0.6s linear forwards; /* 固定0.6s完成抖动 */ }
JS 代码
<input type="number" id="gapInput" value="3.4" min="0" step="0.1" placeholder="间隔时间(秒)"> <button class="wiggle-btn" id="targetBtn">抖动按钮</button> <script> const targetBtn = document.getElementById('targetBtn'); const gapInput = document.getElementById('gapInput'); let intervalId; // 触发单次抖动 function triggerWiggle() { targetBtn.classList.add('wiggle-active'); // 动画结束后移除类,避免重复叠加 targetBtn.addEventListener('animationend', () => { targetBtn.classList.remove('wiggle-active'); }, { once: true }); } // 启动/更新间隔抖动 function startWiggleInterval() { if (intervalId) clearInterval(intervalId); const gap = parseFloat(gapInput.value) * 1000; // 转毫秒 triggerWiggle(); // 先触发一次 intervalId = setInterval(triggerWiggle, gap + 600); // 总周期=间隔+抖动时长 } // 输入框变化时更新间隔 gapInput.addEventListener('change', startWiggleInterval); // 初始启动 startWiggleInterval(); </script>
说明
- 抖动时长固定为0.6s,不会随间隔调整变慢。
- 输入框控制的是两次抖动之间的间隔时间,总循环周期=间隔时间+0.6s。
- 利用
animationend事件确保每次抖动完成后再移除状态类,避免动画冲突。
内容的提问来源于stack exchange,提问作者bib
相关产品推荐
相关产品推荐

