noah-motion

零依赖的小型动画库。闭式弹簧、可以随意拖动的时间轴、几个常用的网页动效,同一份动画既能在网页上播放,也能逐帧导出成视频。

新作品廊新增 10 个场景:主图卖点、扩散出图、水墨晕染…
41
原创场景
0
运行时依赖
8KB
gzip 后
60fps
逐帧导出 MP4

TypeScript · 默认照顾“减少动态效果”设置 · MIT

在 GitHub 上查看 看作品廊 ↓
npm i github:noahvisualsx/noah-motion

功能演示

库里每个功能的最小例子,可以直接上手操作。

弹簧

不逐帧模拟,直接解方程:给一个时间,立刻得到位置和速度。拖动下面两个滑块,看曲线怎么变。

import { spring } from 'noah-motion';
const s = spring({ duration: 0.5, bounce: 0.25 });
s(0.2);          // 第 0.2 秒的进度
s.velocity(0.2); // 第 0.2 秒的速度
s.toCSS();       // { easing: 'linear(0, …, 1)', duration: 812 }

时间轴

每个属性写成关键帧轨道,前一段没停稳就换目标也会自然衔接。整个画面是时间的纯函数,拖动进度条可以停在任意一帧。

noah-motion
0.00s
import { track, timeline, spring } from 'noah-motion';
const w = track(16, [[0.4, 220], [2.2, 120], [3.4, 16]]);
const tl = timeline({ duration: 4, loop: true, target: stage, render(t) {
  shape.style.width = w(t) + 'px';
}});
tl.seek(1.5);

网页小工具

从 noah-motion/dom 引入,都用弹簧驱动。

flip · 布局变化动画
await flip('.tile', () => grid.append(...shuffled));
countUp · 数字滚动
21.2万浏览
1033点赞
536收藏
morph · 尺寸变形
morph(button, () => { label.textContent = '已复制'; button.classList.add('done'); });
denoise · 生成式出现

像扩散模型一轮轮去噪:模糊和噪点分几步减弱。

reveal · 滚动进场

导出视频

同一份时间轴,用命令行逐帧截图,再用 ffmpeg 合成 MP4。每一帧都是算出来的,不会掉帧。

import { exposeForRender } from 'noah-motion';
exposeForRender(tl);

# 终端里
npx noah-motion render demo/hero.html --out hero.mp4 --size 1080x1080 --motion-blur 4

# 作品廊里的任意场景(16:10)
npx noah-motion render demo/scene.html --query name=orbits --out orbits.mp4 --size 1280x800

导出的就是这段 片头动画:1080×1080、60 帧、6 秒,只有 233KB。