JSFiddle - React, Tailwind, and code Playground
CSS
div {
height: 100px;
background: red;
}
JavaScript
var c4 = (2 * Math.PI) / 3
function easeOutElastic (x) {
return x === 0 ? 0 : x === 1 ? 1 :
Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1
}
var div = document.getElementsByTagName('div')[0] // 要变化高度的 div
var startValue = 100 // div 的初始高度
var endValue = 400 // div 的最终高度
var changeValue = endValue - startValue // div 变化了这么多高度
var during = 2000 // 动画持续 2 秒钟
// 为了让动画足够流畅,我们需要达到 60 帧/每秒的动画速率,
// 即大约 17 毫秒更新一次动画的状态
var updateTime = 1000 / 60
// 计算出两秒内我们需要更新动画多少次
var updateCount = during / updateTime
// 我们需要一个在下一帧执行动画的函数
var rAF = window.requestAnimationFrame || function(cb) { setTimeout(cb, updateTime) }
var startPosition = 0 // 动画的开始时间点是 0%
var endPosition = 1 // 动画的结束时间点是 100%
// 因为我们要在动画从 0% 运动到 100% 时更新 `updateCount` 次动画,
// 所以要计算出每次更新动画时动画经过的时间
var perUpdateDistance = endPosition / updateCount
var position = startPosition // 记录动画的当前时间点
function step () {
// 计算 div 在当前时间点的高度
var height = startValue + changeValue * easeOutElastic(position)
div.style.height = height + 'px' // 更新 div 的高度
position += perUpdateDistance
// 如果动画还没结束,则准备在下一帧更新动画
if (position < endPosition) {
rAF(step)
} else {
console.log('动画结束')
}
}
step() // 开始运行动画