• Y AnimationPlayground
研究工作台
  • 实验总览
  • D3
  • Lottie
  • Rive
示例库
  • 示例总览
  • SVG 示例
  • Three.js 示例
  • 代码视频示例
项目
  • 版本记录
GitHubX (Twitter)

SVG 示例

1 个示例

手写矢量几何、浏览器原生渲染的循环插画;每件作品都要说清它是怎么动的、成本多少、什么时候该换运行时。

返回 CSS + SVG 实验

设备插画族

二十台设备一套语法:共享等距几何与材质 token、同一个 MotionValue 时钟、每台恰好一处品牌色「信号」、一行等宽读数。画廊里各台错开相位、 同一节拍;加一台 = 一个场景文件 + 注册表一行。四种画法 —— 等距、机柜与电能表的正视图、分拣线与电池模组的平面图、接触器的剖视图 —— 说明这套语法约束的是风格与驱动方式,不是画法。族是按「动作」而不是 按行业扩的,二十台各带一种:出纸、波形、逐格点亮、盘位轮扫、往复填充、 液位涨落、旋转扫掠、传送过闸、取放易主、沿路径流动、字轮进位、门的开合、 关节链、色场、光束描线、双卷耦合、分度停歇、嵌套伸缩、双稳态吸合、 阻尼整定 —— 最后一种是全族唯一一台动作出自物理响应而非目标姿态的设备。

231 labels left

等距标签打印机标签从出纸口滑出、落地、被取走;计数递减

layer 1 / 14

龙门 3D 打印机横梁推进、喷头往复,当前层以品牌色铺满;一层一个周期

−1.7 dB

信号放大器一段品牌色爆发沿示波屏行进;dB 读数随包络起伏
U8U7U6U5U4U3U2U1

provisioning

8U 机柜U3 上架:指示鳍逐格点亮,读数从 provisioning 变 online

bay 2 · syncing

计算节点同步中的盘位以品牌色高亮,一个周期扫过五个盘位

battery · 85%

不间断电源市电中断转电池,电量柱下降;市电恢复后回充,绿灯亮回

108° · 3 targets

旋转激光雷达品牌色扇区绕轴一圈一个周期,扫过的目标点亮后按角距衰减

#4200 scanned

分拣线扫描门包裹过门时光幕闪亮,过门后带上品牌色描边;一周期一件

tape 01 → drive

磁带库取料手把磁带从格位搬进驱动器,格子空出、绿灯亮起

door 01 · open

智能快递柜一格柜门绕铰链转出,露出包裹,随后合上锁定

pump 62% · Δ9 °C

液冷回路冷却液沿管路流动;冷板到散热器的热腿是品牌色,回程是冷腿
0123456789001234567890012345678900123456789001234567890kWh

2.9 kW

电能表字轮随用电滚动并逐位进位,脉冲灯按功率闪烁

bolt 1 / 5 · 12 Nm

拧紧机器人工位手臂抬起落到下一颗螺栓并拧紧,拧过的留在原地亮着

B4 · 46 °C

电池模组二十四颗电芯的温度铺成一片场,热点在包内游走

mark 82% · 1 200 mm/s

激光打标机光束在工件上一段段描出标记,打完停一拍再换下一件

roll 91% · 180 m/min

卷绕机放卷变小、收卷变大,浮动辊随余料下坠,料带全程连着两卷

0 out · 2.6 s takt

分度转台压头落下的一刻工件被打上品牌色,带着它转到卸料位才交出去

level 1 · 0.0 m

伸缩桅杆堆垛机三节桅杆各走三分之一,品牌色托盘被送进对应层的货位

coil 22% · open

接触器(剖视)触头合上时贯穿两端的主回路亮起;掉下来要跌到更低的电压

480 g · settling

检重秤秤台整定完成、读数锁定的那一刻,指示线亮成品牌色
SVG + Motion零新增运行时无限循环
等距标签打印机
一个 MotionValue 时钟驱动圆盘、屏幕、LED 与出纸;计数器是真文字,随落地递减。

