【免费下载链接】editonny
Local video editing through conversation. Created by Matheus Gomes.
editonny 是一个本地运行的对话式视频剪辑工具(开源、免费),你只需用自然语言描述剪辑意图,它就能自动完成剪辑、字幕与动效合成。本文聚焦它的 3D 场景运行时:动效画面基于 Three.js 构建,核心能力是"任意时间寻址"——把场景拖到时间轴上任意一秒,画面都能精确重放到那一刻。
一、什么是"任意时间寻址"
普通网页动画通常靠"每帧累加"推进:这一帧旋转 1°,下一帧再转 1°。这种写法在预览时没问题,但一旦剪辑工具需要跳转到时间轴任意位置重渲染(逐帧抽帧、seek 预览、渲染导出),累加状态就会算错——跳过去的那段时间被"欠账"了。
editonny 的 3D 场景反其道而行:
- 场景构建时返回一个纯函数
draw(time):输入时间 → 输出该时刻的完整画面; - 官方场景模板明确要求:"Never accumulate frame-to-frame state: seeking to the same time must produce the same frame"(禁止跨帧累积状态,seek 到同一时间必须得到同一帧)。
这条规则写在场景开发文档 scenes/README.md 中,是 editonny 3D 场景的"宪法"。它带来一个直接的好处:预览画面与最终导出帧逐帧一致,所见即所得。
二、场景骨架:three-scene.js 门面与 engine 模块
3D 场景的统一入口是 three-scene.js(facade 门面文件),它把整个运行时 API 一次性导出:
| 类别 | 主要 API | 作用 |
|---|---|---|
| 渲染核心 | initialize | 初始化 WebGL 渲染器、相机、环境光照,返回draw |
| 时间函数 | clamp/mix/smooth/interval/word/moment | 时间区间、缓动、口语词锚点 |
| 相机函数 | orbit/mixPose/frameCamera/fittingDistance | 轨道相机与自动取景 |
| 几何/材质 | plate/box/cylinder/volumeText/loadModel/mediaTexture | 实体、体积文字、GLTF 模型、贴图 |
底层 Three.js 使用本地固定版本的资源(three.module.min.js、GLTFLoader.js、RoomEnvironment.js),放在 assets/three/ 目录,保证离线渲染和版本一致性。
三、draw(time):让"重放"成为可能的核心 API
打开 stage.mjs 可以看到initialize的收尾逻辑(核心片段):
const draw = (t) => { const tt = clamp(Number(t) || 0, 0, DUR); // 时间被钳制在 [0, 时长] 内 update(tt); // 场景状态完全由 tt 推导 for (const tx of textures) tx.update(); // 同步贴图 renderer.render(scene, camera); // 渲染该时刻画面 };要点只有两个:
- 一切状态都是时间的函数——物体旋转角、阴影位置、标签透明度,全部由传入的
t计算得出,而不是上一帧残留; - 时间做钳制,seek 超出范围也不会渲染异常帧。
场景构建阶段还会做一次"预演体检":以 30fps 采样遍历整个时长,检查相机路径是否会"穿模"进入物体内部,命中就写入警告(camera enters "..." at xx s),而不是等到导出时才发现。
口语词锚点:动画跟着"人话"走
time.mjs里的word和moment工具支持用口播词而非绝对秒数定义动画时机,例如内置场景 volume.html 中:
turn: { word: "just", standard: 0.8 }, // 主角说到 "just" 时开始旋转若转写中找不到该词,回退到standard的秒数。这让 3D 动效天然对齐语音节奏——正是对话式剪辑最需要的能力。
四、相机取景:orbit 与 fittingDistance
camera.mjs 把"构图"变成了数学问题:
orbit(camera, pose):用目标点 + 距离 + 方位角 + 仰角(球坐标姿态)确定相机,mixPose可在两个姿态间平滑插值;fittingDistance:给定物体包围盒,用二分搜索求出"物体恰好完整落在安全区"的相机距离,自动取景不再靠手调;frameCamera:把视口对齐到画面安全区(safeArea),适配 9:16、4:5 等竖版格式。
五、场景如何接入时间轴
每个场景 HTML 把一个暂停的 GSAP 时间线注册到window.__timelines[id],并用一个代理时钟驱动 3D 渲染(见 volume.html):
const tl = gsap.timeline({ paused: true }); tl.fromTo(clock, { t: 0 }, { t: DUR, duration: DUR, ease: "none", onUpdate: () => draw && draw(clock.t) }, 0); window.addEventListener("hf-seek", () => { if (draw) draw(clock.t); });播放/seek 由 HyperFrames 运行时驱动:它跳到哪一秒,就把时间线推到哪一秒,draw(clock.t)立即重渲染——任意时间寻址就此闭环。自定义场景只需在 project.json 中注册文件与起止时间({"scenes": [{"file": "compositions/scenes/xxx.html", "start": 2, "end": 7}]})即可。
六、质量如何保障
- 构建期:
python3 build.py hf lint/hf check校验组合结构(见 project-template/README.md); - 诊断面板:
window.__scene3d[id]暴露 ready 状态、警告列表、Three.js 版本与构建耗时; - 自动化测试:tests/three-engine.test.mjs 校验门面 API 完整性与时间函数边界值,scripts/smoke_three.mjs 在真实浏览器里跑通实体、体积文字、贴图与标签的完整渲染冒烟测试。
官方参考文档 references/3d.md 还强调:只有真实几何、光照、相机与遮挡才算 3D,"平铺层 + 视差"只能算 2.5D。
七、小结
editonny 的 3D 场景运行时可以概括为一句话:用draw(time)纯函数取代逐帧累加,用口语词锚点取代绝对时间,用本地固定的 Three.js 保证确定性渲染。这套设计让对话式剪辑里的 3D 动效既能被任意 seek、又能被逐帧精确导出,是"本地、可复现、所见即所得"理念的典型落地。
想动手实践?可参考 project-template 构建文档 与 3D 参考指南,从内置场景 volume / exploded / path / screen 出发,逐步替换成自己的几何体与台词锚点。
【免费下载链接】editonny
Local video editing through conversation. Created by Matheus Gomes.
相关推荐
TexLab性能优化终极指南:如何配置大型LaTeX项目获得最佳响应速度
TexLab性能优化终极指南:如何配置大型LaTeX项目获得最佳响应速度 TexLab是一款专为LaTeX设计的语言服务器协议实现,能够显著提升大型LaTeX项
three.js PropertyBinding 完全指南:场景图属性绑定与动画 Track 寻址机制
three.js PropertyBinding 完全指南:场景图属性绑定与动画 Track 寻址机制 PropertyBinding 是 three.js 动
3D渲染图形学前端Leva与Three.js集成:在3D场景中实现实时参数调整的终极指南
🌋 Leva 是一个React优先的组件GUI库,专门用于创建直观的参数控制面板。当它与强大的3D图形库Three.js结合时,你可以轻松实现3D场景中参数的
UI组件前端开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考