@shotstack/cli 0.3.2 → 0.5.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.
@@ -0,0 +1,64 @@
1
+ # Positioning & coordinates
2
+
3
+ How `position`, `offset`, `width`/`height`, `scale`, and the transform fields place a clip in the frame. `shared/agent-core.md` carries the one-paragraph summary; this is the full reference.
4
+
5
+ ## The coordinate model
6
+
7
+ `position` picks one of nine **anchor points** in the frame; `offset` then nudges the clip from that anchor. **`offset` is a fraction of the output frame — not pixels, and not a centred −1..+1 grid:**
8
+
9
+ - `offset.x` positive → **right** (a fraction of frame width); `offset.y` positive → **up** (a fraction of frame height). Note `y` is *up*-positive, the opposite of typical screen coordinates.
10
+ - `position:"center"` with `offset:{ "x":0, "y":0 }` sits dead centre. `offset:{ "x":0.5 }` moves half a frame-width right; `offset:{ "x":-1 }` moves a full frame-width left — off-screen.
11
+ - The field accepts ±10; anything past ±1 already moves the clip partly or fully out of frame (no error).
12
+
13
+ ## Anchor points
14
+
15
+ `position` pins the clip's centre to the named point; `offset` shifts from there.
16
+
17
+ | | left edge | centre | right edge |
18
+ |---|---|---|---|
19
+ | **top edge** | `topLeft` | `top` | `topRight` |
20
+ | **middle** | `left` | `center` *(default)* | `right` |
21
+ | **bottom edge** | `bottomLeft` | `bottom` | `bottomRight` |
22
+
23
+ Example: `position:"topLeft"`, `offset:{ "x":0.05, "y":-0.05 }` → a 5% margin in from the top-left corner.
24
+
25
+ ## Offset in numbers
26
+
27
+ On a 1920×1080 frame: `offset.x:0.1` → 192 px right; `offset.y:0.1` → 108 px up; `offset.x:-0.5` → 960 px left (half the frame). Because the shift scales with the frame, the same `offset` looks the same at any resolution.
28
+
29
+ ## Sizing & fit (image / video)
30
+
31
+ Give a clip a `width`/`height` (pixels) to define a box; `fit` decides how the media fills it:
32
+
33
+ | `fit` | behaviour |
34
+ |---|---|
35
+ | `crop` *(default)* | fill the box, keep aspect ratio, crop the overflow |
36
+ | `contain` | fit entirely inside the box, keep aspect ratio, letterbox the gaps |
37
+ | `cover` | stretch to the box exactly — **distorts** if the aspect ratio differs |
38
+ | `none` | no scaling; crop to the box |
39
+
40
+ `scale` then multiplies the result (`1` = the fit result, `0.5` = half). `scale` is uniform on both axes — for a deliberate non-uniform stretch, use `fit:"cover"` with a `width`/`height`.
41
+
42
+ ## Sizing text
43
+
44
+ Give a `rich-text` clip a `width`/`height` to set its text box: text wraps to that width, and `align` (`horizontal`: `left`/`center`/`right`; `vertical`: `top`/`middle`/`bottom`) positions the text inside it. **Without a `width`/`height`, the box defaults to the whole frame** — so `align` centres the text across the entire output and `position`/`offset` then move that full-frame block, which is rarely what you intend. Set `width`/`height` on any text you want placed precisely.
45
+
46
+ ## Transforms
47
+
48
+ - `scale` — uniform multiplier (above).
49
+ - `transform.rotate.angle` — degrees clockwise; rotates around the clip's own centre, so it spins in place wherever you positioned it.
50
+ - `transform.skew.x` / `.y` — shear.
51
+ - `transform.flip.horizontal` / `.vertical` — mirror.
52
+ - `opacity` — `0`–`1`.
53
+
54
+ ## Order of operations
55
+
56
+ `fit` (scale media into the box) → `position` (anchor) → `offset` (nudge) → `rotate` / `skew` → `scale`. Worth remembering when a result surprises you: scaling is applied last, around the positioned anchor.
57
+
58
+ ## Common mistakes
59
+
60
+ 1. **`offset.y` sign.** Positive `offset.y` moves **up**; use a negative value to move down.
61
+ 2. **Expecting a centred −1..+1 grid.** There isn't one — `offset` is a fraction of the frame measured from the `position` anchor. `offset.x:-1` is a whole frame-width left, not "the left edge".
62
+ 3. **`fit:"cover"` distorts.** It stretches to the box. Use `fit:"crop"` to fill while keeping aspect ratio.
63
+ 4. **Unsized text.** A `rich-text` with no `width`/`height` fills the frame; set them to place text precisely.
64
+ 5. **Offsets off-screen.** Past ±1 the clip leaves the frame silently — no error.
@@ -1,6 +1,6 @@
1
1
  # Troubleshooting
2
2
 
3
- Common errors and the fix for each. If your error isn't here, run `shotstack feedback` to file a pre-filled GitHub issue with the render UUID attached — engineers can find server-side state in seconds.
3
+ Common errors and the fix for each. **Catch most of them before rendering:** `shotstack validate <file>` checks an Edit against the schema and flags same-track overlaps, unloaded fonts and non-public URLs offline — no API key, no credits. If your error isn't here, run `shotstack feedback` to file a pre-filled GitHub issue with the render UUID attached — engineers can find server-side state in seconds.
4
4
 
5
5
  ## Contents
6
6
 
@@ -9,6 +9,7 @@ Common errors and the fix for each. If your error isn't here, run `shotstack fee
9
9
  - Video looks stretched / squished after rendering
10
10
  - "Font not found"
11
11
  - Captions cover the whole frame
12
+ - Clips flicker / "clips overlap" on one track
12
13
  - Timeline renders but layers are wrong
13
14
  - "Invalid asset URL"
14
15
  - "Render failed" with no other detail
@@ -63,6 +64,12 @@ A `rich-caption` clip without `width`, `height`, and `fit: "none"` defaults to f
63
64
 
64
65
  **Fix:** use one of the five named presets in `references/caption.md` (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) which include the right dimensions, or set `width`/`height`/`fit: "none"` explicitly on your clip.
65
66
 
67
+ ## Clips flicker / "clips overlap" on one track
68
+
69
+ Two clips on the **same track** have overlapping `start`/`length` ranges, so the engine can't decide which to show — they flicker. This is the most common structural mistake when several elements appear at once (e.g. a title, a price and a button on an end card all at `start: 8`).
70
+
71
+ **Fix:** put anything visible at the same time on its **own track**. Sequential clips (one ends, the next begins — chain them with `"start": "auto"`) can share a track. `shotstack validate <file>` pinpoints the offending track and clip indices offline. See `shared/agent-core.md` → "Don't overlap clips on the same track" for a before/after.
72
+
66
73
  ## Timeline renders but layers are wrong
67
74
 
68
75
  You assumed `tracks[0]` was the bottom layer.