You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否有可生成自定义关键帧函数的JavaScript库或方法?

实现关键帧驱动的滚动图片高度动画

直接上可行的实现方案,核心是写一个关键帧插值工具函数,配合滚动事件实时计算即可:

首先定义你的关键帧配置,每个关键帧可以指定对应的缓动函数(没有的话默认线性插值):

// 关键帧配置:按时间点升序排列,time范围0-1,value是目标高度(px),easing是可选的插值函数
const heightKeyframes = [
  { time: 0, value: 400 },
  { time: 0.5, value: 400 },
  { time: 0.75, value: 200, easing: (t) => 1 - Math.pow(1 - t, 3) }, // 指数递减缓动
  { time: 0.95, value: 150 },
  { time: 1, value: 150 }
];

然后写一个插值计算函数,根据当前滚动进度(0-1)返回对应的高度值:

function getInterpolatedValue(progress, keyframes) {
  // 处理边界情况:进度小于第一个关键帧或大于最后一个
  if (progress <= keyframes[0].time) return keyframes[0].value;
  if (progress >= keyframes[keyframes.length - 1].time) return keyframes[keyframes.length - 1].value;

  // 找到当前进度所在的关键帧区间
  let prevFrame, nextFrame;
  for (let i = 0; i < keyframes.length - 1; i++) {
    prevFrame = keyframes[i];
    nextFrame = keyframes[i + 1];
    if (progress >= prevFrame.time && progress <= nextFrame.time) break;
  }

  // 计算区间内的相对进度(0-1)
  const t = (progress - prevFrame.time) / (nextFrame.time - prevFrame.time);
  // 应用缓动函数,默认线性
  const easedT = nextFrame.easing ? nextFrame.easing(t) : t;

  // 计算插值后的最终值
  return prevFrame.value + (nextFrame.value - prevFrame.value) * easedT;
}

接下来绑定滚动事件,实时计算滚动进度并更新图片高度:

const targetImg = document.getElementById('animated-img');

function updateImgHeight() {
  // 计算当前滚动进度:0(顶部)到1(底部)
  const scrollTop = window.scrollY;
  const totalScrollable = document.documentElement.scrollHeight - window.innerHeight;
  const scrollProgress = totalScrollable > 0 ? scrollTop / totalScrollable : 0;

  // 获取插值后的高度
  const currentHeight = getInterpolatedValue(scrollProgress, heightKeyframes);
  // 应用到图片
  targetImg.style.height = `${currentHeight}px`;
}

// 初始化执行一次,避免初始状态错误
updateImgHeight();
// 绑定滚动事件
window.addEventListener('scroll', updateImgHeight);
// 窗口 resize 时也更新,避免滚动进度计算错误
window.addEventListener('resize', updateImgHeight);

对应的HTML结构示例:

<img id="animated-img" src="your-image.jpg" style="width: 100%; object-fit: cover;" />

关键说明:

  • 关键帧必须按时间点升序排列,否则区间查找会出错
  • 缓动函数接收一个0-1的参数t,返回0-1的处理后值,你可以自定义各种曲线:
    • 指数递减:(t) => 1 - Math.pow(1 - t, 3)
    • 线性:(t) => t(默认)
    • 二次缓入:(t) => t * t
    • 你甚至可以写自定义的非线性逻辑,只要输出在0-1范围内即可
  • 滚动进度计算考虑了窗口resize的情况,避免布局变化导致进度错误

内容的提问来源于stack exchange,提问作者EricHier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:26:03