231 labels left

静态模式
暂停
倍速
×
剩余231
已出0
周期2600 ms
几何
52 个 SVG 节点 · 手写 2:1 等距投影
驱动
1 个 MotionValue 时钟 · useAnimationFrame
帧表现
120 fps · p95 9.2 ms · 每帧 0 次 re-render
体量
场景约 14 kB gzip · Motion 45 kB(首页已加载)
它是怎么动的
  • 所有几何在 iso.ts 里用 world 坐标 (x, y, z) 描述,再投影成屏幕坐标;world 圆投影为轴对齐椭圆,所以圆盘直接是 <ellipse>。
  • 一个 MotionValue 时钟由 useAnimationFrame 推进;圆环 stroke-dashoffset、屏幕高亮条位移、LED 透明度、出纸标签的位移与透明度全是它的 useTransform 派生值,直写 SVG 属性,不经过 React 状态。
  • 暂停 = 时钟不走;倍速 = 每帧 delta 乘系数;静态模式 = 时钟停在落地姿态;prefers-reduced-motion 映射到静态模式。
  • 计数器是舞台上的 DOM 文字,由每周期一次的「落地」回调递减 —— 与画面同源,所以天然同步。
这是纯 SVG 动画吗
  • 不是。几何是 SVG,驱动是 JavaScript(Motion);没有用 SMIL <animate>,也没有用 CSS keyframes。
  • 圆环、高亮条、LED、出纸这四样都能改成纯 SVG / CSS 驱动 —— stroke-dashoffset 关键帧、transform 步进、opacity 呼吸、translate + opacity 序列,零 JS。
  • 唯一做不到纯 SVG 的是计数器:「N labels left」要随每次落地递减,这需要一个能改文字内容的时钟。要么 JS,要么放弃同步。
  • 所以选了单时钟方案:既然计数器已经要一个 JS 时钟,就让它同时驱动画面,避免 CSS 动画与 JS 计数器各走各的表、越跑越不同步。
结论:Lottie、Rive 还是 SVG + Motion
这类画面 —— 纯色面、平移 / 旋转 / 透明度、一段要与画面同步的文字 —— 是 SVG + Motion 的舒适区。运行时体量上要诚实:Rive 的 330 kB WASM 没有争议;Motion(约 45 kB)与 Lottie Light 播放器(46.5 kB)其实相当,只是本仓库首页已经加载了 Motion。所以真正决定性的不是字节,而是三件 Lottie 给不了的事:颜色跟 token 走、计数器是真文字、改画面不用重导出。
什么时候换 Lottie
  • 设计师在 After Effects 里做好并持续迭代,交付物就是 JSON。
  • 画面含复杂路径变形、遮罩或位图,手写 SVG 不划算。
什么时候换 Rive
  • 需要 hover / 点击 / 数据驱动的多态切换,状态机比手写编排省事。
  • 同一资产要在 Web、iOS、Android 上跑同一套状态逻辑。

动态状态卡组

二十张卡共用一个壳(标题 / 面包屑 / 状态词 / 菜单 → 舞台 + 读数 → 标题句 + 说明 → 数据区 → 页脚 + 两个动作),数据区有行表与指标块两种词汇。每张卡只写自己的状态机, 二十张各演示一种:耗材见底、进度到头、槽位阈值、限值轮换、两段式终局、 会涨也会跌的量、逐周期改写的日志、被故障抢走的主按钮、越等越久的退避、 补偿到补不动的饱和、会随输入塌掉的预测、时间自己长出来的待办、修它要停机的 漂移、本卡管不了的终局、先解锁再确认的不可逆动作、错过就得停线的窗口、 由最慢一环定死的节拍、能力缩水后够不着的那一半、同一读数两种状态的磁滞、 两头都要付钱因而没有正确答案的取舍。 所有派生文案由状态算出,不存第二份;卡内文案沿用参考稿的英文,「···」里是跳到各状态的演示入口。

