frameyard 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +177 -14
- package/GLOSSARY.md +112 -2
- package/README.md +302 -265
- package/dist/assets/integrations.d.ts +8 -4
- package/dist/assets/integrations.d.ts.map +1 -1
- package/dist/assets/integrations.js +8 -4
- package/dist/assets/integrations.js.map +1 -1
- package/dist/assets/provenance.d.ts +2 -2
- package/dist/assets/provenance.d.ts.map +1 -1
- package/dist/assets/provenance.js +5 -3
- package/dist/assets/provenance.js.map +1 -1
- package/dist/assets/tts-supertonic.d.ts +28 -0
- package/dist/assets/tts-supertonic.d.ts.map +1 -0
- package/dist/assets/tts-supertonic.js +156 -0
- package/dist/assets/tts-supertonic.js.map +1 -0
- package/dist/assets/tts.d.ts +18 -6
- package/dist/assets/tts.d.ts.map +1 -1
- package/dist/assets/tts.js +219 -97
- package/dist/assets/tts.js.map +1 -1
- package/dist/cli.js +1685 -93
- package/dist/cli.js.map +1 -1
- package/dist/composition/format.d.ts +1 -1
- package/dist/composition/format.d.ts.map +1 -1
- package/dist/composition/format.js +1 -1
- package/dist/composition/format.js.map +1 -1
- package/dist/context.d.ts +82 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +277 -0
- package/dist/context.js.map +1 -0
- package/dist/contracts.d.ts +25 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/doctor.d.ts +14 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +166 -7
- package/dist/doctor.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fonts/add.d.ts +41 -0
- package/dist/fonts/add.d.ts.map +1 -0
- package/dist/fonts/add.js +259 -0
- package/dist/fonts/add.js.map +1 -0
- package/dist/fonts/binary.d.ts +4 -0
- package/dist/fonts/binary.d.ts.map +1 -0
- package/dist/fonts/binary.js +21 -0
- package/dist/fonts/binary.js.map +1 -0
- package/dist/fonts/css.d.ts +4 -0
- package/dist/fonts/css.d.ts.map +1 -0
- package/dist/fonts/css.js +50 -0
- package/dist/fonts/css.js.map +1 -0
- package/dist/fonts/fontsource.d.ts +107 -0
- package/dist/fonts/fontsource.d.ts.map +1 -0
- package/dist/fonts/fontsource.js +565 -0
- package/dist/fonts/fontsource.js.map +1 -0
- package/dist/fonts/index.d.ts +11 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +11 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/fonts/install.d.ts +24 -0
- package/dist/fonts/install.d.ts.map +1 -0
- package/dist/fonts/install.js +145 -0
- package/dist/fonts/install.js.map +1 -0
- package/dist/fonts/manifest.d.ts +21 -0
- package/dist/fonts/manifest.d.ts.map +1 -0
- package/dist/fonts/manifest.js +96 -0
- package/dist/fonts/manifest.js.map +1 -0
- package/dist/fonts/options.d.ts +9 -0
- package/dist/fonts/options.d.ts.map +1 -0
- package/dist/fonts/options.js +66 -0
- package/dist/fonts/options.js.map +1 -0
- package/dist/fonts/schema.d.ts +4 -0
- package/dist/fonts/schema.d.ts.map +1 -0
- package/dist/fonts/schema.js +316 -0
- package/dist/fonts/schema.js.map +1 -0
- package/dist/fonts/summary.d.ts +16 -0
- package/dist/fonts/summary.d.ts.map +1 -0
- package/dist/fonts/summary.js +22 -0
- package/dist/fonts/summary.js.map +1 -0
- package/dist/fonts/types.d.ts +56 -0
- package/dist/fonts/types.d.ts.map +1 -0
- package/dist/fonts/types.js +8 -0
- package/dist/fonts/types.js.map +1 -0
- package/dist/fonts/verify.d.ts +33 -0
- package/dist/fonts/verify.d.ts.map +1 -0
- package/dist/fonts/verify.js +200 -0
- package/dist/fonts/verify.js.map +1 -0
- package/dist/html/validate.d.ts.map +1 -1
- package/dist/html/validate.js +59 -0
- package/dist/html/validate.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +61 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +325 -0
- package/dist/inspect.js.map +1 -0
- package/dist/lint.d.ts +63 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +265 -0
- package/dist/lint.js.map +1 -0
- package/dist/policy.d.ts +69 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +361 -0
- package/dist/policy.js.map +1 -0
- package/dist/preview/fonts/LICENSE-figtree.txt +93 -0
- package/dist/preview/fonts/LICENSE-space-mono.txt +93 -0
- package/dist/preview/fonts/README.md +23 -0
- package/dist/preview/fonts/figtree-latin-wght-normal.woff2 +0 -0
- package/dist/preview/fonts/space-mono-latin-400-normal.woff2 +0 -0
- package/dist/preview/fonts/space-mono-latin-700-normal.woff2 +0 -0
- package/dist/preview/main.js +5 -2
- package/dist/preview/main.js.map +1 -1
- package/dist/preview/timeline-data.d.ts +17 -69
- package/dist/preview/timeline-data.d.ts.map +1 -1
- package/dist/preview/timeline-host.d.ts.map +1 -1
- package/dist/preview/timeline-host.js +70 -45
- package/dist/preview/timeline-host.js.map +1 -1
- package/dist/preview/timeline-main.d.ts.map +1 -1
- package/dist/preview/timeline-main.js +88 -27
- package/dist/preview/timeline-main.js.map +1 -1
- package/dist/project.d.ts +10 -3
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +20 -17
- package/dist/project.js.map +1 -1
- package/dist/renderer/audio.d.ts +6 -0
- package/dist/renderer/audio.d.ts.map +1 -1
- package/dist/renderer/audio.js +3 -1
- package/dist/renderer/audio.js.map +1 -1
- package/dist/renderer/browser.d.ts.map +1 -1
- package/dist/renderer/browser.js +13 -0
- package/dist/renderer/browser.js.map +1 -1
- package/dist/renderer/concurrency.d.ts +6 -0
- package/dist/renderer/concurrency.d.ts.map +1 -0
- package/dist/renderer/concurrency.js +27 -0
- package/dist/renderer/concurrency.js.map +1 -0
- package/dist/renderer/ffmpeg.d.ts +104 -5
- package/dist/renderer/ffmpeg.d.ts.map +1 -1
- package/dist/renderer/ffmpeg.js +580 -67
- package/dist/renderer/ffmpeg.js.map +1 -1
- package/dist/renderer/index.js +1 -1
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/keyframe-expressions.d.ts +39 -0
- package/dist/renderer/keyframe-expressions.d.ts.map +1 -0
- package/dist/renderer/keyframe-expressions.js +180 -0
- package/dist/renderer/keyframe-expressions.js.map +1 -0
- package/dist/renderer/session-pool.d.ts +28 -0
- package/dist/renderer/session-pool.d.ts.map +1 -0
- package/dist/renderer/session-pool.js +91 -0
- package/dist/renderer/session-pool.js.map +1 -0
- package/dist/renderer/timeline.d.ts +2 -0
- package/dist/renderer/timeline.d.ts.map +1 -1
- package/dist/renderer/timeline.js +600 -147
- package/dist/renderer/timeline.js.map +1 -1
- package/dist/renderer/timings.d.ts +13 -0
- package/dist/renderer/timings.d.ts.map +1 -0
- package/dist/renderer/timings.js +29 -0
- package/dist/renderer/timings.js.map +1 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/host.js +4 -0
- package/dist/runtime/host.js.map +1 -1
- package/dist/scaffold.d.ts +3 -0
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +48 -320
- package/dist/scaffold.js.map +1 -1
- package/dist/server/composition-html.d.ts +2 -0
- package/dist/server/composition-html.d.ts.map +1 -1
- package/dist/server/composition-html.js +7 -0
- package/dist/server/composition-html.js.map +1 -1
- package/dist/server/preview-html.d.ts.map +1 -1
- package/dist/server/preview-html.js +74 -188
- package/dist/server/preview-html.js.map +1 -1
- package/dist/server/preview-style.d.ts +11 -0
- package/dist/server/preview-style.d.ts.map +1 -0
- package/dist/server/preview-style.js +298 -0
- package/dist/server/preview-style.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +31 -1
- package/dist/server/server.js.map +1 -1
- package/dist/server/timeline-preview-data.d.ts.map +1 -1
- package/dist/server/timeline-preview-data.js +12 -34
- package/dist/server/timeline-preview-data.js.map +1 -1
- package/dist/server/timeline-preview-html.d.ts.map +1 -1
- package/dist/server/timeline-preview-html.js +140 -148
- package/dist/server/timeline-preview-html.js.map +1 -1
- package/dist/templates.d.ts +16 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +186 -0
- package/dist/templates.js.map +1 -0
- package/dist/timeline/easing.d.ts +36 -0
- package/dist/timeline/easing.d.ts.map +1 -0
- package/dist/timeline/easing.js +225 -0
- package/dist/timeline/easing.js.map +1 -0
- package/dist/timeline/keyframes.d.ts +23 -0
- package/dist/timeline/keyframes.d.ts.map +1 -0
- package/dist/timeline/keyframes.js +95 -0
- package/dist/timeline/keyframes.js.map +1 -0
- package/dist/timeline/plan.d.ts +6 -12
- package/dist/timeline/plan.d.ts.map +1 -1
- package/dist/timeline/plan.js +17 -30
- package/dist/timeline/plan.js.map +1 -1
- package/dist/timeline/resolve.d.ts +12 -0
- package/dist/timeline/resolve.d.ts.map +1 -1
- package/dist/timeline/resolve.js +105 -9
- package/dist/timeline/resolve.js.map +1 -1
- package/dist/timeline/scene.d.ts +126 -0
- package/dist/timeline/scene.d.ts.map +1 -0
- package/dist/timeline/scene.js +109 -0
- package/dist/timeline/scene.js.map +1 -0
- package/dist/timeline/schema.d.ts +31 -0
- package/dist/timeline/schema.d.ts.map +1 -1
- package/dist/timeline/schema.js +240 -9
- package/dist/timeline/schema.js.map +1 -1
- package/dist/timeline/transitions.d.ts +21 -0
- package/dist/timeline/transitions.d.ts.map +1 -0
- package/dist/timeline/transitions.js +23 -0
- package/dist/timeline/transitions.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/adr/0007-make-html-documents-the-composition-unit.md +1 -1
- package/docs/adr/0010-make-timelines-the-render-unit.md +3 -2
- package/docs/adr/0012-render-timelines-with-segmented-lossless-clip-intermediates.md +1 -1
- package/docs/adr/0014-compose-timeline-clips-with-css-blend-modes.md +2 -1
- package/docs/adr/0015-inherit-composition-format-from-the-project.md +2 -2
- package/docs/adr/0016-author-compositions-as-html-fragments.md +1 -1
- package/docs/adr/0018-animate-timeline-clips-with-keyframes.md +35 -0
- package/docs/adr/0019-make-same-track-overlap-the-transition-window.md +36 -0
- package/docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md +27 -0
- package/docs/adr/0021-project-timeline-scenes-once.md +32 -0
- package/docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md +35 -0
- package/docs/adr/0023-pin-fonts-as-project-assets.md +98 -0
- package/docs/adr/0024-stream-composition-captures-and-skip-trivial-composites.md +86 -0
- package/docs/adr/0025-capture-timeline-layers-in-parallel-with-a-global-limit.md +67 -0
- package/docs/adr/0026-reuse-loaded-composition-sessions-across-segments.md +70 -0
- package/docs/adr/0027-encode-two-full-frame-layers-through-dual-pipes.md +76 -0
- package/docs/adr/0028-encode-full-frame-video-segments-directly.md +65 -0
- package/docs/migration-0.4.md +2 -2
- package/docs/preview-testing.md +27 -6
- package/docs/{v0.1-design.md → v0.x-design.md} +57 -32
- package/examples/blend/README.md +3 -3
- package/examples/demo/README.md +2 -2
- package/examples/intro/README.md +71 -0
- package/examples/intro/assets/fonts/figtree/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/figtree/figtree-latin-wght-normal.woff2 +0 -0
- package/examples/intro/assets/fonts/instrument-serif/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/instrument-serif/instrument-serif-latin-400-italic.woff2 +0 -0
- package/examples/intro/assets/fonts/space-mono/LICENSE.txt +93 -0
- package/examples/intro/assets/fonts/space-mono/space-mono-latin-400-normal.woff2 +0 -0
- package/examples/intro/assets/fonts/space-mono/space-mono-latin-700-normal.woff2 +0 -0
- package/examples/intro/assets/grain.png +0 -0
- package/examples/intro/assets/score.ogg +0 -0
- package/examples/intro/compositions/brand.html +412 -0
- package/examples/intro/compositions/chrome.controller.js +63 -0
- package/examples/intro/compositions/chrome.html +256 -0
- package/examples/intro/compositions/lattice.controller.js +148 -0
- package/examples/intro/compositions/lattice.html +308 -0
- package/examples/intro/compositions/opening.html +504 -0
- package/examples/intro/compositions/studio.html +930 -0
- package/examples/intro/compositions/theme.css +218 -0
- package/examples/intro/fy.config.js +13 -0
- package/examples/intro/fy.fonts.json +100 -0
- package/examples/intro/scripts/make-grain.mjs +79 -0
- package/examples/intro/scripts/make-score.mjs +702 -0
- package/examples/intro/timelines/intro.timeline.json +60 -0
- package/examples/keyframes/README.md +76 -0
- package/examples/keyframes/compositions/backdrop.html +60 -0
- package/examples/keyframes/compositions/card.html +99 -0
- package/examples/keyframes/fy.config.js +10 -0
- package/examples/keyframes/timelines/keyframes.timeline.json +60 -0
- package/examples/nested/README.md +112 -0
- package/examples/nested/assets/pulse.wav +0 -0
- package/examples/nested/compositions/backdrop.html +84 -0
- package/examples/nested/compositions/card.html +275 -0
- package/examples/nested/compositions/overlay.html +307 -0
- package/examples/nested/fy.config.js +13 -0
- package/examples/nested/scripts/make-pulse.sh +20 -0
- package/examples/nested/timelines/chapter-a.timeline.json +39 -0
- package/examples/nested/timelines/chapter-b.timeline.json +39 -0
- package/examples/nested/timelines/nested-reel.timeline.json +52 -0
- package/examples/static/README.md +2 -2
- package/examples/transitions/README.md +128 -0
- package/examples/transitions/assets/alpha.wav +0 -0
- package/examples/transitions/assets/beta.wav +0 -0
- package/examples/transitions/assets/gamma.wav +0 -0
- package/examples/transitions/compositions/alpha.html +56 -0
- package/examples/transitions/compositions/beta.html +56 -0
- package/examples/transitions/compositions/gamma.html +56 -0
- package/examples/transitions/fy.config.js +12 -0
- package/examples/transitions/timelines/audio-crossfade.timeline.json +44 -0
- package/examples/transitions/timelines/transitions.timeline.json +31 -0
- package/examples/video/README.md +4 -4
- package/examples/webgl/README.md +1 -1
- package/package.json +13 -6
- package/scaffolds/init/AGENTS.md +131 -0
- package/scaffolds/init/README.md +56 -0
- package/scaffolds/init/compositions/hello.html +79 -0
- package/scaffolds/init/fy.config.js +9 -0
- package/scaffolds/init/gitignore.template +1 -0
- package/scaffolds/init/package.json +11 -0
- package/scaffolds/init/props/hello.json +4 -0
- package/scaffolds/init/props/main.json +6 -0
- package/scaffolds/init/timelines/main.timeline.json +20 -0
- package/scaffolds/local-models/LOCAL-MODELS.md +77 -0
- package/scaffolds/local-models/fy.policy.json +5 -0
- package/scaffolds/local-models/opencode/opencode.jsonc +17 -0
- package/scaffolds/local-models/pi/APPEND_SYSTEM.md +21 -0
- package/scaffolds/local-models/pi/sandbox.json +15 -0
- package/scaffolds/local-models/pi/settings.json +15 -0
- package/skills/frameyard/README.md +1 -0
- package/skills/frameyard/SKILL.md +59 -61
- package/skills/frameyard/references/audio-assets.md +32 -3
- package/skills/frameyard/references/common-mistakes.md +53 -2
- package/skills/frameyard/references/deterministic-authoring.md +10 -3
- package/skills/frameyard/references/diagnostics.md +31 -1
- package/skills/frameyard/references/failure-recovery.md +32 -6
- package/skills/frameyard/references/fonts.md +132 -0
- package/skills/frameyard/references/json-results.md +119 -6
- package/skills/frameyard/references/quick-reference.md +222 -0
- package/skills/frameyard/references/timelines.md +97 -7
- /package/examples/blend/{video.config.js → fy.config.js} +0 -0
- /package/examples/demo/{video.config.js → fy.config.js} +0 -0
- /package/examples/static/{video.config.js → fy.config.js} +0 -0
- /package/examples/video/{video.config.js → fy.config.js} +0 -0
- /package/examples/webgl/{video.config.js → fy.config.js} +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const staticPoster = `<script type="application/json" data-fy="props">{
|
|
2
|
+
"title": "A quiet signal",
|
|
3
|
+
"subtitle": "Frameyard static poster",
|
|
4
|
+
"accent": "#ff7a45"
|
|
5
|
+
}</script>
|
|
6
|
+
<style>
|
|
7
|
+
html, body { margin: 0; width: 100%; height: 100%; }
|
|
8
|
+
.poster {
|
|
9
|
+
position: absolute;
|
|
10
|
+
inset: 0;
|
|
11
|
+
display: grid;
|
|
12
|
+
place-items: center;
|
|
13
|
+
background: radial-gradient(circle at 50% 35%, #1d2a44, #080d16 70%);
|
|
14
|
+
color: #f4f7fb;
|
|
15
|
+
font-family: system-ui, sans-serif;
|
|
16
|
+
}
|
|
17
|
+
.card { width: 78%; text-align: center; }
|
|
18
|
+
h1 {
|
|
19
|
+
margin: 0;
|
|
20
|
+
font-size: 8vmin;
|
|
21
|
+
line-height: 1.05;
|
|
22
|
+
color: var(--fy-prop-accent, #ff7a45);
|
|
23
|
+
}
|
|
24
|
+
p {
|
|
25
|
+
margin: 3vmin 0 0;
|
|
26
|
+
font-size: 3vmin;
|
|
27
|
+
letter-spacing: 0.08em;
|
|
28
|
+
text-transform: uppercase;
|
|
29
|
+
color: #9fb0c8;
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
32
|
+
<fy-composition>
|
|
33
|
+
<main class="poster">
|
|
34
|
+
<div class="card">
|
|
35
|
+
<h1 data-fy-text="title"></h1>
|
|
36
|
+
<p data-fy-text="subtitle"></p>
|
|
37
|
+
</div>
|
|
38
|
+
</main>
|
|
39
|
+
</fy-composition>
|
|
40
|
+
`;
|
|
41
|
+
const titleCard = `<script type="application/json" data-fy="props">{
|
|
42
|
+
"title": "Chapter one",
|
|
43
|
+
"subtitle": "A deterministic title card"
|
|
44
|
+
}</script>
|
|
45
|
+
<style>
|
|
46
|
+
html, body { margin: 0; width: 100%; height: 100%; }
|
|
47
|
+
@keyframes rise {
|
|
48
|
+
from { opacity: 0; transform: translateY(4vmin); }
|
|
49
|
+
to { opacity: 1; transform: translateY(0); }
|
|
50
|
+
}
|
|
51
|
+
.stage {
|
|
52
|
+
position: absolute;
|
|
53
|
+
inset: 0;
|
|
54
|
+
display: grid;
|
|
55
|
+
place-items: center;
|
|
56
|
+
background: linear-gradient(135deg, #0c1220, #18243a);
|
|
57
|
+
color: #f4f7fb;
|
|
58
|
+
font-family: system-ui, sans-serif;
|
|
59
|
+
text-align: center;
|
|
60
|
+
}
|
|
61
|
+
h1 { margin: 0; font-size: 9vmin; line-height: 1.05; animation: rise 1s linear both; }
|
|
62
|
+
p { margin: 3vmin 0 0; font-size: 3vmin; color: #8fa4c4; animation: rise 1s linear both; }
|
|
63
|
+
</style>
|
|
64
|
+
<fy-composition duration-in-frames="150">
|
|
65
|
+
<main class="stage">
|
|
66
|
+
<div>
|
|
67
|
+
<h1 data-fy-text="title" data-fy-anim-start="0" data-fy-anim-duration="36"></h1>
|
|
68
|
+
<p data-fy-text="subtitle" data-fy-anim-start="18" data-fy-anim-duration="36"></p>
|
|
69
|
+
</div>
|
|
70
|
+
</main>
|
|
71
|
+
</fy-composition>
|
|
72
|
+
`;
|
|
73
|
+
const lowerThird = `<script type="application/json" data-fy="props">{
|
|
74
|
+
"name": "Ada Lovelace",
|
|
75
|
+
"role": "Computing pioneer",
|
|
76
|
+
"accent": "#ff7a45"
|
|
77
|
+
}</script>
|
|
78
|
+
<style>
|
|
79
|
+
html, body { margin: 0; width: 100%; height: 100%; }
|
|
80
|
+
@keyframes slide {
|
|
81
|
+
from { opacity: 0; transform: translateX(-6vmin); }
|
|
82
|
+
to { opacity: 1; transform: translateX(0); }
|
|
83
|
+
}
|
|
84
|
+
.stage {
|
|
85
|
+
position: absolute;
|
|
86
|
+
inset: 0;
|
|
87
|
+
background: transparent;
|
|
88
|
+
font-family: system-ui, sans-serif;
|
|
89
|
+
}
|
|
90
|
+
.bar {
|
|
91
|
+
position: absolute;
|
|
92
|
+
left: 6vmin;
|
|
93
|
+
bottom: 9vmin;
|
|
94
|
+
padding: 2.4vmin 3.2vmin;
|
|
95
|
+
border-left: 0.8vmin solid var(--fy-prop-accent, #ff7a45);
|
|
96
|
+
background: color-mix(in srgb, #0c1220 88%, transparent);
|
|
97
|
+
color: #f4f7fb;
|
|
98
|
+
animation: slide 1s ease both;
|
|
99
|
+
}
|
|
100
|
+
strong { display: block; font-size: 4.2vmin; line-height: 1.1; }
|
|
101
|
+
span { display: block; margin-top: 0.8vmin; font-size: 2.4vmin; color: #9fb0c8; }
|
|
102
|
+
</style>
|
|
103
|
+
<fy-composition duration-in-frames="120">
|
|
104
|
+
<main class="stage">
|
|
105
|
+
<div class="bar" data-fy-anim-start="0" data-fy-anim-duration="30">
|
|
106
|
+
<strong data-fy-text="name"></strong>
|
|
107
|
+
<span data-fy-text="role"></span>
|
|
108
|
+
</div>
|
|
109
|
+
</main>
|
|
110
|
+
</fy-composition>
|
|
111
|
+
`;
|
|
112
|
+
const slideshowTimeline = `{
|
|
113
|
+
"version": 1,
|
|
114
|
+
"tracks": [
|
|
115
|
+
{ "id": "v1", "kind": "video" }
|
|
116
|
+
],
|
|
117
|
+
"clips": [
|
|
118
|
+
{
|
|
119
|
+
"id": "slide-1",
|
|
120
|
+
"track": "v1",
|
|
121
|
+
"source": { "kind": "image", "src": "assets/slide-1.png" },
|
|
122
|
+
"start": 0,
|
|
123
|
+
"duration": 90
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "slide-2",
|
|
127
|
+
"track": "v1",
|
|
128
|
+
"source": { "kind": "image", "src": "assets/slide-2.png" },
|
|
129
|
+
"start": 90,
|
|
130
|
+
"duration": 90
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "slide-3",
|
|
134
|
+
"track": "v1",
|
|
135
|
+
"source": { "kind": "image", "src": "assets/slide-3.png" },
|
|
136
|
+
"start": 180,
|
|
137
|
+
"duration": 90
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
"transitions": []
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
export const TEMPLATES = [
|
|
144
|
+
{
|
|
145
|
+
name: "static-poster",
|
|
146
|
+
kind: "composition",
|
|
147
|
+
description: "A timeless poster with title, subtitle, and accent props; renders to PNG.",
|
|
148
|
+
entry: (id) => `compositions/${id}.html`,
|
|
149
|
+
content: staticPoster,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "title-card",
|
|
153
|
+
kind: "composition",
|
|
154
|
+
description: "A 150-frame title card with staggered CSS entrance animations.",
|
|
155
|
+
entry: (id) => `compositions/${id}.html`,
|
|
156
|
+
content: titleCard,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "lower-third",
|
|
160
|
+
kind: "composition",
|
|
161
|
+
description: "A 120-frame lower third for a name and role.",
|
|
162
|
+
entry: (id) => `compositions/${id}.html`,
|
|
163
|
+
content: lowerThird,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "slideshow",
|
|
167
|
+
kind: "timeline",
|
|
168
|
+
description: "A three-slide image timeline with 90-frame clips.",
|
|
169
|
+
entry: (id) => `timelines/${id}.timeline.json`,
|
|
170
|
+
content: slideshowTimeline,
|
|
171
|
+
prerequisites: ["assets/slide-1.png", "assets/slide-2.png", "assets/slide-3.png"],
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
export function findTemplate(name) {
|
|
175
|
+
return TEMPLATES.find((template) => template.name === name);
|
|
176
|
+
}
|
|
177
|
+
export function listTemplates(kind) {
|
|
178
|
+
return TEMPLATES.filter((template) => kind === undefined || template.kind === kind);
|
|
179
|
+
}
|
|
180
|
+
export function templateRegistration(template, id) {
|
|
181
|
+
const entry = template.entry(id);
|
|
182
|
+
return template.kind === "composition"
|
|
183
|
+
? { compositions: { [id]: `./${entry}` }, timelines: undefined }
|
|
184
|
+
: { compositions: undefined, timelines: { [id]: `./${entry}` } };
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAaA,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCpB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsClB,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BzB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAA+B;IACnD;QACE,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,2EAA2E;QACxF,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO;QACxC,OAAO,EAAE,YAAY;KACtB;IACD;QACE,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,gEAAgE;QAC7E,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO;QACxC,OAAO,EAAE,SAAS;KACnB;IACD;QACE,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,8CAA8C;QAC3D,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO;QACxC,OAAO,EAAE,UAAU;KACpB;IACD;QACE,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,mDAAmD;QAChE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,gBAAgB;QAC9C,OAAO,EAAE,iBAAiB;QAC1B,aAAa,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,oBAAoB,CAAC;KAClF;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,QAAyB,EACzB,EAAU;IAEV,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC,IAAI,KAAK,aAAa;QACpC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;QAChE,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe CSS timing-function parsing and evaluation for timeline
|
|
3
|
+
* keyframes. This is the single source of truth shared by the preview, the
|
|
4
|
+
* static checker, and the FFmpeg expression builder.
|
|
5
|
+
*/
|
|
6
|
+
export interface CubicBezierEasing {
|
|
7
|
+
kind: "cubic-bezier";
|
|
8
|
+
x1: number;
|
|
9
|
+
y1: number;
|
|
10
|
+
x2: number;
|
|
11
|
+
y2: number;
|
|
12
|
+
}
|
|
13
|
+
export type StepPosition = "jump-start" | "jump-end" | "jump-none" | "jump-both";
|
|
14
|
+
export interface StepsEasing {
|
|
15
|
+
kind: "steps";
|
|
16
|
+
steps: number;
|
|
17
|
+
position: StepPosition;
|
|
18
|
+
}
|
|
19
|
+
export interface LinearEasing {
|
|
20
|
+
kind: "linear";
|
|
21
|
+
}
|
|
22
|
+
export type Easing = LinearEasing | CubicBezierEasing | StepsEasing;
|
|
23
|
+
export declare const LINEAR_EASING: LinearEasing;
|
|
24
|
+
/** Human-readable grammar used in diagnostics and documentation. */
|
|
25
|
+
export declare const EASING_GRAMMAR = "linear, ease, ease-in, ease-out, ease-in-out, step-start, step-end, hold, cubic-bezier(x1, y1, x2, y2), or steps(n, jump-start|jump-end|jump-none|jump-both)";
|
|
26
|
+
/** Parses a CSS timing function from the supported keyframe vocabulary. */
|
|
27
|
+
export declare function parseEasing(value: string): Easing | null;
|
|
28
|
+
/** Solves x(u) = progress for a CSS cubic-bezier and returns y(u). */
|
|
29
|
+
export declare function cubicBezierProgress(easing: CubicBezierEasing, progress: number): number;
|
|
30
|
+
/** dy/dx of a CSS cubic-bezier at x = progress, used by the Hermite approximation. */
|
|
31
|
+
export declare function cubicBezierSlope(easing: CubicBezierEasing, progress: number): number;
|
|
32
|
+
/** Evaluates a parsed easing at a normalized progress in `0..1`. */
|
|
33
|
+
export declare function easeProgress(easing: Easing, progress: number): number;
|
|
34
|
+
/** Caches parsing by the raw string; timelines often repeat the same easing. */
|
|
35
|
+
export declare function easingFor(value: string | undefined): Easing;
|
|
36
|
+
//# sourceMappingURL=easing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing.d.ts","sourceRoot":"","sources":["../../src/timeline/easing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;AAEjF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAEpE,eAAO,MAAM,aAAa,EAAE,YAAiC,CAAC;AAE9D,oEAAoE;AACpE,eAAO,MAAM,cAAc,iKACqI,CAAC;AAwEjK,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6BxD;AAYD,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoCvF;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA8BpF;AAoBD,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUrE;AAID,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAW3D"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe CSS timing-function parsing and evaluation for timeline
|
|
3
|
+
* keyframes. This is the single source of truth shared by the preview, the
|
|
4
|
+
* static checker, and the FFmpeg expression builder.
|
|
5
|
+
*/
|
|
6
|
+
export const LINEAR_EASING = { kind: "linear" };
|
|
7
|
+
/** Human-readable grammar used in diagnostics and documentation. */
|
|
8
|
+
export const EASING_GRAMMAR = "linear, ease, ease-in, ease-out, ease-in-out, step-start, step-end, hold, cubic-bezier(x1, y1, x2, y2), or steps(n, jump-start|jump-end|jump-none|jump-both)";
|
|
9
|
+
const NAMED_EASINGS = {
|
|
10
|
+
ease: [0.25, 0.1, 0.25, 1],
|
|
11
|
+
"ease-in": [0.42, 0, 1, 1],
|
|
12
|
+
"ease-out": [0, 0, 0.58, 1],
|
|
13
|
+
"ease-in-out": [0.42, 0, 0.58, 1],
|
|
14
|
+
};
|
|
15
|
+
function parseNumber(value) {
|
|
16
|
+
const trimmed = value.trim();
|
|
17
|
+
if (trimmed.length === 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const number = Number(trimmed);
|
|
21
|
+
return Number.isFinite(number) ? number : null;
|
|
22
|
+
}
|
|
23
|
+
function parseSteps(value) {
|
|
24
|
+
const match = /^steps\(([^)]*)\)$/i.exec(value);
|
|
25
|
+
if (!match) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const parts = match[1].split(",").map((part) => part.trim());
|
|
29
|
+
if (parts.length < 1 || parts.length > 2) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const count = parseNumber(parts[0]);
|
|
33
|
+
if (count === null || !Number.isInteger(count) || count <= 0) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const positionValue = (parts[1] ?? "jump-end").toLowerCase();
|
|
37
|
+
const position = positionValue === "start"
|
|
38
|
+
? "jump-start"
|
|
39
|
+
: positionValue === "end"
|
|
40
|
+
? "jump-end"
|
|
41
|
+
: positionValue === "jump-start" ||
|
|
42
|
+
positionValue === "jump-end" ||
|
|
43
|
+
positionValue === "jump-none" ||
|
|
44
|
+
positionValue === "jump-both"
|
|
45
|
+
? positionValue
|
|
46
|
+
: null;
|
|
47
|
+
if (position === null) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (position === "jump-none" && count < 2) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return { kind: "steps", steps: count, position };
|
|
54
|
+
}
|
|
55
|
+
function parseCubicBezier(value) {
|
|
56
|
+
const match = /^cubic-bezier\(([^)]*)\)$/i.exec(value);
|
|
57
|
+
if (!match) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const parts = match[1].split(",").map((part) => part.trim());
|
|
61
|
+
if (parts.length !== 4) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const numbers = parts.map(parseNumber);
|
|
65
|
+
if (numbers.some((number) => number === null)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const [x1, y1, x2, y2] = numbers;
|
|
69
|
+
if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return { kind: "cubic-bezier", x1, y1, x2, y2 };
|
|
73
|
+
}
|
|
74
|
+
/** Parses a CSS timing function from the supported keyframe vocabulary. */
|
|
75
|
+
export function parseEasing(value) {
|
|
76
|
+
if (typeof value !== "string") {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const trimmed = value.trim();
|
|
80
|
+
if (trimmed.length === 0) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const lower = trimmed.toLowerCase();
|
|
84
|
+
if (lower === "linear") {
|
|
85
|
+
return LINEAR_EASING;
|
|
86
|
+
}
|
|
87
|
+
if (lower === "hold" || lower === "step-end") {
|
|
88
|
+
return { kind: "steps", steps: 1, position: "jump-end" };
|
|
89
|
+
}
|
|
90
|
+
if (lower === "step-start") {
|
|
91
|
+
return { kind: "steps", steps: 1, position: "jump-start" };
|
|
92
|
+
}
|
|
93
|
+
const named = NAMED_EASINGS[lower];
|
|
94
|
+
if (named) {
|
|
95
|
+
return { kind: "cubic-bezier", x1: named[0], y1: named[1], x2: named[2], y2: named[3] };
|
|
96
|
+
}
|
|
97
|
+
if (lower.startsWith("cubic-bezier(")) {
|
|
98
|
+
return parseCubicBezier(trimmed);
|
|
99
|
+
}
|
|
100
|
+
if (lower.startsWith("steps(")) {
|
|
101
|
+
return parseSteps(trimmed);
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
function cubicCoordinate(u, first, second) {
|
|
106
|
+
const inverse = 1 - u;
|
|
107
|
+
return 3 * inverse * inverse * u * first + 3 * inverse * u * u * second + u * u * u;
|
|
108
|
+
}
|
|
109
|
+
function cubicDerivative(u, first, second) {
|
|
110
|
+
const inverse = 1 - u;
|
|
111
|
+
return 3 * inverse * inverse * first + 6 * inverse * u * (second - first) + 3 * u * u * (1 - second);
|
|
112
|
+
}
|
|
113
|
+
/** Solves x(u) = progress for a CSS cubic-bezier and returns y(u). */
|
|
114
|
+
export function cubicBezierProgress(easing, progress) {
|
|
115
|
+
const target = Math.max(0, Math.min(1, progress));
|
|
116
|
+
if (target === 0 || target === 1) {
|
|
117
|
+
return target;
|
|
118
|
+
}
|
|
119
|
+
let u = target;
|
|
120
|
+
for (let iteration = 0; iteration < 8; iteration += 1) {
|
|
121
|
+
const x = cubicCoordinate(u, easing.x1, easing.x2);
|
|
122
|
+
const difference = x - target;
|
|
123
|
+
if (Math.abs(difference) < 1e-9) {
|
|
124
|
+
return cubicCoordinate(u, easing.y1, easing.y2);
|
|
125
|
+
}
|
|
126
|
+
const derivative = cubicDerivative(u, easing.x1, easing.x2);
|
|
127
|
+
if (Math.abs(derivative) < 1e-9) {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
const next = u - difference / derivative;
|
|
131
|
+
if (!Number.isFinite(next) || next < 0 || next > 1) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
u = next;
|
|
135
|
+
}
|
|
136
|
+
let low = 0;
|
|
137
|
+
let high = 1;
|
|
138
|
+
for (let iteration = 0; iteration < 48; iteration += 1) {
|
|
139
|
+
u = (low + high) / 2;
|
|
140
|
+
const x = cubicCoordinate(u, easing.x1, easing.x2);
|
|
141
|
+
if (x < target) {
|
|
142
|
+
low = u;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
high = u;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return cubicCoordinate((low + high) / 2, easing.y1, easing.y2);
|
|
149
|
+
}
|
|
150
|
+
/** dy/dx of a CSS cubic-bezier at x = progress, used by the Hermite approximation. */
|
|
151
|
+
export function cubicBezierSlope(easing, progress) {
|
|
152
|
+
const target = Math.max(0, Math.min(1, progress));
|
|
153
|
+
let u = target;
|
|
154
|
+
if (target > 0 && target < 1) {
|
|
155
|
+
for (let iteration = 0; iteration < 8; iteration += 1) {
|
|
156
|
+
const x = cubicCoordinate(u, easing.x1, easing.x2);
|
|
157
|
+
const derivative = cubicDerivative(u, easing.x1, easing.x2);
|
|
158
|
+
if (Math.abs(derivative) < 1e-9) {
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
const next = u - (x - target) / derivative;
|
|
162
|
+
if (!Number.isFinite(next) || next < 0 || next > 1) {
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
u = next;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const dx = cubicDerivative(u, easing.x1, easing.x2);
|
|
169
|
+
const dy = cubicDerivative(u, easing.y1, easing.y2);
|
|
170
|
+
if (Math.abs(dx) > 1e-7) {
|
|
171
|
+
return dy / dx;
|
|
172
|
+
}
|
|
173
|
+
// Endpoint limits for curves with a vertical or degenerate tangent. Sample a
|
|
174
|
+
// tiny step on either side and use the secant slope.
|
|
175
|
+
const delta = 1e-5;
|
|
176
|
+
const low = Math.max(0, target - delta);
|
|
177
|
+
const high = Math.min(1, target + delta);
|
|
178
|
+
const lowY = cubicBezierProgress(easing, low);
|
|
179
|
+
const highY = cubicBezierProgress(easing, high);
|
|
180
|
+
return high === low ? 0 : (highY - lowY) / (high - low);
|
|
181
|
+
}
|
|
182
|
+
function stepsProgress(easing, progress) {
|
|
183
|
+
const p = Math.max(0, Math.min(1, progress));
|
|
184
|
+
if (p >= 1) {
|
|
185
|
+
return 1;
|
|
186
|
+
}
|
|
187
|
+
const n = easing.steps;
|
|
188
|
+
switch (easing.position) {
|
|
189
|
+
case "jump-start":
|
|
190
|
+
return Math.floor(p * n + 1) / n;
|
|
191
|
+
case "jump-end":
|
|
192
|
+
return Math.floor(p * n) / n;
|
|
193
|
+
case "jump-none":
|
|
194
|
+
return Math.floor(p * n) / (n - 1);
|
|
195
|
+
case "jump-both":
|
|
196
|
+
return (Math.floor(p * n) + 1) / (n + 1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** Evaluates a parsed easing at a normalized progress in `0..1`. */
|
|
200
|
+
export function easeProgress(easing, progress) {
|
|
201
|
+
const p = Math.max(0, Math.min(1, progress));
|
|
202
|
+
switch (easing.kind) {
|
|
203
|
+
case "linear":
|
|
204
|
+
return p;
|
|
205
|
+
case "steps":
|
|
206
|
+
return stepsProgress(easing, p);
|
|
207
|
+
case "cubic-bezier":
|
|
208
|
+
return cubicBezierProgress(easing, p);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const easingCache = new Map();
|
|
212
|
+
/** Caches parsing by the raw string; timelines often repeat the same easing. */
|
|
213
|
+
export function easingFor(value) {
|
|
214
|
+
if (value === undefined) {
|
|
215
|
+
return LINEAR_EASING;
|
|
216
|
+
}
|
|
217
|
+
const cached = easingCache.get(value);
|
|
218
|
+
if (cached !== undefined) {
|
|
219
|
+
return cached ?? LINEAR_EASING;
|
|
220
|
+
}
|
|
221
|
+
const parsed = parseEasing(value);
|
|
222
|
+
easingCache.set(value, parsed);
|
|
223
|
+
return parsed ?? LINEAR_EASING;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=easing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing.js","sourceRoot":"","sources":["../../src/timeline/easing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type TimelineKeyframe, type TimelineKeyframeChannel, type TimelineKeyframes, type TimelineTransform } from "./schema.js";
|
|
2
|
+
export type KeyframeChannel = TimelineKeyframeChannel;
|
|
3
|
+
export interface PresentationValues {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
scale: number;
|
|
7
|
+
rotation: number;
|
|
8
|
+
opacity: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Evaluates one channel at a clip-local frame. Keys are sorted and validated by
|
|
12
|
+
* the schema/resolver. Values before the first key and after the last key hold.
|
|
13
|
+
*/
|
|
14
|
+
export declare function evaluateKeyframeTrack(keys: readonly TimelineKeyframe[], frame: number): number;
|
|
15
|
+
/** Resolves every presentation channel for a clip-local frame. */
|
|
16
|
+
export declare function evaluatePresentation(transform: TimelineTransform, keyframes: TimelineKeyframes | undefined, localFrame: number): PresentationValues;
|
|
17
|
+
export declare function keyframeMarkerFrames(keyframes: TimelineKeyframes | undefined): number[];
|
|
18
|
+
export declare function keyframeChannelsAt(keyframes: TimelineKeyframes | undefined, frame: number): Array<{
|
|
19
|
+
channel: KeyframeChannel;
|
|
20
|
+
value: number;
|
|
21
|
+
easing?: string;
|
|
22
|
+
}>;
|
|
23
|
+
//# sourceMappingURL=keyframes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyframes.d.ts","sourceRoot":"","sources":["../../src/timeline/keyframes.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAsB9F;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,iBAAiB,GAAG,SAAS,EACxC,UAAU,EAAE,MAAM,GACjB,kBAAkB,CAqBpB;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,EAAE,CAWvF;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,iBAAiB,GAAG,SAAS,EACxC,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBrE"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { easeProgress, easingFor } from "./easing.js";
|
|
2
|
+
import { KEYFRAME_CHANNELS, } from "./schema.js";
|
|
3
|
+
function intervalIndex(keys, frame) {
|
|
4
|
+
let low = 0;
|
|
5
|
+
let high = keys.length - 1;
|
|
6
|
+
while (low < high) {
|
|
7
|
+
const middle = Math.ceil((low + high) / 2);
|
|
8
|
+
if (keys[middle].frame <= frame) {
|
|
9
|
+
low = middle;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
high = middle - 1;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return low;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Evaluates one channel at a clip-local frame. Keys are sorted and validated by
|
|
19
|
+
* the schema/resolver. Values before the first key and after the last key hold.
|
|
20
|
+
*/
|
|
21
|
+
export function evaluateKeyframeTrack(keys, frame) {
|
|
22
|
+
if (keys.length === 0) {
|
|
23
|
+
throw new Error("Cannot evaluate an empty keyframe track.");
|
|
24
|
+
}
|
|
25
|
+
const first = keys[0];
|
|
26
|
+
if (frame <= first.frame) {
|
|
27
|
+
return first.value;
|
|
28
|
+
}
|
|
29
|
+
const last = keys[keys.length - 1];
|
|
30
|
+
if (frame >= last.frame) {
|
|
31
|
+
return last.value;
|
|
32
|
+
}
|
|
33
|
+
const index = intervalIndex(keys, frame);
|
|
34
|
+
const from = keys[index];
|
|
35
|
+
const to = keys[index + 1];
|
|
36
|
+
if (frame === from.frame) {
|
|
37
|
+
return from.value;
|
|
38
|
+
}
|
|
39
|
+
const progress = (frame - from.frame) / (to.frame - from.frame);
|
|
40
|
+
const eased = easeProgress(easingFor(from.easing), progress);
|
|
41
|
+
return from.value + (to.value - from.value) * eased;
|
|
42
|
+
}
|
|
43
|
+
/** Resolves every presentation channel for a clip-local frame. */
|
|
44
|
+
export function evaluatePresentation(transform, keyframes, localFrame) {
|
|
45
|
+
const values = {
|
|
46
|
+
x: transform.x,
|
|
47
|
+
y: transform.y,
|
|
48
|
+
scale: transform.scale,
|
|
49
|
+
rotation: transform.rotation,
|
|
50
|
+
opacity: transform.opacity,
|
|
51
|
+
};
|
|
52
|
+
if (keyframes) {
|
|
53
|
+
for (const channel of KEYFRAME_CHANNELS) {
|
|
54
|
+
const track = keyframes[channel];
|
|
55
|
+
if (track !== undefined) {
|
|
56
|
+
values[channel] = evaluateKeyframeTrack(track, localFrame);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Easing may overshoot. Alpha is clamped by CSS, and a negative scale would
|
|
61
|
+
// mirror a layer that the static schema forbids from being negative.
|
|
62
|
+
values.scale = Math.max(0, values.scale);
|
|
63
|
+
values.opacity = Math.min(1, Math.max(0, values.opacity));
|
|
64
|
+
return values;
|
|
65
|
+
}
|
|
66
|
+
export function keyframeMarkerFrames(keyframes) {
|
|
67
|
+
if (!keyframes) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const frames = new Set();
|
|
71
|
+
for (const channel of KEYFRAME_CHANNELS) {
|
|
72
|
+
for (const key of keyframes[channel] ?? []) {
|
|
73
|
+
frames.add(key.frame);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return [...frames].sort((left, right) => left - right);
|
|
77
|
+
}
|
|
78
|
+
export function keyframeChannelsAt(keyframes, frame) {
|
|
79
|
+
if (!keyframes) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const channels = [];
|
|
83
|
+
for (const channel of KEYFRAME_CHANNELS) {
|
|
84
|
+
const key = keyframes[channel]?.find((entry) => entry.frame === frame);
|
|
85
|
+
if (key) {
|
|
86
|
+
channels.push({
|
|
87
|
+
channel,
|
|
88
|
+
value: key.value,
|
|
89
|
+
...(key.easing !== undefined ? { easing: key.easing } : {}),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return channels;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=keyframes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyframes.js","sourceRoot":"","sources":["../../src/timeline/keyframes.ts"],"names":[],"mappings":"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"}
|
package/dist/timeline/plan.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type { ResolvedTimeline,
|
|
2
|
-
|
|
3
|
-
clip: ResolvedTimelineClip;
|
|
4
|
-
/** Source frame used at the segment's first timeline frame. */
|
|
5
|
-
sourceStart: number;
|
|
6
|
-
}
|
|
1
|
+
import type { ResolvedTimeline, ResolvedTimelineSource } from "./resolve.js";
|
|
2
|
+
import { type TimelineSceneLayer } from "./scene.js";
|
|
7
3
|
export interface TimelineRenderSegment {
|
|
8
4
|
index: number;
|
|
9
5
|
/** Inclusive first timeline frame. */
|
|
@@ -12,17 +8,15 @@ export interface TimelineRenderSegment {
|
|
|
12
8
|
end: number;
|
|
13
9
|
frames: number;
|
|
14
10
|
/** Visual layers from bottom to top. */
|
|
15
|
-
layers:
|
|
11
|
+
layers: TimelineSceneLayer<ResolvedTimelineSource>[];
|
|
16
12
|
}
|
|
17
13
|
export interface TimelineRenderPlan {
|
|
18
|
-
timeline: ResolvedTimeline;
|
|
19
|
-
maxSegmentFrames: number;
|
|
20
14
|
segments: TimelineRenderSegment[];
|
|
21
15
|
}
|
|
22
16
|
/**
|
|
23
|
-
* Splits a resolved timeline
|
|
24
|
-
*
|
|
25
|
-
* globally and never appears here.
|
|
17
|
+
* Splits a resolved timeline into independently renderable segments. Segment
|
|
18
|
+
* boundaries fall on visual clip starts and ends, so every segment has a fixed
|
|
19
|
+
* scene projection; audio is mixed globally and never appears here.
|
|
26
20
|
*/
|
|
27
21
|
export declare function planTimelineRender(timeline: ResolvedTimeline, options?: {
|
|
28
22
|
maxSegmentFrames?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/timeline/plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/timeline/plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,kBAAkB,CAqDpB"}
|