Commit 8a467b8
committed
fix(animation): make the animation knobs actually reach the solver (#158)
Eight confirmed audit findings. Six of them are dead knobs: a field the
author sets, the schema accepts, `validate` calls clean, and the engine
ignores. Nobody gets an error; the video simply lacks the animation that was
asked for. For a tool driven by generated JSON that is the worst failure
mode there is, because the correction loop never closes.
- `float_3d`'s `amplitude` never reached `PresetConfig`: `AnimationTiming`
had no such field and the only converter wrote `None`. Every `float_3d`
moved by the 12px default, so the documented parallax recipe produced no
parallax. Measured: 60 requested, -12 delivered.
- `pulse` / `float` / `shake` / `spin` built keyframes at the literal times
0.0 / 0.25 / 0.5 / 1.0 and never read `delay` or `duration`. With
`delay: 1.0`, all four were already mid-animation at t=0.5s.
- `"loop": true` was inert on keyframe effects and `tilt_in`: the resolver
was handed `None` for the preset config, fell back to `repeat: false`,
and never called `loop_time`.
- `--strict-anim` resolved effects at global scene time while the engine
resolves at remapped local time, so it flagged violations at instants
that are never rendered — and missed real ones. It now reads the
`time_params` the builder already computes.
- The completion budget added `start_at` to `delay + duration`, which the
engine does not do: since PR #27 `start_at` gates visibility only and
`delay` is absolute scene time. A 1s animation at `start_at: 1.5` in a 2s
scene was reported as overrunning.
- Two keyframe animations on the same property summed or overwrote each
other depending on whether one carried a `delay` — a field with nothing
to do with composition, routing effects into two separately-resolved
buckets. Now a single bucket with one rule: last declared wins, the CSS
cascade rule, which was already the behaviour within a bucket.
- The spring solver returned NaN for `mass: 0` or `stiffness: 0` and
diverged on negative damping, with no validation anywhere. A NaN reaching
layout contaminates the whole tree. Both ends are handled: the solver
floors its inputs, and `validate` now rejects the configs outright.
- Unknown keys inside `style.animation[*]` were never reported.
That last one has a deliberate consequence worth stating: `deny_unknown_fields`
on the nine effect-config structs means a typo now fails deserialization, and
`deserialize_children` skips a child it cannot parse. A misspelled key stops
producing a default-valued animation and starts removing the component, with
a stderr warning. That is the same contract `CssStyle` has carried all along
— it is why `margin-top` drops a component — so this extends an existing
policy rather than inventing one, and `validate` catches it first.
Tests: full workspace green on this branch alone.1 parent b24878a commit 8a467b8
5 files changed
Lines changed: 864 additions & 72 deletions
File tree
- crates
- rustmotion-cli/src/commands
- rustmotion-core/src
- engine
- schema
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1182 | 1182 | | |
1183 | 1183 | | |
1184 | 1184 | | |
| 1185 | + | |
1185 | 1186 | | |
1186 | 1187 | | |
1187 | 1188 | | |
| |||
1206 | 1207 | | |
1207 | 1208 | | |
1208 | 1209 | | |
| 1210 | + | |
1209 | 1211 | | |
1210 | 1212 | | |
1211 | 1213 | | |
| |||
1257 | 1259 | | |
1258 | 1260 | | |
1259 | 1261 | | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
1260 | 1280 | | |
1261 | | - | |
| 1281 | + | |
1262 | 1282 | | |
1263 | 1283 | | |
1264 | 1284 | | |
| |||
1307 | 1327 | | |
1308 | 1328 | | |
1309 | 1329 | | |
| 1330 | + | |
1310 | 1331 | | |
1311 | 1332 | | |
1312 | 1333 | | |
| |||
1899 | 1920 | | |
1900 | 1921 | | |
1901 | 1922 | | |
| 1923 | + | |
| 1924 | + | |
| 1925 | + | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
| 1944 | + | |
| 1945 | + | |
| 1946 | + | |
| 1947 | + | |
| 1948 | + | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
| 1952 | + | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
| 1963 | + | |
| 1964 | + | |
| 1965 | + | |
| 1966 | + | |
| 1967 | + | |
| 1968 | + | |
| 1969 | + | |
| 1970 | + | |
| 1971 | + | |
| 1972 | + | |
| 1973 | + | |
| 1974 | + | |
| 1975 | + | |
| 1976 | + | |
| 1977 | + | |
1902 | 1978 | | |
1903 | 1979 | | |
1904 | 1980 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
351 | 351 | | |
352 | 352 | | |
353 | 353 | | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
354 | 415 | | |
0 commit comments