Label Printer/packing line · P2
Roll runs short

231 labels left

The roll runs out nine labels into the batch

240 labels are queued and 231 are left on the roll, so the run stops at label 232 unless a new roll goes on first

queued
240 labelsbatch 5104
on the roll
231 left9 short
media
50 × 25 mmthermal
Printer P2 · Packing line
Storage Tower/node 12 · 6 bays
Bay 4 rebuilding

Five drives are carrying the sixth

Bay 4 is rebuilding onto a spare. Until it finishes, the array has no parity left, so a second failure loses the volume

bays 1–3, 5–6
onlinehealthy
bay 4
rebuilding62% · 3 h left
parity
none while rebuildingat risk
Rebuild started 11:04
Print Job/printer 02 · 14 layers
Layer 7

layer 7 / 14

7 more layers after this one

Each pass lays one layer and the gantry rises by its height. The estimate assumes the remaining layers match the ones already down

layer
7 / 1432 min left
nozzle
214 °Cbed 60 °C
filament
62 g left1.75 mm
Started 09:12 · PLA
Power Shelf/rack 04 · 5.5 kVA
Recharging

mains · 62%

Mains is back, the pack is refilling

Charging while carrying the load. Runtime climbs back as it fills, so a second outage right now would be shorter than the first

circuitstate
mains feed
present230 V
battery
62%16 min
load
3.4 kW62% of rated
Last transfer 14:32
Worker Pool/us-east-1 · rack 04
U8U7U6U5U4U3U2U1

provisioning

One slot left before autoscale

U3 is warming and will accept traffic in about two minutes. The last empty slot is reserved for drain-and-replace

6 of 8
slots occupied
1
warming
72%
pool cpu
Autoscale at 7 of 8
Sort Line/dock 3 · lane B

#4200 scanned

Every parcel is being read at the gate

One parcel crosses the curtain per cycle. A parcel that fails the read goes down the reject chute instead of continuing, roughly one in 7

812
scanned
6
rejects
1,240 / h
throughput
Shift started 06:00
Signal Analyser/bench · channel 2
Peak over limit

−2.2 dB

Channel two clips whenever the compressor cycles

The trace sits well inside the window until the compressor kicks in, then runs three decibels over for about forty milliseconds — long enough to hear, short enough for the meter to miss

Channel 2Level · State
peak · 40 ms burst
+0.8 dB over limit
average level
−12.4 dB
limit
−3.0 dB
Sweep 20 Hz — 20 kHz
Perimeter Scanner/yard gate · 1 rev / 2.6 s
Scanning

000° · 3 targets

Three contacts, all where they should be

Each revolution re-measures all three returns. Nothing is inside the 6.0 m keep-out radius

contactrange
A · vehicle
11.8 mtracking
B · gate post
12.2 mfixed
C · fence corner
9.6 mfixed
Keep-out radius 6.0 m
Archive Restore/library 01 · 6 tapes
Tape 3

tape 03 → drive

4 tapes still to mount

The picker mounts one tape per pass. A tape that fails is retried with a growing delay before it is skipped

stagestate
mounted
2 of 633%
current tape
LTO-1042reading
unreadable
0none
Backoff 5s · 10s · 21s
Coolant Loop/node 12 · single loop
Holding

pump 50% · Δ9.0 °C

Rising load, steady temperature

Load is climbing but Δ has not moved, because the pump is speeding up to match. A flat temperature here means spare capacity, not a quiet machine

stagereading
heat load
210 W50% of capacity
pump
50%compensating
coolant Δ
9.0 °Cwithin spec
Capacity 420 W · spec Δ14 °C
Tariff Meter/site 04 · tiered
off-peak
0123456789001234567890012345678900123456789001234567890kWh

2.9 kW

Holding in the off-peak tier

