givemotion 0.0.0-stage → 0.1.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/AGENTS.md +37 -0
- package/LICENSE +21 -0
- package/README.md +492 -2
- package/SECURITY.md +40 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/blocks/bar-chart.html +63 -0
- package/blocks/browser-window.html +52 -0
- package/blocks/callout.html +57 -0
- package/blocks/captions.html +120 -0
- package/blocks/checklist.html +32 -0
- package/blocks/code-window.html +126 -0
- package/blocks/compare.html +33 -0
- package/blocks/cursor.html +157 -0
- package/blocks/end-card.html +28 -0
- package/blocks/gradient-bg.html +48 -0
- package/blocks/grid-bg.html +18 -0
- package/blocks/highlight.html +13 -0
- package/blocks/line-chart.html +36 -0
- package/blocks/logo-reveal.html +33 -0
- package/blocks/lottie.html +34 -0
- package/blocks/lower-third.html +24 -0
- package/blocks/phone.html +18 -0
- package/blocks/quote.html +19 -0
- package/blocks/stat.html +24 -0
- package/blocks/steps.html +40 -0
- package/blocks/title-card.html +22 -0
- package/blocks/word-pop.html +40 -0
- package/examples/bench/index.html +24 -0
- package/examples/data-story/data.json +9 -0
- package/examples/data-story/index.html +361 -0
- package/examples/data-story/other.json +46 -0
- package/examples/generative/index.html +60 -0
- package/examples/made-by-agents/README.md +5 -0
- package/examples/made-by-agents/photosynthesis/blocks/checklist.html +32 -0
- package/examples/made-by-agents/photosynthesis/blocks/end-card.html +25 -0
- package/examples/made-by-agents/photosynthesis/blocks/gradient-bg.html +48 -0
- package/examples/made-by-agents/photosynthesis/blocks/steps.html +40 -0
- package/examples/made-by-agents/photosynthesis/blocks/title-card.html +22 -0
- package/examples/made-by-agents/photosynthesis/index.html +217 -0
- package/examples/personalized/index.html +28 -0
- package/llms.txt +34 -0
- package/package.json +80 -4
- package/skills/givemotion/SKILL.md +152 -0
- package/skills/givemotion/references/api.md +40 -0
- package/skills/givemotion/references/camera.md +72 -0
- package/skills/givemotion/references/charts.md +138 -0
- package/skills/givemotion/references/check-codes.md +94 -0
- package/skills/givemotion/references/data-templates.md +61 -0
- package/skills/givemotion/references/diagrams.md +75 -0
- package/skills/givemotion/references/genres/code-explainer.md +15 -0
- package/skills/givemotion/references/genres/data-story.md +21 -0
- package/skills/givemotion/references/genres/explainer.md +20 -0
- package/skills/givemotion/references/genres/hand-drawn.md +18 -0
- package/skills/givemotion/references/genres/logo-sting.md +20 -0
- package/skills/givemotion/references/genres/promo.md +18 -0
- package/skills/givemotion/references/genres/ui-demo.md +21 -0
- package/skills/givemotion/references/genres/vertical.md +19 -0
- package/skills/givemotion/references/genres/year-recap.md +18 -0
- package/skills/givemotion/references/javascript.md +72 -0
- package/skills/givemotion/references/media-audio.md +57 -0
- package/skills/givemotion/references/motion-design.md +183 -0
- package/skills/givemotion/references/output.md +64 -0
- package/skills/givemotion/references/review.md +60 -0
- package/skills/givemotion/references/styles.md +133 -0
- package/skills/givemotion/references/techniques/backgrounds-and-ambient.md +85 -0
- package/skills/givemotion/references/techniques/camera-moves.md +88 -0
- package/skills/givemotion/references/techniques/captions-vertical.md +89 -0
- package/skills/givemotion/references/techniques/code-on-screen.md +125 -0
- package/skills/givemotion/references/techniques/hand-drawn.md +87 -0
- package/skills/givemotion/references/techniques/impacts-and-energy.md +106 -0
- package/skills/givemotion/references/techniques/kinetic-type.md +92 -0
- package/skills/givemotion/references/techniques/light-and-depth.md +91 -0
- package/skills/givemotion/references/techniques/logo-reveal.md +94 -0
- package/skills/givemotion/references/techniques/numbers-and-charts.md +92 -0
- package/skills/givemotion/references/techniques/paths-and-maps.md +99 -0
- package/skills/givemotion/references/techniques/scene-transitions.md +85 -0
- package/skills/givemotion/references/techniques/shapes-and-motion-graphics.md +92 -0
- package/skills/givemotion/references/techniques/text-reveals.md +94 -0
- package/skills/givemotion/references/techniques/ui-demo.md +110 -0
- package/skills/givemotion/references/timeline.md +85 -0
- package/src/analyze.js +1485 -0
- package/src/api.js +36 -0
- package/src/args.js +33 -0
- package/src/audio-cli.js +58 -0
- package/src/bench.js +153 -0
- package/src/browser.js +381 -0
- package/src/bundle.js +79 -0
- package/src/cdp.js +94 -0
- package/src/check.js +1818 -0
- package/src/cli.js +611 -0
- package/src/dev.js +26 -0
- package/src/ffmpeg.js +330 -0
- package/src/parts.js +380 -0
- package/src/player/gm-player.js +175 -0
- package/src/render.js +772 -0
- package/src/runtime/audio.js +306 -0
- package/src/runtime/chart.js +665 -0
- package/src/runtime/fonts/BebasNeue-OFL.txt +93 -0
- package/src/runtime/fonts/Caveat-OFL.txt +93 -0
- package/src/runtime/fonts/Inter-OFL.txt +93 -0
- package/src/runtime/fonts/JetBrainsMono-OFL.txt +93 -0
- package/src/runtime/fonts/Nunito-OFL.txt +93 -0
- package/src/runtime/fonts/PlayfairDisplay-OFL.txt +93 -0
- package/src/runtime/fonts/SpaceGrotesk-OFL.txt +93 -0
- package/src/runtime/fonts/bebas-neue-latin-400-normal.woff2 +0 -0
- package/src/runtime/fonts/bebas-neue-latin-ext-400-normal.woff2 +0 -0
- package/src/runtime/fonts/caveat-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/caveat-latin-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/inter-latin-ext-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/inter-latin-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/jetbrains-mono-latin-ext-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/jetbrains-mono-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/jetbrains-mono-latin-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/nunito-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/nunito-latin-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/playfair-display-latin-ext-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/playfair-display-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/playfair-display-latin-wght-italic.woff2 +0 -0
- package/src/runtime/fonts/playfair-display-latin-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/space-grotesk-latin-ext-wght-normal.woff2 +0 -0
- package/src/runtime/fonts/space-grotesk-latin-wght-normal.woff2 +0 -0
- package/src/runtime/motion.js +2674 -0
- package/src/runtime/preset.css +97 -0
- package/src/runtime/runtime.js +2141 -0
- package/src/runtime/sketch.js +1249 -0
- package/src/server.js +402 -0
- package/src/studio/index.html +238 -0
- package/src/types/api.d.ts +354 -0
- package/templates/starter/index.html +70 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- block:
|
|
2
|
+
description: Big headline with optional kicker and subtitle. Words rise in one by one.
|
|
3
|
+
params: title, subtitle, kicker, accent (color), align (center|left)
|
|
4
|
+
usage: <gm-include src="blocks/title-card.html" kicker="Chapter 1" title="Ship faster" subtitle="Automate the boring parts" data-duration="4"></gm-include>
|
|
5
|
+
-->
|
|
6
|
+
<div class="gmb-title gmb-title--{{align|center}}" style="--accent:{{accent|#7c9cff}}">
|
|
7
|
+
<div class="gmb-title__kicker" data-enter="fade-up 0.6 0 out-expo">{{kicker}}</div>
|
|
8
|
+
<h1 class="gmb-title__h" data-split="words" data-enter="rise 0.9 0.1" data-stagger="0.07">{{title|Your title here}}</h1>
|
|
9
|
+
<div class="gmb-title__line"></div>
|
|
10
|
+
<p class="gmb-title__sub" data-enter="fade-up 0.7 0.55">{{subtitle}}</p>
|
|
11
|
+
</div>
|
|
12
|
+
<style>
|
|
13
|
+
.gmb-title{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:0 calc(var(--px)*160);gap:calc(var(--px)*26)}
|
|
14
|
+
.gmb-title--left{align-items:flex-start;text-align:left}
|
|
15
|
+
.gmb-title__kicker{font-size:calc(var(--px)*30);font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:color-mix(in oklab,var(--accent),white 30%);text-shadow:0 1px calc(var(--px)*14) rgba(0,0,0,.45)}
|
|
16
|
+
.gmb-title__h{margin:0;font-size:calc(var(--px)*132);line-height:1.02;font-weight:800;letter-spacing:-.035em;max-width:16ch;text-wrap:balance}
|
|
17
|
+
.gmb-title__line{margin:calc(var(--px)*10) 0;width:calc(var(--px)*120);height:calc(var(--px)*8);border-radius:99px;background:var(--accent);transform-origin:left;animation:gmb-title-line .9s var(--ease-out-expo) .45s both}
|
|
18
|
+
.gmb-title--center .gmb-title__line{transform-origin:center}
|
|
19
|
+
.gmb-title__sub{margin:0;font-size:calc(var(--px)*44);line-height:1.3;opacity:.8;text-shadow:0 1px calc(var(--px)*14) rgba(0,0,0,.4);max-width:30ch;text-wrap:balance}
|
|
20
|
+
.gmb-title__kicker:empty,.gmb-title__sub:empty{display:none}
|
|
21
|
+
@keyframes gmb-title-line{from{scale:0 1}}
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<!-- How plants make food: a kids explainer about photosynthesis. -->
|
|
3
|
+
<html data-width="1920" data-height="1080" data-fps="30">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<style>
|
|
7
|
+
:root {
|
|
8
|
+
--sun: #ffd23f; --leaf: #3fbf5a; --leaf-dark: #23893b; --water: #3aa8ff; --air: #b9c3d6; --oxy: #7ef0ff;
|
|
9
|
+
--ink: #13324a;
|
|
10
|
+
}
|
|
11
|
+
body { background: #0f3b5c; color: #fff; font-family: Inter, system-ui, sans-serif; }
|
|
12
|
+
.scene { display: grid; place-items: center; }
|
|
13
|
+
.front { position: relative; z-index: 1; }
|
|
14
|
+
|
|
15
|
+
/* ---------- light "sky" scenes (custom illustrations) ---------- */
|
|
16
|
+
.sky { background: linear-gradient(180deg, #8fd6ff 0%, #c9efff 62%, #e9f9ff 100%); color: var(--ink); }
|
|
17
|
+
.heading { position: absolute; left: 0; right: 0; top: 80px; text-align: center; margin: 0;
|
|
18
|
+
font-size: 88px; font-weight: 900; letter-spacing: -.03em; color: var(--ink); }
|
|
19
|
+
|
|
20
|
+
/* Scene 2: three things a plant needs */
|
|
21
|
+
.needs { display: flex; gap: 120px; align-items: flex-end; margin-top: 120px; }
|
|
22
|
+
.need { display: flex; flex-direction: column; align-items: center; gap: 36px; }
|
|
23
|
+
.need svg { width: 300px; height: 300px; overflow: visible; }
|
|
24
|
+
.need .label { font-size: 60px; font-weight: 800; color: var(--ink); }
|
|
25
|
+
.need .small { font-size: 40px; font-weight: 600; color: #3d6683; margin-top: -24px; }
|
|
26
|
+
.rays { transform-box: fill-box; transform-origin: center; animation: spin 12s linear infinite; }
|
|
27
|
+
.bob { animation: float 2.4s ease-in-out infinite; }
|
|
28
|
+
|
|
29
|
+
/* Scene 3: the leaf kitchen */
|
|
30
|
+
.art { position: absolute; inset: 0; width: 100%; height: 100%; }
|
|
31
|
+
.soil { fill: #7a4b2a; }
|
|
32
|
+
.beam { stroke: var(--sun); stroke-width: 14; stroke-linecap: round; fill: none; stroke-dasharray: 1;
|
|
33
|
+
animation: draw .9s var(--ease-in-out-cubic) both; }
|
|
34
|
+
.root { stroke: #d9a877; stroke-width: 10; stroke-linecap: round; fill: none; stroke-dasharray: 1;
|
|
35
|
+
animation: draw 1s var(--ease-out-cubic) .3s both; }
|
|
36
|
+
.leafbody { transform-box: fill-box; transform-origin: 50% 100%; animation: pop-in .8s var(--ease-out-back) .1s both; }
|
|
37
|
+
.leafglow { transform-box: fill-box; transform-origin: center; animation: glow 1.2s ease-in-out 6.2s infinite alternate both; }
|
|
38
|
+
@keyframes glow { from { opacity: 0; } to { opacity: .85; } }
|
|
39
|
+
|
|
40
|
+
.drop, .bubble { position: absolute; left: 0; top: 0; border-radius: 50%; }
|
|
41
|
+
.drop { width: 34px; height: 34px; margin: -17px 0 0 -17px; background: var(--water);
|
|
42
|
+
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; box-shadow: 0 0 0 5px #ffffff88;
|
|
43
|
+
animation: up-stem 1.8s linear var(--d) infinite both; }
|
|
44
|
+
@keyframes up-stem {
|
|
45
|
+
0% { translate: 960px 1000px; opacity: 0; }
|
|
46
|
+
15% { opacity: 1; }
|
|
47
|
+
85% { opacity: 1; }
|
|
48
|
+
100% { translate: 960px 640px; opacity: 0; }
|
|
49
|
+
}
|
|
50
|
+
.bubble { width: 110px; height: 110px; margin: -55px 0 0 -55px; display: grid; place-items: center;
|
|
51
|
+
font-size: 36px; font-weight: 900; }
|
|
52
|
+
.co2 { background: #e7ecf5; color: #47546b; border: 5px solid #9aa7bf;
|
|
53
|
+
animation: in-leaf 2.2s var(--ease-in-out-cubic) var(--d) infinite both; }
|
|
54
|
+
@keyframes in-leaf {
|
|
55
|
+
0% { translate: 1880px 560px; opacity: 0; scale: 1; }
|
|
56
|
+
20% { opacity: 1; }
|
|
57
|
+
80% { opacity: 1; scale: 1; }
|
|
58
|
+
100% { translate: 1130px 520px; opacity: 0; scale: .8; }
|
|
59
|
+
}
|
|
60
|
+
.o2 { background: #dffbff; color: #0b6f86; border: 5px solid var(--oxy);
|
|
61
|
+
animation: out-leaf 2.4s var(--ease-out-cubic) var(--d) infinite both; }
|
|
62
|
+
@keyframes out-leaf {
|
|
63
|
+
0% { translate: 1120px 330px; opacity: 0; scale: .8; }
|
|
64
|
+
20% { opacity: 1; scale: 1; }
|
|
65
|
+
80% { opacity: 1; }
|
|
66
|
+
100% { translate: 1760px 290px; opacity: 0; }
|
|
67
|
+
}
|
|
68
|
+
.pill { position: absolute; padding: 16px 30px; border-radius: 999px; font-size: 44px; font-weight: 800;
|
|
69
|
+
background: #fff; color: var(--ink); box-shadow: 0 14px 34px #0b2a4a33; white-space: nowrap; }
|
|
70
|
+
.pill i { font-style: normal; display: inline-block; width: 22px; height: 22px; border-radius: 50%; margin-right: 14px; vertical-align: 2px; }
|
|
71
|
+
.sugar { position: absolute; left: 960px; top: 470px; translate: -50% -50%; padding: 22px 40px; border-radius: 28px;
|
|
72
|
+
background: var(--sun); color: #5a3d00; font-size: 56px; font-weight: 900; box-shadow: 0 16px 40px #7a5a0055; white-space: nowrap; }
|
|
73
|
+
|
|
74
|
+
/* Scene 4: steps */
|
|
75
|
+
.stepwrap { display: flex; flex-direction: column; align-items: center; gap: 110px; }
|
|
76
|
+
.stepwrap h2 { margin: 0; font-size: 96px; font-weight: 900; letter-spacing: -.03em; text-align: center; }
|
|
77
|
+
.stepwrap h2 b { color: var(--sun); }
|
|
78
|
+
|
|
79
|
+
/* Scene 5: checklist + tree */
|
|
80
|
+
.thanks { display: flex; align-items: center; gap: 140px; }
|
|
81
|
+
.tree { font-size: 360px; line-height: 1; animation: float 3s ease-in-out infinite; }
|
|
82
|
+
</style>
|
|
83
|
+
</head>
|
|
84
|
+
<body>
|
|
85
|
+
<main data-sequence data-transition="slide-left 0.7 in-out-cubic">
|
|
86
|
+
|
|
87
|
+
<!-- 1. Title -->
|
|
88
|
+
<section class="scene" data-duration="4">
|
|
89
|
+
<gm-include src="blocks/gradient-bg.html" c1="#3fbf5a" c2="#ffd23f" c3="#3aa8ff" base="#0f3b5c"></gm-include>
|
|
90
|
+
<div class="front" style="position:absolute;inset:0">
|
|
91
|
+
<gm-include src="blocks/title-card.html" kicker="Science for kids" title="How plants make food" subtitle="It has a big name: photosynthesis!" accent="#ffd23f"></gm-include>
|
|
92
|
+
</div>
|
|
93
|
+
</section>
|
|
94
|
+
|
|
95
|
+
<!-- 2. What a plant needs (custom illustration) -->
|
|
96
|
+
<section class="scene sky" data-duration="5">
|
|
97
|
+
<h2 class="heading" data-enter="fade-down 0.7">A plant needs 3 things</h2>
|
|
98
|
+
<div class="needs" data-enter="pop 0.7 0.3" data-stagger="0.3">
|
|
99
|
+
<div class="need">
|
|
100
|
+
<svg viewBox="-150 -150 300 300">
|
|
101
|
+
<g class="rays" stroke="#ffb703" stroke-width="16" stroke-linecap="round">
|
|
102
|
+
<line x1="0" y1="-140" x2="0" y2="-105"/><line x1="0" y1="140" x2="0" y2="105"/>
|
|
103
|
+
<line x1="-140" y1="0" x2="-105" y2="0"/><line x1="140" y1="0" x2="105" y2="0"/>
|
|
104
|
+
<line x1="-99" y1="-99" x2="-74" y2="-74"/><line x1="99" y1="99" x2="74" y2="74"/>
|
|
105
|
+
<line x1="-99" y1="99" x2="-74" y2="74"/><line x1="99" y1="-99" x2="74" y2="-74"/>
|
|
106
|
+
</g>
|
|
107
|
+
<circle r="82" fill="#ffd23f" stroke="#ffb703" stroke-width="8"/>
|
|
108
|
+
<circle cx="-28" cy="-12" r="9" fill="#5a3d00"/><circle cx="28" cy="-12" r="9" fill="#5a3d00"/>
|
|
109
|
+
<path d="M-32 22 Q0 52 32 22" stroke="#5a3d00" stroke-width="9" fill="none" stroke-linecap="round"/>
|
|
110
|
+
</svg>
|
|
111
|
+
<div class="label">Sunlight</div>
|
|
112
|
+
<div class="small">for energy</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div class="need">
|
|
115
|
+
<svg viewBox="-150 -150 300 300"><g class="bob">
|
|
116
|
+
<path d="M0 -125 C 40 -60, 95 -5, 95 45 A 95 95 0 0 1 -95 45 C -95 -5, -40 -60, 0 -125 Z" fill="#3aa8ff" stroke="#1d7fd1" stroke-width="8"/>
|
|
117
|
+
<ellipse cx="-38" cy="20" rx="14" ry="30" fill="#ffffff99"/>
|
|
118
|
+
<circle cx="-26" cy="55" r="9" fill="#0b3d6b"/><circle cx="26" cy="55" r="9" fill="#0b3d6b"/>
|
|
119
|
+
<path d="M-24 85 Q0 105 24 85" stroke="#0b3d6b" stroke-width="8" fill="none" stroke-linecap="round"/>
|
|
120
|
+
</g></svg>
|
|
121
|
+
<div class="label">Water</div>
|
|
122
|
+
<div class="small">from the ground</div>
|
|
123
|
+
</div>
|
|
124
|
+
<div class="need">
|
|
125
|
+
<svg viewBox="-150 -150 300 300"><g class="bob" style="animation-delay:-1.2s">
|
|
126
|
+
<path d="M-110 60 A 55 55 0 0 1 -80 -40 A 70 70 0 0 1 40 -70 A 60 60 0 0 1 110 10 A 50 50 0 0 1 90 90 L -80 90 A 40 40 0 0 1 -110 60 Z" fill="#eef2f8" stroke="#9aa7bf" stroke-width="8"/>
|
|
127
|
+
<text x="0" y="40" text-anchor="middle" font-size="72" font-weight="900" fill="#47546b" font-family="Inter">CO₂</text>
|
|
128
|
+
</g></svg>
|
|
129
|
+
<div class="label">Air</div>
|
|
130
|
+
<div class="small">a gas called CO₂</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</section>
|
|
134
|
+
|
|
135
|
+
<!-- 3. The leaf kitchen (custom animated illustration) -->
|
|
136
|
+
<section class="scene sky" data-duration="9">
|
|
137
|
+
<svg class="art" viewBox="0 0 1920 1080">
|
|
138
|
+
<!-- sun + beams -->
|
|
139
|
+
<g transform="translate(260 300)">
|
|
140
|
+
<g class="rays" stroke="#ffb703" stroke-width="14" stroke-linecap="round">
|
|
141
|
+
<line x1="0" y1="-125" x2="0" y2="-95"/><line x1="0" y1="125" x2="0" y2="95"/>
|
|
142
|
+
<line x1="-125" y1="0" x2="-95" y2="0"/><line x1="125" y1="0" x2="95" y2="0"/>
|
|
143
|
+
<line x1="-88" y1="-88" x2="-67" y2="-67"/><line x1="88" y1="88" x2="67" y2="67"/>
|
|
144
|
+
<line x1="-88" y1="88" x2="-67" y2="67"/><line x1="88" y1="-88" x2="67" y2="-67"/>
|
|
145
|
+
</g>
|
|
146
|
+
<circle r="75" fill="#ffd23f" stroke="#ffb703" stroke-width="8"/>
|
|
147
|
+
</g>
|
|
148
|
+
<path class="beam" pathLength="1" d="M380 250 L760 360" style="animation-delay:.8s"/>
|
|
149
|
+
<path class="beam" pathLength="1" d="M390 320 L740 450" style="animation-delay:1s"/>
|
|
150
|
+
<path class="beam" pathLength="1" d="M370 390 L760 540" style="animation-delay:1.2s"/>
|
|
151
|
+
<!-- soil + roots -->
|
|
152
|
+
<rect class="soil" x="0" y="880" width="1920" height="200"/>
|
|
153
|
+
<path d="M0 880 Q 480 860 960 880 T 1920 880 V 900 H 0 Z" fill="#5e3a20"/>
|
|
154
|
+
<path class="root" pathLength="1" d="M960 880 C 950 940, 900 980, 840 1030"/>
|
|
155
|
+
<path class="root" pathLength="1" d="M960 880 C 970 950, 1030 990, 1090 1040"/>
|
|
156
|
+
<path class="root" pathLength="1" d="M960 880 C 960 960, 955 1010, 960 1070"/>
|
|
157
|
+
<!-- stem -->
|
|
158
|
+
<path d="M960 880 C 950 800, 970 740, 960 660" stroke="#2e9a48" stroke-width="26" fill="none" stroke-linecap="round"/>
|
|
159
|
+
<!-- leaf -->
|
|
160
|
+
<g class="leafbody">
|
|
161
|
+
<ellipse class="leafglow" cx="960" cy="460" rx="300" ry="240" fill="#fff6a8" style="filter: blur(30px)"/>
|
|
162
|
+
<path d="M960 680 C 700 620, 660 330, 960 230 C 1260 330, 1220 620, 960 680 Z" fill="#3fbf5a" stroke="#23893b" stroke-width="10"/>
|
|
163
|
+
<path d="M960 670 L960 260 M960 560 L860 480 M960 560 L1060 480 M960 450 L880 380 M960 450 L1040 380" stroke="#2a9a46" stroke-width="9" fill="none" stroke-linecap="round"/>
|
|
164
|
+
</g>
|
|
165
|
+
</svg>
|
|
166
|
+
|
|
167
|
+
<h2 class="heading" data-enter="fade-down 0.7">The leaf is a tiny kitchen</h2>
|
|
168
|
+
|
|
169
|
+
<!-- water drops climbing the stem -->
|
|
170
|
+
<div data-start="2">
|
|
171
|
+
<div class="drop" style="--d:0s"></div><div class="drop" style="--d:.6s"></div><div class="drop" style="--d:1.2s"></div>
|
|
172
|
+
</div>
|
|
173
|
+
<!-- CO2 going in -->
|
|
174
|
+
<div data-start="3.4">
|
|
175
|
+
<div class="bubble co2" style="--d:0s">CO₂</div><div class="bubble co2" style="--d:1.1s">CO₂</div>
|
|
176
|
+
</div>
|
|
177
|
+
<!-- oxygen coming out -->
|
|
178
|
+
<div data-start="5">
|
|
179
|
+
<div class="bubble o2" style="--d:0s">O₂</div><div class="bubble o2" style="--d:1.2s">O₂</div>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
<div class="pill" style="left:120px; top:470px" data-enter="pop 0.5 1">☀️ Sunlight in</div>
|
|
183
|
+
<div class="pill" style="left:200px; top:760px" data-enter="pop 0.5 2.2"><i style="background:var(--water)"></i>Water climbs up</div>
|
|
184
|
+
<div class="pill" style="left:1380px; top:640px" data-enter="pop 0.5 3.6"><i style="background:#9aa7bf"></i>CO₂ goes in</div>
|
|
185
|
+
<div class="pill" style="left:1330px; top:380px" data-enter="pop 0.5 5.2"><i style="background:var(--oxy)"></i>Oxygen comes out</div>
|
|
186
|
+
<div class="sugar" data-enter="pop 0.7 6.4">Sugar = plant food!</div>
|
|
187
|
+
</section>
|
|
188
|
+
|
|
189
|
+
<!-- 4. The recipe as steps -->
|
|
190
|
+
<section class="scene" data-duration="5.5">
|
|
191
|
+
<gm-include src="blocks/gradient-bg.html" c1="#1c6b33" c2="#1b5f9e" c3="#256e66" base="#0a2338"></gm-include>
|
|
192
|
+
<div class="front stepwrap">
|
|
193
|
+
<h2 data-enter="rise 0.8">The plant <b>recipe</b></h2>
|
|
194
|
+
<gm-include src="blocks/steps.html" steps="Catch sunlight|Drink water|Breathe in CO₂|Make sugar!" every="0.9" first="0.6" accent="#ffd23f"></gm-include>
|
|
195
|
+
</div>
|
|
196
|
+
</section>
|
|
197
|
+
|
|
198
|
+
<!-- 5. Why it matters -->
|
|
199
|
+
<section class="scene" data-duration="5">
|
|
200
|
+
<gm-include src="blocks/gradient-bg.html" c1="#1e6e3f" c2="#145f6b" c3="#0f4d3a" base="#06241f"></gm-include>
|
|
201
|
+
<div class="front thanks">
|
|
202
|
+
<gm-include src="blocks/checklist.html" title="Plants help us too!" every="0.7" first="0.5" accent="#ffd23f"><li>Fresh oxygen to breathe</li><li>Food for animals and us</li><li>Homes for bugs and birds</li></gm-include>
|
|
203
|
+
<div data-enter="pop 0.8 0.2"><div class="tree">🌳</div></div>
|
|
204
|
+
</div>
|
|
205
|
+
</section>
|
|
206
|
+
|
|
207
|
+
<!-- 6. End card -->
|
|
208
|
+
<section class="scene" data-duration="4.5">
|
|
209
|
+
<gm-include src="blocks/gradient-bg.html" c1="#6b5200" c2="#1c6b33" c3="#1b5f9e" base="#0a2236"></gm-include>
|
|
210
|
+
<div class="front" style="position:absolute;inset:0">
|
|
211
|
+
<gm-include src="blocks/end-card.html" title="Light + water + air = food!" subtitle="Next time you see a leaf, say thank you." cta="Go find a leaf! 🍃" accent="#ffd23f"></gm-include>
|
|
212
|
+
</div>
|
|
213
|
+
</section>
|
|
214
|
+
|
|
215
|
+
</main>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<!-- One template, many videos. Values come from --props / --data (or the defaults below).
|
|
3
|
+
npx givemotion render examples/personalized/index.html --props '{"name":"Ada","plan":"Pro","color":"#22c55e"}' -o out/ada.mp4
|
|
4
|
+
Batch from Node: for (const p of people) await render('index.html', { data: p, output: `out/${p.name}.mp4` }) -->
|
|
5
|
+
<html data-width="1080" data-height="1080" data-fps="30" data-duration="5">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="utf-8">
|
|
8
|
+
<script type="application/json" id="gm-data">{ "name": "Friend", "plan": "Starter", "color": "#8ea2ff", "days": 30 }</script>
|
|
9
|
+
<style>
|
|
10
|
+
body { background: #0b0d14; color: #fff; font-family: Inter, system-ui, sans-serif; }
|
|
11
|
+
.wrap { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 30px; text-align: center; padding: 0 90px; }
|
|
12
|
+
.hi { font-size: 54px; color: #ffffffb8; }
|
|
13
|
+
h1 { margin: 0; font-size: 120px; line-height: 1; letter-spacing: -.045em; font-weight: 800; }
|
|
14
|
+
.plan { padding: 18px 40px; border-radius: 99px; font-size: 44px; font-weight: 800; color: #0b0d14; background: {{data.color}}; box-shadow: 0 20px 60px {{data.color}}55; }
|
|
15
|
+
.ring { position: absolute; width: 860px; height: 860px; border-radius: 50%; border: 3px solid {{data.color}}33; animation: pulse 3s ease-in-out infinite; }
|
|
16
|
+
.small { font-size: 36px; color: #ffffff99; }
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<div class="ring"></div>
|
|
21
|
+
<div class="wrap" data-camera="push 1.08">
|
|
22
|
+
<div class="hi" data-enter="fade-up 0.6">Welcome aboard,</div>
|
|
23
|
+
<h1 data-split="chars" data-enter="pop 0.5 0.3" data-stagger="0.04">{{data.name}}</h1>
|
|
24
|
+
<div class="plan" data-enter="scale 0.6 1.0 out-back">{{data.plan}} plan</div>
|
|
25
|
+
<div class="small" data-enter="fade 0.6 1.6">Your first <span data-count="0 {{data.days}}" data-count-delay="1.6"></span> days are on us.</div>
|
|
26
|
+
</div>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
package/llms.txt
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# givemotion
|
|
2
|
+
|
|
3
|
+
> Make videos with AI, free and open source (MIT). A free code-to-video engine built for AI coding agents (Claude Code, Cursor, Codex): the agent writes one HTML/CSS/JS page, checks it (`check`), looks at key frames (`snapshot`) and renders MP4/WebM/ProRes/GIF. After an edit, a new render redoes only the 1-2 s parts that changed, byte-identical to a full render. Free for any use, including companies (MIT, zero npm dependencies, no telemetry, no account). Needs Node 20+, ffmpeg and Chrome.
|
|
4
|
+
|
|
5
|
+
Created by Leonardo Grigorio (https://github.com/leonardogrig) as an independent open-source project. Website: https://givemotion.org. Compared with HyperFrames and Remotion in the README ("How it compares").
|
|
6
|
+
|
|
7
|
+
Install in a project: `npx givemotion init my-video` (starter video + the agent skill pack) or `npx givemotion skill` (skill pack only: `.claude/skills/givemotion/`, `.agents/skills/givemotion/`, and a section in `AGENTS.md`). As a Claude Code plugin: `/plugin marketplace add givemotion/givemotion`, then `/plugin install givemotion@givemotion`. With the skills CLI: `npx skills add givemotion/givemotion`. Then ask the agent for a video.
|
|
8
|
+
|
|
9
|
+
Core loop: plan a shot list → write HTML → `npx givemotion check file.html` → `npx givemotion snapshot file.html` (look at snapshots/sheet.png) → `npx givemotion render file.html -o out/video.mp4`.
|
|
10
|
+
|
|
11
|
+
## Agent skill (read SKILL.md first, the rest on demand)
|
|
12
|
+
|
|
13
|
+
- [SKILL.md](skills/givemotion/SKILL.md): the loop, composition format, timing model, quality rules, built-in motion, presets, blocks, and which reference to read when.
|
|
14
|
+
- [techniques/](skills/givemotion/references/techniques/): one short recipe per technique (logo reveal, kinetic type, text reveals, camera, transitions, light, charts, paths/maps, shapes, UI demo, code, impacts, captions, hand-drawn, backgrounds).
|
|
15
|
+
- [api.md](skills/givemotion/references/api.md): built-in attributes, presets, easings, preset CSS, blocks.
|
|
16
|
+
- [motion-design.md](skills/givemotion/references/motion-design.md): motion design principles with numbers (timing, easing, camera grammar, continuity) and what blind judges punished.
|
|
17
|
+
- [styles.md](skills/givemotion/references/styles.md): eight named looks (palette tokens, fonts, background, motion personality).
|
|
18
|
+
- [timeline.md](skills/givemotion/references/timeline.md): full `gm.timeline` / `gm.fly` API, sequences, cuts, cut-align, the morph transition.
|
|
19
|
+
- [camera.md](skills/givemotion/references/camera.md): `gm.camera` over a world, shot options, parallax, path travel, one object riding another.
|
|
20
|
+
- [charts.md](skills/givemotion/references/charts.md): live line charts (`gm.chart.line`), chart blocks, counters.
|
|
21
|
+
- [diagrams.md](skills/givemotion/references/diagrams.md): arrows (`gm.connect`), hand-drawn (`data-sketch`), `data-anchor` labels, shapes and path morphs.
|
|
22
|
+
- [media-audio.md](skills/givemotion/references/media-audio.md): video, audio, beats, `data-pulse`, `gm.audio`, captions, fonts.
|
|
23
|
+
- [data-templates.md](skills/givemotion/references/data-templates.md): `--data`, `{{data.…}}`, `<gm-include>`, blocks, the cursor block.
|
|
24
|
+
- [javascript.md](skills/givemotion/references/javascript.md): `gm.onFrame` and helpers, particle bursts, seekable JS rules, canvas, Lottie.
|
|
25
|
+
- [output.md](skills/givemotion/references/output.md): render options, the parts cache, render speed, transparent overlays, bundle and `<gm-player>`, React.
|
|
26
|
+
- [review.md](skills/givemotion/references/review.md): snapshot/inspect/check recipes, reading a sheet, `analyze` for reference videos.
|
|
27
|
+
- [check-codes.md](skills/givemotion/references/check-codes.md): every `check` code and how to fix it, `data-check`.
|
|
28
|
+
- [genres/](skills/givemotion/references/genres/): explainer, data story, promo, UI demo, code explainer, logo sting, vertical short, whiteboard, year recap.
|
|
29
|
+
|
|
30
|
+
## More
|
|
31
|
+
|
|
32
|
+
- [README](README.md): overview, commands, performance, how it works.
|
|
33
|
+
- [Blocks](blocks/): copyable HTML building blocks; each file's header lists params and usage.
|
|
34
|
+
- [Examples](examples/): complete compositions.
|
package/package.json
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "givemotion",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Make videos with AI, free and open source (MIT). A code-to-video engine built for AI agents like Claude Code, Cursor and Codex: the agent writes HTML/CSS, checks and previews its own video, and renders MP4.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Leonardo Grigorio (https://github.com/leonardogrig)",
|
|
8
|
+
"homepage": "https://givemotion.org",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/givemotion/givemotion.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/givemotion/givemotion/issues",
|
|
14
|
+
"bin": {
|
|
15
|
+
"givemotion": "src/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"main": "src/api.js",
|
|
18
|
+
"types": "./src/types/api.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./src/types/api.d.ts",
|
|
22
|
+
"default": "./src/api.js"
|
|
23
|
+
},
|
|
24
|
+
"./runtime": "./src/runtime/runtime.js",
|
|
25
|
+
"./preset.css": "./src/runtime/preset.css",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"src",
|
|
30
|
+
"blocks",
|
|
31
|
+
"templates",
|
|
32
|
+
"skills",
|
|
33
|
+
"examples",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"THIRD_PARTY_NOTICES.md",
|
|
37
|
+
"SECURITY.md",
|
|
38
|
+
"llms.txt",
|
|
39
|
+
"AGENTS.md"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"test": "tsc -p . && node --test --test-concurrency=1 test/unit.test.js test/e2e.test.js test/features.test.js",
|
|
46
|
+
"typecheck": "tsc -p .",
|
|
47
|
+
"bench": "node src/cli.js bench"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"video",
|
|
51
|
+
"html-to-video",
|
|
52
|
+
"animation",
|
|
53
|
+
"motion-graphics",
|
|
54
|
+
"ai",
|
|
55
|
+
"agents",
|
|
56
|
+
"claude",
|
|
57
|
+
"render",
|
|
58
|
+
"mp4",
|
|
59
|
+
"ffmpeg",
|
|
60
|
+
"headless-chrome",
|
|
61
|
+
"ai-video",
|
|
62
|
+
"ai-agents",
|
|
63
|
+
"claude-code",
|
|
64
|
+
"cursor",
|
|
65
|
+
"codex",
|
|
66
|
+
"agent-skills",
|
|
67
|
+
"motion-design",
|
|
68
|
+
"video-generation",
|
|
69
|
+
"programmatic-video",
|
|
70
|
+
"explainer-video",
|
|
71
|
+
"social-video",
|
|
72
|
+
"captions",
|
|
73
|
+
"data-visualization",
|
|
74
|
+
"open-source",
|
|
75
|
+
"free",
|
|
76
|
+
"mit"
|
|
77
|
+
],
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@types/node": "^20.19.43",
|
|
80
|
+
"typescript": "^5.9.3"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: givemotion
|
|
3
|
+
description: Makes videos from HTML + CSS + JS with givemotion and renders MP4/WebM/GIF/ProRes. Use for any request to create, edit, check or render a video, animation, motion graphic, explainer, promo, logo sting, title card, lower third, animated chart or data story, captions, whiteboard/hand-drawn video, UI or product demo, or vertical social clip, or when a givemotion composition is open.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "0.1.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# givemotion: HTML in, video out
|
|
9
|
+
|
|
10
|
+
A composition is one HTML file. Every frame is that page at a moment in time. CSS animations, transitions, Web Animations, timers, `requestAnimationFrame`, canvas and WebGL all run on a virtual clock, so what you write renders frame-exact and identically every time. No script tag or import is needed: the runtime (`window.gm`) and a preset stylesheet are injected for you.
|
|
11
|
+
|
|
12
|
+
This file is the core (read it all). Then read **only** the 1-3 technique recipes your video needs (table at the end): each one shows how a professional builds that effect, with numbers and a working example. Look up anything else when you need it.
|
|
13
|
+
|
|
14
|
+
## The loop
|
|
15
|
+
|
|
16
|
+
0. **Plan.** Read the brief. Pick the recipes it needs. Write a shot list as a comment at the top of the HTML, one line per moment: time range, what is on screen, how it moves, how it hands over to the next moment.
|
|
17
|
+
1. **Write** the composition (`video.html`).
|
|
18
|
+
2. `npx givemotion check video.html`: fix every ✖ error; fix ⚠ warnings (real faults: text cut off, overlapping, unreadable) unless you meant it. ℹ notes are style hints (a straight path, one easing everywhere, the camera pausing): look at the frames and ignore them when the move is what you meant. Do not spend rounds making check quiet; spend them making the video look better. The report starts with a motion strip, one mark per half second (`▁` little changes, `█` the whole picture changes).
|
|
19
|
+
3. `npx givemotion snapshot video.html`: **open `snapshots/sheet.png` and look at it** with a designer's eye. To judge one move, `snapshot --every 0.1 --from 2 --to 3`. Fix and repeat 2-3.
|
|
20
|
+
4. `npx givemotion render video.html -o out/video.mp4`.
|
|
21
|
+
|
|
22
|
+
`--json` on any command for machine output; `<command> --help` for options. `still video.html -t 3.2 -o f.png` renders one moment; `inspect --at 4.5 --el "#logo"` says where an element is then.
|
|
23
|
+
|
|
24
|
+
## How good motion is made here
|
|
25
|
+
|
|
26
|
+
The engine gives you any HTML/CSS/SVG/canvas and a frame-exact timeline; the look comes from how you choreograph it. Blind viewers preferred videos where every element was choreographed by hand over videos built from one-word presets.
|
|
27
|
+
|
|
28
|
+
1. **Choreograph by hand.** Use `gm.timeline` for anything that matters: explicit start times, per-move easing (a fast `expo.out` slam, a soft `sine.inOut` drift, a `back.out(1.6)` landing), offsets of 40-120 ms between related parts. Presets (`data-enter`, `data-camera`) are fine for small supporting things.
|
|
29
|
+
2. **Three layers on every hero moment:** the main move; secondary detail that sells it (blur while fast, a glow, a shadow that grows, follow-through, a ring or particles on impact); and ambient motion so the frame is never frozen (drifting background, slow camera push).
|
|
30
|
+
3. **Contrast in timing.** Fast in, slow settle; holds of 0.4-1 s after something lands; exits shorter than entrances. Never move everything at the same speed with the same curve.
|
|
31
|
+
4. **Follow the brief exactly** for colors, fonts, copy, sizes and timing; your craft goes into how things move, not into extra content.
|
|
32
|
+
5. **Frame 0 is the hook**, nothing is cut by the frame edge, text is big (titles 96-200 px, body ≥ 36 px at 1080p), one hero per moment, scenes flow into each other (push, whip, morph, match cut) rather than fading.
|
|
33
|
+
6. **Things come from things.** A new element is born from one already on screen, not spawned from nowhere: three circles squeeze out of the main circle; one of the rectangles on screen slides over and becomes the underline; a card grows out of the button that was clicked; the logo's mark becomes the end card's mark. Reuse and transform before you add.
|
|
34
|
+
7. **A camera move means "look here".** Push in only toward something the viewer should read next. Never zoom into empty space or into the old scene as a way to transition: to leave a scene, move sideways (push, whip, wipe) or carry an element across (morph, the rule above).
|
|
35
|
+
8. **Animate** `transform`/`translate`/`scale`/`rotate`/`opacity`/`filter`/`clip-path`, not `width`/`top`/`left`.
|
|
36
|
+
9. **Every element gets a planned life:** in, a readable hold (~1 s + 0.25 s a word), then an exit or hand-over. The shot list gives each hold.
|
|
37
|
+
|
|
38
|
+
## Hierarchy: one thing matters at a time
|
|
39
|
+
|
|
40
|
+
Viewers preferred videos where the eye always knew where to look.
|
|
41
|
+
- **Every line has a key word.** Give the word that carries the meaning contrast: the accent color, a heavier weight, a bigger size, or a highlight/underline drawn on. The rest of the line stays quieter (ink or muted color, lighter weight). One per line, at most two per screen. If everything is accent, nothing is.
|
|
42
|
+
- **Every moment has one hero:** the biggest, brightest thing with the most motion. Support is clearly smaller (hero ≥ 1.6× the next size; three levels at most: hero, support, label), dimmer (muted color or 50-70% opacity), arrives after the hero and moves less.
|
|
43
|
+
- **Lead the eye in order:** the hero lands first; the key word changes color or gets its underline on its own beat (0.2-0.4 s after the line settles); support follows. When the camera or a callout focuses on something, dim or blur the rest.
|
|
44
|
+
- **Use the brief's palette roles strictly:** accent colors for emphasis only, muted for secondary text.
|
|
45
|
+
|
|
46
|
+
## Easing: match the curve to the motion
|
|
47
|
+
|
|
48
|
+
- **Entering** decelerates (ease-out: `expo.out`, `power3.out`, or `back.out(1.4)` when it lands with weight).
|
|
49
|
+
- **Leaving** accelerates (ease-in: `power2.in`), shorter than the entrance (60-70%).
|
|
50
|
+
- **Moving from A to B** while visible, camera moves, a scale change of something already on screen: ease-in-out (`power2.inOut`, `sine.inOut`): it starts gently and lands gently.
|
|
51
|
+
- **Ambient drift:** long `sine.inOut`; `linear` only for loops (spins, tickers). Nothing that starts or stops on screen moves linearly.
|
|
52
|
+
- Leave `ease` out and the engine already does this (entrances spring in, moves ease in and out, exits ease in); when you set one, follow the rules above.
|
|
53
|
+
|
|
54
|
+
## Minimal composition
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
<!doctype html>
|
|
58
|
+
<html data-width="1920" data-height="1080" data-fps="30" data-duration="2.5">
|
|
59
|
+
<head>
|
|
60
|
+
<style>
|
|
61
|
+
:root { --bg: #0b0d12; --ink: #fff; --accent: #7c9cff; }
|
|
62
|
+
body { background: var(--bg); color: var(--ink); font-family: Inter, sans-serif; }
|
|
63
|
+
.scene { display: grid; place-items: center; } /* .scene is already absolute + full frame */
|
|
64
|
+
h1 { font-size: 160px; letter-spacing: -0.03em; margin: 0; }
|
|
65
|
+
.glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; background: var(--accent); filter: blur(160px); opacity: .25; }
|
|
66
|
+
</style>
|
|
67
|
+
</head>
|
|
68
|
+
<body>
|
|
69
|
+
<section class="scene">
|
|
70
|
+
<div class="glow"></div>
|
|
71
|
+
<h1 id="t" data-split="chars">Hello</h1>
|
|
72
|
+
</section>
|
|
73
|
+
<script>
|
|
74
|
+
gm.timeline('.scene')
|
|
75
|
+
.from('.glow', { scale: 0.6, opacity: 0, duration: 1.2, ease: 'sine.out' }, 0) // ambient: light blooms in…
|
|
76
|
+
.to('.glow', { x: 220, y: -90, duration: 2.5, ease: 'sine.inOut' }, 0) // …and keeps drifting
|
|
77
|
+
.from('#t .gm-char', { y: 140, opacity: 0, filter: 'blur(12px)', duration: 0.7, ease: 'expo.out', stagger: 0.05 }, 0.2) // main: fast in, blur while fast
|
|
78
|
+
.fromTo('#t', { letterSpacing: '0.12em' }, { letterSpacing: '-0.03em', duration: 2.4, ease: 'expo.out' }, 0.2) // detail: tracking tightens
|
|
79
|
+
.to('#t', { scale: 1.06, duration: 1.9, ease: 'sine.inOut' }, 0.6); // the hold keeps breathing
|
|
80
|
+
</script>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Built-in fonts (no files needed): `Inter`, `JetBrains Mono`, `Playfair Display`, `Space Grotesk`, `Bebas Neue`, `Nunito`, `Caveat`. Other fonts: `@font-face` from their file.
|
|
86
|
+
|
|
87
|
+
## Timing model (read this)
|
|
88
|
+
|
|
89
|
+
- Settings live on `<html>`: `data-width`, `data-height` (even numbers), `data-fps` (default 30), optional `data-duration`, optional `data-background`.
|
|
90
|
+
- Times are seconds: `1.5`, `1.5s`, `500ms`, `45f` (frames), `1:02.5`.
|
|
91
|
+
- **Clips.** An element with `data-start`, `data-duration` or `data-end` only exists (is `display`ed) from start to start+duration. Times are relative to its parent clip. Elements without timing are always there.
|
|
92
|
+
- **Video length** = `data-duration` on `<html>`, otherwise the end of the last clip.
|
|
93
|
+
- **Sequences.** `data-sequence` on a container plays its children one after another. Every child needs `data-duration`, or give the container `data-cuts="0 2.13 4.27"` (when each child starts; also `"beats: 0 4 8"` / `"bars: 0 1 2"`). `data-gap="0.2"` (negative = overlap). `data-transition="<name> <seconds> [easing]"` overlaps neighbours and animates the change; a child can set its own `data-transition` (how it comes in). **Each transition takes its length off the total**: 3 scenes of 4s with `fade 0.5` last 11s. Cuts on the beat, `data-cut-align`, and where a scene's time 0 then sits: `references/timeline.md`.
|
|
94
|
+
- **Transitions:** `push-`/`cover-`/`whip-`/`wipe-` + `left/right/up/down` (push: new pushes old out; cover: new slides over; whip: fast, blurred) `diagonal` `clock` `iris` `zoom` `zoom-through` (old scene flies past) `flip` (3D) `dip` (through black) `blur` `fade-up` `fade`, and **`morph`**: elements with the same `data-morph="name"` in both scenes fly and resize from the old place to the new one while the rest crossfades. Carries a logo, card or number across; in one scene use `gm.fly`.
|
|
95
|
+
- **CSS animations run on clip time.** `animation: fade-up .6s .4s both` starts .4s after its clip appears. Use `both` (or `backwards`) fill so the element is hidden before its delay.
|
|
96
|
+
- **Something appears later inside a long scene** (one camera world, one whiteboard): the delay in `data-enter` counts from the start of the element's clip, so `data-enter="write 0.8 11.9"` writes a label 11.9 s into the scene and keeps it hidden until then. No extra clip needed.
|
|
97
|
+
- `gm.onFrame(fn)` gets the **video's** time, even in a scene; `gm.onFrame('#s', (local, info, el) => …)` counts from `#s`'s start, like `gm.timeline('#s')`.
|
|
98
|
+
- Timers, `requestAnimationFrame`, `Date.now()`, `performance.now()` are virtual and `Math.random()` is seeded. Normal web animation code works.
|
|
99
|
+
|
|
100
|
+
## Timeline: precise choreography (GSAP-style, built in)
|
|
101
|
+
|
|
102
|
+
For anything with more than a few moving parts, use `gm.timeline`: the GSAP API you know, but every value is computed from the time, so it renders frame-exact and in parallel. Times are seconds **relative to the clip that contains the scope**.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
gm.timeline('#scene2') // scope: selectors are looked up inside it
|
|
106
|
+
.from('.title .gm-word', { y: 120, opacity: 0, rotate: 8, stagger: 0.06 }) // no ease: springs in
|
|
107
|
+
.to('.card', { x: 400, y: -60, scale: 1.2 }, '+=0.3') // arcs, sized to the distance
|
|
108
|
+
.fromTo('.bar', { scaleY: 0 }, { scaleY: 1, stagger: { each: 0.08, from: 'center' } }, '<')
|
|
109
|
+
.to('#line', { draw: 1, duration: 1.5 }, 2) // draw an SVG stroke
|
|
110
|
+
.to('.price', { textContent: 249, duration: 1.5 }, 2.5); // count a number
|
|
111
|
+
gm.fly('#event', { from: '#slot2', at: 7.5, duration: 0.8 }); // fly from another element's box into its own place
|
|
112
|
+
```
|
|
113
|
+
`from()`/`fromTo()` show their start values from the beginning of the clip (keeps things hidden until they enter). When tweens overlap on the same property, the one that started last wins. Positions, all props and options, labels, keyframes, `gm.fly` and SVG caveats: `references/timeline.md`.
|
|
114
|
+
|
|
115
|
+
Also built in (tables in `references/api.md`): `data-enter`/`data-exit` presets, `data-split`, `data-stagger`, `data-count`, `data-type` (typewriter), `data-scramble`, `data-camera` (push, float, shake…), `data-parallax`, `data-morph`, `data-fit`, `data-pulse`, easing names (GSAP names work), preset CSS keyframes and `var(--px)`, and ready-made blocks (`npx givemotion blocks`: captions, code-window, cursor, browser-window, charts…).
|
|
116
|
+
|
|
117
|
+
## Technique recipes (read the ones your video needs)
|
|
118
|
+
|
|
119
|
+
| Your video has… | Read |
|
|
120
|
+
|---|---|
|
|
121
|
+
| A logo, brand sting, intro or end card | `references/techniques/logo-reveal.md` |
|
|
122
|
+
| Big type that slams, stacks, rotates; a quote or headline as the star | `references/techniques/kinetic-type.md` |
|
|
123
|
+
| Text appearing: word/char reveals, typewriter, write-on, scramble, underline or highlight | `references/techniques/text-reveals.md` |
|
|
124
|
+
| Camera moves: push, follow, whip, bank, zoom to a detail, shake | `references/techniques/camera-moves.md` |
|
|
125
|
+
| Several scenes: how one hands over to the next (push, whip, morph, shape wipes) | `references/techniques/scene-transitions.md` |
|
|
126
|
+
| Glow, light sweeps, gradients, grain, motion blur, depth | `references/techniques/light-and-depth.md` |
|
|
127
|
+
| Numbers, counters, bar/line charts, callouts | `references/techniques/numbers-and-charts.md` |
|
|
128
|
+
| Lines that draw, routes, maps, pins, something travelling a path | `references/techniques/paths-and-maps.md` |
|
|
129
|
+
| Flat shapes: grow, squash, split, orbit, morph | `references/techniques/shapes-and-motion-graphics.md` |
|
|
130
|
+
| An app/UI with a cursor, clicks, typing, lists | `references/techniques/ui-demo.md` |
|
|
131
|
+
| Code in an editor, typing, line highlights | `references/techniques/code-on-screen.md` |
|
|
132
|
+
| Impact and energy: slams, shake, bursts, music beats | `references/techniques/impacts-and-energy.md` |
|
|
133
|
+
| Word-by-word captions, vertical 9:16 clips | `references/techniques/captions-vertical.md` |
|
|
134
|
+
| Whiteboard, sketch, hand-drawn | `references/techniques/hand-drawn.md` |
|
|
135
|
+
| A living background behind everything | `references/techniques/backgrounds-and-ambient.md` |
|
|
136
|
+
|
|
137
|
+
## API reference (look up when needed)
|
|
138
|
+
|
|
139
|
+
| When… | Read |
|
|
140
|
+
|---|---|
|
|
141
|
+
| An attribute, preset, easing name, preset CSS or block | `references/api.md` |
|
|
142
|
+
| `gm.timeline` in full: positions, keyframes, labels, `gm.fly`, SVG | `references/timeline.md` |
|
|
143
|
+
| `gm.camera` worlds, shots, `gm.path.travel`, riding, parallax | `references/camera.md` |
|
|
144
|
+
| `gm.chart.*`, chart blocks | `references/charts.md` |
|
|
145
|
+
| Diagrams, arrows, `data-sketch`, `gm.connect`, `gm.shape`, path morphs | `references/diagrams.md` |
|
|
146
|
+
| Music, beats, voice-over, video clips, captions files | `references/media-audio.md` |
|
|
147
|
+
| Data/templates, `<gm-include>` (scope, scenes, brand kit), blocks, highlight, cursor | `references/data-templates.md` |
|
|
148
|
+
| `gm.onFrame`, canvas, three.js, `gm.burst`, springs, noise, random, Lottie | `references/javascript.md` |
|
|
149
|
+
| Render options, transparency, cache | `references/output.md` |
|
|
150
|
+
| Reviewing frames, learning from a reference video | `references/review.md` |
|
|
151
|
+
| A check code | `references/check-codes.md` |
|
|
152
|
+
| Motion principles in depth (optional) | `references/motion-design.md`; genre structures in `references/genres/` |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# API: built-in attributes, presets, easings, preset CSS, blocks
|
|
2
|
+
|
|
3
|
+
Lookup tables. SKILL.md has the core; `references/timeline.md` has `gm.timeline` in full.
|
|
4
|
+
|
|
5
|
+
## Built-in motion (no JavaScript)
|
|
6
|
+
|
|
7
|
+
| Attribute | What it does |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `data-enter="<preset> [dur] [delay] [easing]"` | Animate in at the start of the element's clip. Default: a spring timed to the move's size. |
|
|
10
|
+
| `data-exit="<preset> [dur] [delay] [easing]"` | Animate out so it finishes at the clip end (delay counts back from the end). `collapse` takes a row out of a list: it slides aside, then its height closes and what is below moves up. |
|
|
11
|
+
| `data-stagger="0.08"` | Apply enter/exit to each child (or each split piece) with increasing delay. |
|
|
12
|
+
| `data-split="words\|chars\|lines"` | Wrap pieces in `.gm-word` / `.gm-char` spans with `--i` (index) and `--n` (count) for your own CSS. |
|
|
13
|
+
| `data-count="0 1250"` | Count up. Also `data-count-duration` (1.6), `-delay`, `-prefix`, `-suffix`, `-decimals`, `-ease`, `-group="false"`. |
|
|
14
|
+
| `data-type="30"` | Typewriter at 30 chars/sec, keeps inner markup. The text not typed yet stays in the layout, invisible (`.gm-rest`), so every letter appears where it stays: centred text does not drift as it grows and no word jumps to the next line. Also `data-type-delay`, `data-type-caret` (a blinking caret; `data-type-caret="0.8"` removes it 0.8 s after the typing ends). |
|
|
15
|
+
| `data-scramble="1.2"` | Text decodes from random glyphs, left to right, over 1.2s. Also `data-scramble-delay`, `data-scramble-chars`. |
|
|
16
|
+
| (no attribute) | To swap a word, a time or a label at a moment: `gm.timeline('#scene').set('#label', { textContent: 'Done' }, 2)` (seekable; `references/timeline.md`, "Text"). In JS, `gm.onFrame('#scene', (local, info, el) => …)` gets the scene's time; `gm.onFrame(fn)` alone gets the video's (`references/javascript.md`). |
|
|
17
|
+
| `data-camera="push 1.1"` | Slow camera move over the clip (added on top of other transforms). Moves: `push [scale]` `pull [scale]` `move-left/right/up/down [px]` `rotate [deg]` `orbit [deg]` (3D) `float [px]` (gentle drift, default 14) `handheld [px]` (default 7) `shake [px] [from-to]` (an impact: rises and dies away inside its window, e.g. `shake 14 2.1-2.5`). Combine with commas: `"push 1.08, float"`. Optional window `"push 1.2 1-3"` (seconds into the clip) and easing. Put it on the scene or on a wrapper of the content. |
|
|
18
|
+
| `data-parallax="0.3"` | Next to a `gm.camera` world: moves 30% as much as the world (depth). |
|
|
19
|
+
| `data-morph="logo"` | Shared element for `data-transition="morph"`. |
|
|
20
|
+
| `data-fit` | Shrink the text until it fits its box (give the box a width/height). `data-fit="grow"` makes one line exactly fill the box width (big kinetic lines; `data-fit-max="300"` caps the size). |
|
|
21
|
+
| `data-pulse="beat 0.06 0.25"` | Scale up on every beat of the `<html data-bpm>` grid (`references/media-audio.md`). |
|
|
22
|
+
| `data-loop="2"` `data-freeze="1.5"` `data-speed="0.5"` | On a clip: its content repeats every 2s / stops at 1.5s / plays at half speed (CSS animations, timeline, counters, video, onFrame). |
|
|
23
|
+
|
|
24
|
+
**Presets** (named by direction of travel): `fade` `fade-up` `fade-down` `fade-left` `fade-right` `rise` (up + unblur) `scale` `pop` (overshoot) `zoom` (from big) `blur` `slide-up/down/left/right` (by own size) `wipe-right/left/up/down` `iris` `draw` (SVG strokes) `none`, and for text and objects: `mask-up` `mask-down` `mask-left` `mask-right` (slides out from behind an invisible edge: the classic kinetic-type reveal, best with `data-split`) `flip-up` `drop` (falls in and bounces) `swing` `stretch` `tilt` `spin-in` `elastic` `grow` `grow-x` `grow-y` (bars, lines) `typewriter` (use with `data-split="chars"`) `write` (handwriting: the text appears left to right at pen speed; with `data-split="lines"` and `data-stagger` each line is written after the other). Each has good default timing.
|
|
25
|
+
|
|
26
|
+
**Easings:** `linear` `ease` `in/out/in-out-` + `sine` `quad` `cubic` `quart` `quint` `expo` `circ` `back` `elastic` `bounce`, springs `spring` `bouncy` `snappy` `gentle`, `steps(4)`, `cubic-bezier(…)`. GSAP names also work: `power2.out`, `back.out(1.7)`, `elastic.out(1,0.3)`, `sine.inOut`, `none`.
|
|
27
|
+
|
|
28
|
+
Enter/exit use the `translate`, `scale`, `opacity`, `filter`, `clip-path` properties, so they combine with your own `transform`, but they replace your own CSS `translate:`/`scale:` properties while they run: center with `transform: translate(-50%, -50%)`, `margin: auto` or a wrapper, not `translate: -50% 0`. Do not also animate `opacity` on the same element in your CSS; wrap it instead.
|
|
29
|
+
|
|
30
|
+
Classes the engine uses: `.scene` (full-frame layer), `.gm-word` / `.gm-char` (made by `data-split`), `.gm-caret`; everything else is yours.
|
|
31
|
+
|
|
32
|
+
## Preset CSS you can use
|
|
33
|
+
|
|
34
|
+
- Keyframes: `fade-in` `fade-out` `fade-up` `fade-down` `fade-left` `fade-right` `scale-in` `pop-in` `zoom-in` `blur-in` `slide-in-up/down/left/right` `wipe-right/left/up/down` `draw` `spin` `float` `pulse` `shimmer` `blink`. Example: `animation: pop-in .5s var(--ease-out-back) .3s both;`
|
|
35
|
+
- Easing variables: `--ease-out-expo` `--ease-out-back` `--ease-in-out-cubic` `--ease-spring` `--ease-bouncy` `--ease-snappy` `--ease-gentle` and the usual `--ease-in/out/in-out-{quad,cubic,quart,expo,back}`.
|
|
36
|
+
- `var(--px)` = 1px when the **short side** of the frame is 1080px (1920×1080, 1080×1920 and 1080×1080 all have `--px` = 1px; 4K has 2px). `calc(var(--px) * 48)` scales with the video. In JS: `gm.px`. `var(--stage-w)` / `var(--stage-h)` = frame size. Block sizes ("px at 1080p") use the same unit.
|
|
37
|
+
|
|
38
|
+
## Blocks
|
|
39
|
+
|
|
40
|
+
`npx givemotion blocks` lists ready-made blocks; `npx givemotion add lower-third captions` copies them into `./blocks/`, then `<gm-include src="blocks/captions.html" file="captions.json">`. Each file's header shows its params and usage. Blocks: title-card, lower-third, captions, code-window, bar-chart, line-chart, stat, checklist, steps, browser-window, phone, cursor, callout, compare, quote, word-pop, logo-reveal, end-card, gradient-bg, grid-bg, lottie. Custom visuals score better than stock blocks; use blocks for captions, code, cursor clicks, backgrounds (`references/data-templates.md`).
|