mcpField
S
scroll-film

scroll-film

github.com/moh4696其他276 次安装今天更新
代码仓库

关于 scroll-film

scroll-film 是用于构建滚动控制画布动画的网页技能,可将渲染片段处理为帧序列或可寻址视频,并支持停帧、平滑和减少动态效果。

主要功能

  1. 01将滚动进度映射到画面帧
  2. 02制作 WebP 帧序列或 MP4 视频
  3. 03检测片段衔接处的跳变
  4. 04为字幕段落设置停帧
  5. 05支持减少动态效果偏好

适用场景

  1. 01制作滚动驱动的落地页动画
  2. 02呈现沿固定镜头路径生成的场景
  3. 03字幕显示时暂停画面
  4. 04为手机视口准备独立素材

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/moh4696/open-3d-skills --skill scroll-film

安装后在 Claude Code 中输入/scroll-film确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
assets/
scroll-film.js
scripts/
prep.py

详细介绍

滚动画卷

滚动画卷会在访客滚动浏览一个较长的区块时固定画布,并根据滚动位置选择帧。访客控制镜头,因此即使每一帧都提前渲染好了,效果仍有三维感。当运动过于复杂、不适合实时 3D(生成的世界、液体、人物),且路径固定时,这就是合适的工具。

工具

文件功能
assets/scroll-film.js引擎:固定画布、带停留段的进度到帧映射、帧序列或视频、平滑处理、减少动态效果
scripts/prep.py frames将片段合并为一个带编号的 WebP 序列和清单
scripts/prep.py video将片段合并为一个支持即时定位的 MP4
scripts/prep.py seams为片段之间的每个衔接处评分,并在出现明显跳变时失败

需要 ffmpeg 和 ffprobe、Python 3.9+,以及 pip install pillow numpy。制作片段请用 motion-assets;透明主体请用 alpha-cutout;检查结果请用 site-check 和 frame-capture。

生成前先规划

  1. 按节拍编写故事。 每个场景对应一个节拍:镜头一开始看到什么、镜头移向哪里、访客在那里会读到什么。四到七个节拍足以填满一个落地页。一个节拍对应一个生成的片段(一“段”)。
  2. 先生成所有关键帧,并确保风格统一。 每一段都在起始帧和结束帧之间生成,而上一段的结束帧就是下一段的起始帧。在生成任何视频前,先用同一个模型和同一个风格参考图生成所有关键帧静帧,并将它们并排排列。静帧之间风格漂移,整部影片的风格也会随之漂移。
  3. 明确估算预算。 成本大致为静帧费用加上片段数量乘以单个片段的价格。手机竖屏版本会使视频成本翻倍(见“手机”)。投入前先用一张静帧和一个片段进行校准(motion-assets 涵盖模型选择、定价和速率限制)。