The forecast divides what is left before the next tier by the current draw, so it is a projection and not a promise. Raising the load collapses it immediately, which is the point of watching it rather than the meter reading

meterreading
consumption
4217.6 kWhthis period
tier
off-peak1.0× rate
next tier
in 4.4 kWhabout 1.5 h
Tiers at 4222 and 4232 kWh
Locker Bank/station 07 · 10 cells
All within window

4 of 10 held

4 parcels waiting, none overdue

Parcels age one day per pass and are returned after 5 days. The oldest one here has 1 days left, which is the number worth watching

cellstate
held
4 of 106 free
oldest parcel
day 41 days left
to return
0none
Pickup window 5 days · depot run day 8
Fastening Cell/line 2 · 5 bolts per part
In tolerance

5 / 5 · 0.19 mm

6 parts done, still on centre

The tool centre point creeps as the cell warms up, about 0.014 mm per part. It is fine until it is not, which is why the number matters more than the parts count

stagereading
parts
634 bolts
tool centre drift
0.19 mmlimit 0.25 mm
downtime
6 minthis shift
Limit 0.25 mm · calibration 6 min
Battery Module/string 3 · 24 cells
Balanced

peak 44 °C

Pack is warm and even

Temperature is spread across the pack rather than piled into one cell, which is the shape you want. The number to watch is the peak, not the average

packreading
peak cell
44 °Ctrip 61 °C
spread
16 Khot to cold
contactor
closedcarrying load
Trip at 61 °C · physical reset
Marking Line/station 5 · permanent
spiral-24

spiral-24 · 1284

164 parts marked in this format

A mark is permanent, so changing the format splits the batch into a before and an after. That is why the button arms first instead of firing on the first press

linestate
parts marked
1284this shift
format
spiral-24since part 1120
pending change
nonenot armed
Arm expires after 8s
Web Line/coater 1 · 180 m/min
Running

roll 42% · 180 m/min

Roll is 42% and running down

The supply roll shrinks as the take-up grows, so the same web is always between them. The splice window opens on its own at 22%

linestate
supply roll
42%unwinding
splice window
closedopens at 22%
roll changes
3all flying
Window opens at 22% · 8s wide
Transfer Table/cell 4 · 6 stations
press is the constraint

takt 4.7 s

Takt is 4.7 s because press takes 3.8 s

The table cannot index until press is done, so nothing else on the list changes the takt. press is 1.2 s slower than drill — cut more than that and drill becomes the constraint instead

stationseconds
slowest · press
3.8 s+1.2 s
next · drill
2.6 swould take over
delivered
0 parts766/h
Index 0.9 s · floor 1.6 s/station
Putaway/aisle 2 · 5 levels
Full reach

level 1 · 0.0 m

All 10 pallets sit inside the 5-level reach

All three stages extend together, each covering a third of the 5.6 m lift. Anything on the queue can be reached, so the only thing setting the rate is the round trip

aislestate
queue
10 palletsnext level 1
mast reach
level 53 stages
put away
00 refused
Reach level 5 of 5 · 0 refused
Contactor/MCC 3 · K12
Closed

coil 100% · closed

Pulled in — the coil is above the 72% pick-up

It stays closed all the way down to 38%, far below the 72% it took to pull in. That gap is deliberate: without it a supply wobbling around the pick-up would chatter the contacts apart in a few hundred operations

coilvalue
coil voltage
100%above pick-up
contacts
closed1 operations
weak closes
0none
Pick-up 72% · release 38%
Fill Line/line 6 · 500 g declared
2 in 12 short

503 g

2 packs in every 12 come out under 500 g

The filler's spread is fixed; the setpoint only slides the whole distribution. Two grams up leaves 1 short at 5.3 g a pack, two grams down leaves 4 short at 2.3 g. Nothing on this dial gets both numbers to zero

fillvalue
setpoint
501 g+1 g
underweight
2/120 this run
giveaway
3.7 g/pack13.2 kg/h
Spread ±9/-4 g · 0 weighed