如何将CSS命名缓动函数转为JS可用的cubic-bezier数值
解决命名缓动函数转贝塞尔数值的问题
要把ease-in这类CSS命名缓动函数转换成对应的贝塞尔曲线数值,核心是利用CSS标准中定义的命名缓动与贝塞尔曲线的映射关系,通过构建映射表完成转换,进而同步JavaScript动画时序。
步骤1:定义命名缓动到贝塞尔曲线的映射
CSS规范已为所有命名缓动函数指定了标准贝塞尔参数,直接用对象存储映射关系即可:
const easingMap = { 'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)', 'linear': 'cubic-bezier(0, 0, 1, 1)', 'ease-in': 'cubic-bezier(0.42, 0, 1, 1)', 'ease-out': 'cubic-bezier(0, 0, 0.58, 1)', 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1)' };
步骤2:统一处理缓动函数格式
获取元素的animation-timing-function后,判断是否为命名缓动,是则替换为对应贝塞尔字符串,否则直接返回原内容:
function getBezierString(timingFunc) { return easingMap[timingFunc] || timingFunc; }
步骤3:修改原代码适配所有场景
将上述逻辑整合到代码中,即可同时处理命名缓动和自定义贝塞尔缓动:
document.addEventListener("DOMContentLoaded", () => { const i = document.querySelector("i"); const b = document.querySelector("b"); const span = document.querySelector("span"); // 命名缓动到贝塞尔的映射表 const easingMap = { 'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)', 'linear': 'cubic-bezier(0, 0, 1, 1)', 'ease-in': 'cubic-bezier(0.42, 0, 1, 1)', 'ease-out': 'cubic-bezier(0, 0, 0.58, 1)', 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1)' }; // 转换缓动函数为贝塞尔格式 function getBezierString(timingFunc) { return easingMap[timingFunc] || timingFunc; } const iFunction = getComputedStyle(i)["animation-timing-function"]; const bFunction = getComputedStyle(b)["animation-timing-function"]; // 查看转换结果 console.log("💀 转换后: ", getBezierString(iFunction)); console.log("❤️ 原贝塞尔: ", getBezierString(bFunction)); // 处理元素b的动画参数 const bAnim = b.getAnimations()[0]; const bDuration = bAnim.effect.getTiming().duration; const bCurveStr = getBezierString(bFunction); const bCurveNumbers = bCurveStr.match(/[\d.]+/g).map(Number); const bEasing = BezierEasing(...bCurveNumbers); // 处理元素i的动画参数 const iAnim = i.getAnimations()[0]; const iDuration = iAnim.effect.getTiming().duration; const iCurveStr = getBezierString(iFunction); const iCurveNumbers = iCurveStr.match(/[\d.]+/g).map(Number); const iEasing = BezierEasing(...iCurveNumbers); // 同步显示两个动画的进度 setInterval(() => { // 计算元素b的进度 const bEasingX = (bAnim.currentTime % bDuration) / bDuration; const bPercent = bEasing(bEasingX); // 计算元素i的进度 const iEasingX = (iAnim.currentTime % iDuration) / iDuration; const iPercent = iEasing(iEasingX); span.innerText = `❤️: ${(bPercent*100).toFixed(0)}% | 💀: ${(iPercent*100).toFixed(0)}%`; }, 10); });
可行性说明
CSS规范对命名缓动的贝塞尔参数有明确且统一的定义,主流浏览器均严格遵循标准,因此使用固定映射表能确保JavaScript动画与CSS动画的时序完全同步。
内容的提问来源于stack exchange,提问作者Joel Peltonen
相关产品推荐
相关产品推荐

