greenlight-motion 0.2.4 → 0.3.1

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/skill/SKILL.md CHANGED
@@ -18,7 +18,7 @@ You never write UI or animation code. If something is not in the format, it is n
18
18
  ## Setup (once per machine)
19
19
 
20
20
  ```
21
- npx greenlight-motion@0.2.4 doctor
21
+ npx greenlight-motion@0.3.1 doctor
22
22
  ```
23
23
 
24
24
  It checks Node 18+, Chrome or Edge, WebGPU and H.264 encoding, and prints a fix for anything missing. Do not install
@@ -39,7 +39,7 @@ animation presets (the same converter the GreenLight Motion connector uses in Cl
39
39
  keyframes rarely look as good. The format, the design rules and the catalogues: `skill/references/scene-script.md`.
40
40
 
41
41
  ```
42
- npx greenlight-motion@0.2.4 script <folder> --from scenes.json # or write <folder>/script.json, then: script <folder>
42
+ npx greenlight-motion@0.3.1 script <folder> --from scenes.json # or write <folder>/script.json, then: script <folder>
43
43
  ```
44
44
 
45
45
  Then `check` and `stills` (below), fix the SCRIPT and run `script` again — it rewrites `project.json`. A scene's
@@ -85,14 +85,14 @@ What the engine does there, so you don't learn it from a broken frame:
85
85
 
86
86
  ## Workflow
87
87
 
88
- 1. `npx greenlight-motion@0.2.4 init <folder>` — starts from a working example (title, subtitle, accent line, four
88
+ 1. `npx greenlight-motion@0.3.1 init <folder>` — starts from a working example (title, subtitle, accent line, four
89
89
  options). `--from file.json` starts from a project you have (for example one exported from GreenLight Dash).
90
90
  2. Edit `<folder>/project.json` — for changes to an EXISTING project prefer `apply` (below): it checks every edit and
91
91
  applies all or nothing. Put pictures, video, sound and fonts in `<folder>/assets/` and refer to them as
92
92
  `"asset:<file>"` (e.g. `"url": "asset:product.png"`).
93
- 3. `npx greenlight-motion@0.2.4 check <folder>` — fix everything it lists (missing files, template mistakes, blank
93
+ 3. `npx greenlight-motion@0.3.1 check <folder>` — fix everything it lists (missing files, template mistakes, blank
94
94
  frames, page errors), and read its notes: text the engine wraps where you did not break it. `--json` for machine output.
95
- 4. `npx greenlight-motion@0.2.4 stills <folder>` — renders frames and **a labelled contact sheet**. Open and look at
95
+ 4. `npx greenlight-motion@0.3.1 stills <folder>` — renders frames and **a labelled contact sheet**. Open and look at
96
96
  it before you go on: layout, readability, timing. Fix and repeat. `--at 0.5,1.2,3` for exact times.
97
97
  5. Hand it over: tell the user to open `<folder>/index.html` (Chrome or Edge), or `pack` it into one file, or
98
98
  `render` the MP4 yourself (`--fps 60 --motion-blur` for fast motion).
@@ -157,7 +157,7 @@ editor's own normalizer), so write only what you mean.
157
157
  Full references (generated from the editor's own docs; ignore the `/api/` routes they mention):
158
158
  `skill/references/` — video-design, scene-script, video-projects, video-text, video-text-kinetic, video-text-presets, video-shapes, video-keyframes,
159
159
  video-camera, video-3d, video-effects, video-transitions, video-particles, video-paths, video-backgrounds, video-grid.
160
- Machine-readable lists: `npx greenlight-motion@0.2.4 schema effects | transitions | easings | paths | expressions`.
160
+ Machine-readable lists: `npx greenlight-motion@0.3.1 schema effects | transitions | easings | paths | expressions`.
161
161
 
162
162
  ## Template
163
163
 
@@ -204,7 +204,7 @@ an absolute moment; `align` `sync` (default) / `start` / `end`; `offset` seconds
204
204
 
205
205
  The library is 77 hand-picked sounds in categories (whooshes and swooshes, transitions, clicks, pop-ups and
206
206
  notifications, data blips, typing and writing, foley, bubbles, impacts and bass drops, camera, gears, voice clips).
207
- `npx greenlight-motion@0.2.4 schema sounds` lists every one with its `category`, `use` (what it is for), `duration`
207
+ `npx greenlight-motion@0.3.1 schema sounds` lists every one with its `category`, `use` (what it is for), `duration`
208
208
  and `sync`. Pick by `category` and `use`, then by name.
209
209
 
210
210
  - **Where the files come from:** the GreenLight sound CDN. `build` downloads each sound a cue uses into
@@ -220,7 +220,7 @@ The page has **Notes**: the user marks what should change right on the frame (a
220
220
  and writes a note for each mark. Every note carries the moment (seconds and frame), the mark in composition pixels
221
221
  and the layers under it (item ids in project.json), so you change exactly that and nothing else.
222
222
 
223
- - **They review on this computer:** run `npx greenlight-motion@0.2.4 review <folder>` and give them the URL it prints
223
+ - **They review on this computer:** run `npx greenlight-motion@0.3.1 review <folder>` and give them the URL it prints
224
224
  (it keeps running; `--open` opens their browser, only when they ask). Their notes land in `<folder>/review/`: read
225
225
  `review/NOTES.md`, look at the `at-<t>s.png` pictures (the marks are numbered), make the changes (`apply`), `build`
226
226
  again and tell them to reload the page.
@@ -249,11 +249,11 @@ that fails (`plugin`); look at `stills` for the look. A package that carries its
249
249
 
250
250
  The same project opens in GreenLight Dash (the desktop editor this engine comes from) for full editing: the page's
251
251
  edit note offers **Open in GreenLight Dash** (it imports the folder as a new project on the open board; a page with
252
- changes saves a `.glvideo`). `npx greenlight-motion@0.2.4 pack <folder> --glvideo` writes that file yourself: ONE
252
+ changes saves a `.glvideo`). `npx greenlight-motion@0.3.1 pack <folder> --glvideo` writes that file yourself: ONE
253
253
  `.glvideo` (the project + its files) that opens in GreenLight Dash on a double-click, or dropped on its board. Hand it
254
254
  over when the user wants to keep editing in the app. A
255
255
  GreenLight Dash project comes the other way through the app's **Export for agents** — a ready folder like the one
256
- `init` makes, with the options the author ticked. `npx greenlight-motion@0.2.4 init <folder> --from <its project.json>`
256
+ `init` makes, with the options the author ticked. `npx greenlight-motion@0.3.1 init <folder> --from <its project.json>`
257
257
  starts from one too. Never tell the user they must install it: the page plays, changes options and renders on its own.
258
258
 
259
259
  ## Files
@@ -101,7 +101,7 @@ Some GLBs are authored facing away from the viewer — for those, set `baseRotat
101
101
  | `env.exposure` | `0.05–8` | `1` | Tone-mapping exposure of the model pass. |
102
102
  | `env.rotation` | `±360` deg | `0` | Spins the environment (moves reflections). |
103
103
  | `lights.key/fill/rim` | `0–10` each | `1 / 0.45 / 0.35` | The three directional lights' intensities. **Accepted, normalised on read** — see "Scene Rig" below. Still the right shape to emit when a project has no rig layer; ignored on every model once one exists. |
104
- | `animation.clip` | glTF animation name \| `"*"` \| `null` | `null` | Plays the named animation baked into the asset; `"*"` plays EVERY clip together, each on its own length (Blender's exporter writes one clip per animated object); `null` = static. Names must match the glTF exactly. `loop: "once"` holds the last frame. |
104
+ | `animation.clip` | glTF animation name \| `"*"` \| `null` | `null` | Plays the named animation baked into the asset; `"*"` plays EVERY clip together, each on its own length (Blender's exporter writes one clip per animated object); `null` = static. Names must match the glTF exactly. `loop: "once"` holds the last frame. A machine running or a device coming apart is made as such a GLB: video-mechanisms.md (GreenLight Dash only). |
105
105
  | `animation.speed` | `-8–8` | `1` | Playback rate (negative = reversed). |
106
106
  | `animation.loop` | `"once"` \| `"loop"` \| `"pingpong"` | `loop` | Loop mode. |
107
107
  | `animation.offset` | `±600` s | `0` | Start offset into the animation. |
@@ -91,12 +91,12 @@ An adjustment item processes every channel below it at its level. Inside the gro
91
91
  { "id": "plexus-glow-ch", "name": "Plexus glow", "visible": true, "unsnapped": true,
92
92
  "items": [{ "id": "plexus-glow", "clipId": "plexus-glow-clip", "freeStart": 0, "trimStart": 0, "trimEnd": 1.05,
93
93
  "effects": [{ "id": "glow", "eid": "plexus-glow-g", "enabled": true, "mix": 100,
94
- "params": { "intensity": 0.85, "threshold": 0.05, "radius": 13, "color": "#33EFAB" } }] }] }]
94
+ "params": { "exposure": 0.85, "glowThreshold": 5, "glowRadius": 60, "tintAmount": 100, "tintInner": "#33EFAB", "tintOuter": "#33EFAB" } }] }] }]
95
95
  }
96
96
  }
97
97
  ```
98
98
 
99
- One glow over the composite reads slightly differently from many. Per-layer glows add up wherever layers overlap; one glow over the composite does not. When converting an existing look, compare composited stills and raise `intensity` (or keyframe `fx:<eid>:intensity`) for the stretch where the layers lie on top of each other.
99
+ One glow over the composite reads slightly differently from many. Per-layer glows add up wherever layers overlap; one glow over the composite does not. When converting an existing look, compare composited stills and raise `exposure` (or keyframe `fx:<eid>:exposure`) for the stretch where the layers lie on top of each other.
100
100
 
101
101
  ## Storage contract
102
102
 
@@ -136,10 +136,9 @@ The chain:
136
136
  "enabled": true,
137
137
  "mix": 100,
138
138
  "params": {
139
- "intensity": 1.1,
140
- "threshold": 0.55,
141
- "radius": 26,
142
- "color": "#ffffff"
139
+ "glowRadius": 420,
140
+ "exposure": 1,
141
+ "glowThreshold": 72
143
142
  },
144
143
  "start": 0.5,
145
144
  "end": 2.75,
@@ -210,7 +209,9 @@ Presets (the panel's chips, all params + colours in one click): Drifting Fog, Ro
210
209
 
211
210
  #### Bloom
212
211
 
213
- `bloom` (**Bloom**, group Glow, both scopes) makes bright content leak light — a physically-shaped glow built on an octave pyramid rather than a blur kernel. `threshold` (0–1) with `knee` (soft shoulder) picks what counts as bright; `intensity` (0–600 %) scales the leak; `radius` (1–4) is **octaves of spread, not pixels** — 1 is a tight halo, 4 folds in a sixteenth-resolution octave whose halos span hundreds of px, and fractional values morph continuously. `saturation` desaturates or over-saturates the leaked light only, `tint` + `tintAmount` recolour it (the classic cold anamorphic look is a blue tint at ~60 %), and `blend` composites `0` Add / `1` Screen (protects already-bright frames from clipping) / `2` Lighten (max — halos never stack past the glow itself) / `3` Color Dodge (punchy filmic burn; falls back to Add over transparency so the outside halo survives) / `4` Bloom Only (just the leaked light, alpha from the bloom energy — for compositing the glow on its own). `anamorphic` (−100…100 %) smears the bloom into wide lens streaks — positive horizontal, negative vertical; magnitude sets streak length. `0` disables that pass entirely. It writes outside the silhouette by design; leave `clip` unset. On an adjustment item it blooms the whole below-stack — the usual "cinematic glow" move is an adjustment layer with `threshold` ~0.7 so only real highlights leak. Differs from `glow`: `glow` is a single-radius Gaussian with a colour; `bloom` is multi-scale, energy-conserving, and holds its shape at any radius.
212
+ `glow` (**Deep Glow**, group Glow, both scopes) is light with a physically shaped falloff: a bright core and an inverse-square tail, computed in linear light. `glowRadius` (10–2000 px at 1080p) is how far the light reaches; `exposure` (0–4) is how much of the source's light scatters (0 = the effect does nothing and costs nothing); `falloff` (1.3–3.5, `2` = inverse square) steepens or flattens the tail. What glows: `glowThreshold` (0–100 %) with `thresholdSmooth`, measured by `thresholdBy` `0` Brightness (any bright colour, saturated neon included) / `1` Luminance / `2` Everything (the whole layer glows; the usual choice on a transparent text or shape layer). Shape: `aspect` (0.25–16 ×, above 1 = wider) and `angle` (−90…90°, clockwise) make it an ellipse — `aspect` ~11 with a short `glowRadius` (~130) is an anamorphic streak. Colour: the light takes the source's colour; `tintAmount` (0–100 %) recolours it from `tintInner` at the core to `tintOuter` at the edge (`tintMode` `0` Colorize / `1` Multiply), so a glow in one colour is `tintAmount` 100 with both set to it; `saturation` (0–200 %). The keys `intensity`, `threshold`, `radius` and `color` are not read. `radiusRed` / `radiusGreen` / `radiusBlue` (0.3–2.5 ×) let one channel reach further than another (red wide, blue tight = a warm fringe) and `aberration` (0–100 %) splits it radially. Output: `tonemap` `2` Hot Core (default — the picture under the glow stays exact; over-bright colour turns white instead of clipping) / `0` Clamp / `1` Soft Clip / `3` Reinhard / `4` ACES Filmic / `5` Hable Filmic (the last three regrade the whole layer), `linearLight` `1`/`0`, `blend` `0` Add / `1` Screen, `dither` `1`/`0`, `quality` `1` Standard / `0` Draft (half-resolution core). It writes outside the silhouette by design; leave `clip` unset. Example: `{"id": "glow", "mix": 100, "params": {"glowRadius": 260, "exposure": 1.7, "glowThreshold": 35, "saturation": 125}}` (Neon Tube).
213
+
214
+ `bloom` (**Bloom**, group Glow, both scopes) makes bright content leak light — a physically-shaped glow built on an octave pyramid rather than a blur kernel. `threshold` (0–1) with `knee` (soft shoulder) picks what counts as bright; `intensity` (0–600 %) scales the leak; `radius` (1–4) is **octaves of spread, not pixels** — 1 is a tight halo, 4 folds in a sixteenth-resolution octave whose halos span hundreds of px, and fractional values morph continuously. `saturation` desaturates or over-saturates the leaked light only, `tint` + `tintAmount` recolour it (the classic cold anamorphic look is a blue tint at ~60 %), and `blend` composites `0` Add / `1` Screen (protects already-bright frames from clipping) / `2` Lighten (max — halos never stack past the glow itself) / `3` Color Dodge (punchy filmic burn; falls back to Add over transparency so the outside halo survives) / `4` Bloom Only (just the leaked light, alpha from the bloom energy — for compositing the glow on its own). `anamorphic` (−100…100 %) smears the bloom into wide lens streaks — positive horizontal, negative vertical; magnitude sets streak length. `0` disables that pass entirely. It writes outside the silhouette by design; leave `clip` unset. On an adjustment item it blooms the whole below-stack — the usual "cinematic glow" move is an adjustment layer with `threshold` ~0.7 so only real highlights leak. Differs from `glow` (Deep Glow, below): Bloom's spread stops at 4 octaves and blends in display space; Deep Glow reaches up to 2000 px with an inverse-square tail in linear light.
214
215
 
215
216
  #### Echo
216
217
 
@@ -282,7 +283,7 @@ It writes outside the silhouette by design; leave `clip` unset. Keyframable: `am
282
283
 
283
284
  **Light cone through a line (the AE "Light Text Reveal" port).** The AE rig is a 2–4 px line whose own layer carries CC Radial Fast Blur ×2, Glow ×4 and Tint, with the text layers using it as a LUMA track matte. Rebuild it as:
284
285
 
285
- 1. A `sequence` clip holding: the glow line (`shapeType: "line"`, `lineWidth` 4, `lineStroke.paint` `{mode: "gradient", colors: ["#ffffff", "#000000", "#000000"], span: "path"}` — AE's white→black gradient stroke, which becomes the yellow→green split after the tint), animated with the AE `translateX/Y`/`rotate` keys; an adjustment item with `radialFastBlur` twice — Center 1 = Glow Position + (0, Spread), `zoom` 1, `falloff` 98, `intensity` 1500, `mix` 40; Center 2 = Glow Position − (0, Spread), `zoom` 1, `falloff` 96, `intensity` 1000 — `space` 1 on both, `amount` = AE amount (80 + Light Distance, 80 + 2 × Light Distance); and a second adjustment item with AE's outer glows (`glow` 0.5 / threshold 0.71 / radius 80, `glow` 0.1 / threshold 0 / radius 54), the Tint as `curves` with two points per channel (black → Light Color 3, white → Light Color 2: `r [[0, 43/255], [1, 198/255]]`, `g [[0, 217/255], [1, 1]]`, `b [[0, 143/255], [1, 74/255]]`) and AE's comp Curves as a second `curves` (kept inside the cone: on top of everything it also dims the white line). An effect chain holds 4 entries, hence two adjustment items.
286
+ 1. A `sequence` clip holding: the glow line (`shapeType: "line"`, `lineWidth` 4, `lineStroke.paint` `{mode: "gradient", colors: ["#ffffff", "#000000", "#000000"], span: "path"}` — AE's white→black gradient stroke, which becomes the yellow→green split after the tint), animated with the AE `translateX/Y`/`rotate` keys; an adjustment item with `radialFastBlur` twice — Center 1 = Glow Position + (0, Spread), `zoom` 1, `falloff` 98, `intensity` 1500, `mix` 40; Center 2 = Glow Position − (0, Spread), `zoom` 1, `falloff` 96, `intensity` 1000 — `space` 1 on both, `amount` = AE amount (80 + Light Distance, 80 + 2 × Light Distance); and a second adjustment item with AE's outer glows as two `glow` entries (`exposure` 0.5 / `glowThreshold` 71 / `glowRadius` 240 and `exposure` 0.1 / `glowThreshold` 0 / `glowRadius` 160), the Tint as `curves` with two points per channel (black → Light Color 3, white → Light Color 2: `r [[0, 43/255], [1, 198/255]]`, `g [[0, 217/255], [1, 1]]`, `b [[0, 143/255], [1, 74/255]]`) and AE's comp Curves as a second `curves` (kept inside the cone: on top of everything it also dims the white line). An effect chain holds 4 entries, hence two adjustment items.
286
287
  2. Two items of that ONE sequence clip at the top level: one visible (the cone), one used only as the matte source (a matte source is hidden from output).
287
288
  3. The white line (2 px) on its own channel, and the text with `trackMatte: {sourceId: <the matte item>, mode: "luma"}`.
288
289
  Key the light on/off with the cone items' `opacity` plus `fx:<eid>:amount`, and raise `fx:<eid>:falloff` towards 99.8 as it goes off (CC's trail shortens with Amount; here the visible length is set by Falloff); key the light source with `fx:<eid>:centerX/centerY`. A ready rig: `tests/radial-fast-blur/build_light_rig.py`. CC's Standard mode keeps a thin line bright, which this effect's normalised Standard does not; Brightest + Falloff + Intensity is the measured match (see the report in `tests/radial-fast-blur/README.md`).
@@ -489,7 +490,7 @@ Geometry look controls: `objectNodes` — `shape` (0–7, `8` mixed), `size`, `w
489
490
  "eid": "title-glow",
490
491
  "enabled": true,
491
492
  "mix": 85,
492
- "params": { "intensity": 1.2, "threshold": 0.5, "radius": 24, "color": "#69e7ff" },
493
+ "params": { "glowRadius": 240, "exposure": 1.2, "glowThreshold": 50, "tintAmount": 100, "tintInner": "#69e7ff", "tintOuter": "#69e7ff" },
493
494
  "clip": false
494
495
  }
495
496
  ]
@@ -541,9 +542,9 @@ Overlay Effects use `fx:<eid>:<parameter>` tracks:
541
542
  { "position": 0, "value": "0", "easing": "AE Smooth" },
542
543
  { "position": 25, "value": "100", "easing": "AE Smooth" }
543
544
  ],
544
- "fx:title-glow:radius": [
545
- { "position": 0, "value": "8", "easing": "Smooth" },
546
- { "position": 100, "value": "44", "easing": "Linear" }
545
+ "fx:title-glow:glowRadius": [
546
+ { "position": 0, "value": "80", "easing": "Smooth" },
547
+ { "position": 100, "value": "440", "easing": "Linear" }
547
548
  ]
548
549
  }
549
550
  }
@@ -25,6 +25,7 @@
25
25
  | HTML pages as timeline layers (html clips) and their bakes | video-html-clips.md (GreenLight Dash only) |
26
26
  | Overlay Effects and Layer Effects, including Running Glow and Depth | [video-effects.md](video-effects.md) |
27
27
  | 3D models, Scene Rig, lighting and shadow plates | [video-3d.md](video-3d.md) |
28
+ | Mechanisms and teardowns: a working machine or an exploded device as a 3D layer | video-mechanisms.md (GreenLight Dash only) |
28
29
  | Camera layer, Camera Rig, camera paths and presets | [video-camera.md](video-camera.md) |
29
30
  | Particles, packing, proximity, fluid and smoke | [video-particles.md](video-particles.md) |
30
31
  | Writing motion tracks, roto masks or solved cameras | tracking-data.md (GreenLight Dash only) |
@@ -247,7 +247,7 @@ Rules the sanitizer enforces (anything else is dropped or clamped on load): `aid
247
247
  | `gradient` | `colors` (2–6 hex), `angle` 0°, `span` `text`\|`unit`, `shift` 0 %, `repeat` false, `mix` 100 % | paints the unit with the gradient (across the whole text or each unit); `shift` slides the colours, `repeat` lets them loop |
248
248
  | `hue` | `hue` 180°, `saturation` 0, `brightness` 0 % | rotates whatever colour the unit has at that point |
249
249
  | `stroke` | `color` `#ffffff`, `width` 4 px, `outline` false | outline around the glyphs; `outline: true` fades the fill out |
250
- | `glow` | `color` `#5ef2ff`, `size` 30 px, `strength` 120 % | soft light around the glyphs |
250
+ | `glow` | `color` `#5ef2ff`, `size` 30 px, `strength` 120 % | light around the glyphs (Deep Glow): a hot core and an inverse-square tail reaching about 5 × `size`; units with the same `size` share one glow, at most three sizes per layer |
251
251
  | `shadow` | `color` `#000000`, `x` 0, `y` 18, `blur` 20 px, `opacity` 70 % | offset shadow; only when the user asks for a text shadow |
252
252
  | `blur` | `amount` 18 px | defocus |
253
253
  | `box` | `color` `#33efab`, `behind` `selected`\|`revealed`, `shape` `line`\|`unit`\|`block`, `padX` 12, `padY` 4, `radius` 10 px, `opacity` 100 %, `grow` true, `withText` false | `line`: one bar behind each run of selected units in a row; `unit`: a bar behind each selected unit of `basedOn` (a whole word even when drawn by letters), as bright as its amount; `block`: one shape around all of it. `behind: revealed` = behind what this animator lets through (a typing animator grows its box). `grow` makes a moving span sweep it like a marker. `withText` (`unit` only): each bar is as visible as its unit — every animator's opacity included — so a word that has not appeared yet has no bar |