构建

  1. 生成各段,使用第 2 步中的起始帧和结束帧。检查每个衔接处:

    python3 scripts/prep.py seams legs/01.mp4 legs/02.mp4 legs/03.mp4
    

    低于 4 就看不出来;高于 10 就会出现跳变。若衔接不佳,请以紧接前一段最后一帧的画面为锚点重新生成该段(用 ffmpeg 提取该帧,而不是重复使用静帧:模型会稍微改变色彩和构图)。

  2. 选择帧序列或视频。

    帧序列(默认)可拖动定位的视频
    精确度每个滚动位置都对应精确帧定位会稍有延迟,在 Safari 和低端手机上最明显
    大小1280 到 1600 px 时每帧 20 到 60 kB大约只有前者的三分之一
    适用场景最多约 300 帧注重体积而非精度的长影片
    python3 scripts/prep.py frames legs/*.mp4 site/film/lg --width 1600 --fps 24
    python3 scripts/prep.py frames legs/*.mp4 site/film/sm --width 900 --fps 24 --quality 72
    python3 scripts/prep.py video legs/*.mp4 site/film.mp4 --width 1920 --gop 4
    

    frames 会丢弃每个后续片段的第一帧,因为它与前一片段的最后一帧重复。video 使用 4 帧 GOP 且不使用 B 帧:普通导出若使用 250 帧 GOP,每次定位都要解码数百帧,导致拖动时卡顿。

  3. 标记区块。 高度决定影片需要滚动多长距离。大致按影片每秒对应一个视口的滚动距离,会让节奏显得从容;距离更短则会显得仓促。

    <section id="film" style="height: 600vh">
      <div class="pin" style="position: sticky; top: 0; height: 100vh">
        <canvas style="width: 100%; height: 100%; display: block"></canvas>
        <div class="captions">...</div>
      </div>
    </section>
    
  4. 接入引擎。

    import { ScrollFilm } from "./scroll-film.js";
    const small = matchMedia("(max-width: 760px)").matches;
    const film = new ScrollFilm({
      section: document.querySelector("#film"),
      canvas: document.querySelector("#film canvas"),
      frames: { count: 247, src: (i) => `film/${small ? "sm" : "lg"}/${String(i).padStart(3, "0")}.webp` },
      keys: [[0, 0], [0.18, 60], [0.3, 60], [0.62, 160], [0.72, 160], [1, 246]],
      onUpdate: ({ progress }) => captions(progress),
      onReady: () => document.body.classList.add("film-ready"),
    });
    

    keys 是 [progress, frame] 对。同一帧对应两个键就会形成停留段:影片会在某个节拍处暂停,同时说明文字滚入和滚出。每个包含文字的节拍都应设置停留段。若没有停留段,文字就会叠在移动的画面上,没人看得清。

    smooth(默认值 0.18)会让影片平滑地跟随滚动位置,并且不受帧率影响,因此鼠标滚轮的一步步滚动会变成流畅运动,而不是画面跳变。如果页面已经平滑处理滚动(Lenis),请设置 smooth: 1。

    说明文字和图层通过 onUpdate 读取 progress。在停留段开始时,用一小段范围淡入说明文字,并在停留段结束时淡出;让文字避开画面中最繁忙的区域,必要时在后方加一层柔和的遮罩。

手机

将 16:9 影片居中裁切为手机竖屏画面,通常会裁掉主体。请检查每个节拍的裁切效果。如果不合适,请根据竖屏关键帧生成 9:16 竖屏片段,并将其作为单独的一组发布,通过媒体查询切换;还要提前说明,这会使视频预算翻倍。只有当每个节拍中的主体都处于画面中间三分之一时,居中裁切才合适。

手机也应使用较小的帧集,整部影片的大小应控制在约 8 MB 以内。

加载

  • 将第 0 帧作为 <img> 放入 HTML 中(或设为画布背景),这样首次绘制时显示的就是影片,而不是空白框。
  • 引擎会先加载第 0 帧,再加载最后一帧,然后按由粗到细的顺序加载分布帧(每隔 64 帧、32 帧,依此类推),每次加载 6 帧。访客快速滚动时,总能停在接近已解码帧的位置,并看到画面逐渐变清晰。
  • 视频模式会先将整个文件下载为 blob,再开始播放,因此跳转时无需等待网络。
  • 请使用支持 Range 请求的主机。python3 -m http.server 不支持此功能,因此它所提供的视频无法跳转;在本地,请使用 frame-capture 技能中的 serve.py。

减少动态效果

设置 prefers-reduced-motion: reduce 时,引擎会在关键帧之间切换(默认值为 reducedMotion: "steps"),而不是播放视频,因此每个节拍仍会显示对应画面。"still" 则只显示最后一个关键帧。

检查

  • 使用 frame-capture 技能,以较低帧率录制滚动过程,按秒评估节奏:record.py URL check.mp4 --fps 8 --seconds 20 --scroll "0:0 18:100%"。
  • 快速上下拖动:画面不能空白,接缝处不能闪烁,滚动固定应在末尾平滑解除。
  • 在限速网络下加载:首次绘制时应显示第 0 帧。
  • 检查手机视口和较短的笔记本电脑视口(1280x720):字幕不能遮住主体。

评论

支持 Markdown