@clipkit/patterns 1.0.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/LICENSE +201 -0
- package/README.md +84 -0
- package/dist/anchor-default.d.ts +4 -0
- package/dist/anchor-default.d.ts.map +1 -0
- package/dist/anchor-default.js +34 -0
- package/dist/anchor-default.js.map +1 -0
- package/dist/bar-chart-row.d.ts +43 -0
- package/dist/bar-chart-row.d.ts.map +1 -0
- package/dist/bar-chart-row.js +143 -0
- package/dist/bar-chart-row.js.map +1 -0
- package/dist/beat-sync.d.ts +101 -0
- package/dist/beat-sync.d.ts.map +1 -0
- package/dist/beat-sync.js +145 -0
- package/dist/beat-sync.js.map +1 -0
- package/dist/camera-orbit.d.ts +22 -0
- package/dist/camera-orbit.d.ts.map +1 -0
- package/dist/camera-orbit.js +32 -0
- package/dist/camera-orbit.js.map +1 -0
- package/dist/cta-outro.d.ts +18 -0
- package/dist/cta-outro.d.ts.map +1 -0
- package/dist/cta-outro.js +44 -0
- package/dist/cta-outro.js.map +1 -0
- package/dist/data-scenes.d.ts +66 -0
- package/dist/data-scenes.d.ts.map +1 -0
- package/dist/data-scenes.js +188 -0
- package/dist/data-scenes.js.map +1 -0
- package/dist/flow-line.d.ts +27 -0
- package/dist/flow-line.d.ts.map +1 -0
- package/dist/flow-line.js +53 -0
- package/dist/flow-line.js.map +1 -0
- package/dist/glass-panel.d.ts +24 -0
- package/dist/glass-panel.d.ts.map +1 -0
- package/dist/glass-panel.js +32 -0
- package/dist/glass-panel.js.map +1 -0
- package/dist/header-bar.d.ts +36 -0
- package/dist/header-bar.d.ts.map +1 -0
- package/dist/header-bar.js +108 -0
- package/dist/header-bar.js.map +1 -0
- package/dist/hero-reveal.d.ts +17 -0
- package/dist/hero-reveal.d.ts.map +1 -0
- package/dist/hero-reveal.js +47 -0
- package/dist/hero-reveal.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/intro-card.d.ts +23 -0
- package/dist/intro-card.d.ts.map +1 -0
- package/dist/intro-card.js +123 -0
- package/dist/intro-card.js.map +1 -0
- package/dist/kinetic-headline.d.ts +18 -0
- package/dist/kinetic-headline.d.ts.map +1 -0
- package/dist/kinetic-headline.js +39 -0
- package/dist/kinetic-headline.js.map +1 -0
- package/dist/layers.d.ts +13 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +19 -0
- package/dist/layers.js.map +1 -0
- package/dist/liquid-morph.d.ts +62 -0
- package/dist/liquid-morph.d.ts.map +1 -0
- package/dist/liquid-morph.js +113 -0
- package/dist/liquid-morph.js.map +1 -0
- package/dist/lit-surface.d.ts +38 -0
- package/dist/lit-surface.d.ts.map +1 -0
- package/dist/lit-surface.js +63 -0
- package/dist/lit-surface.js.map +1 -0
- package/dist/lower-third.d.ts +26 -0
- package/dist/lower-third.d.ts.map +1 -0
- package/dist/lower-third.js +101 -0
- package/dist/lower-third.js.map +1 -0
- package/dist/morph-shape.d.ts +42 -0
- package/dist/morph-shape.d.ts.map +1 -0
- package/dist/morph-shape.js +57 -0
- package/dist/morph-shape.js.map +1 -0
- package/dist/pie-card.d.ts +35 -0
- package/dist/pie-card.d.ts.map +1 -0
- package/dist/pie-card.js +168 -0
- package/dist/pie-card.js.map +1 -0
- package/dist/promo.d.ts +38 -0
- package/dist/promo.d.ts.map +1 -0
- package/dist/promo.js +61 -0
- package/dist/promo.js.map +1 -0
- package/dist/ranked-list.d.ts +38 -0
- package/dist/ranked-list.d.ts.map +1 -0
- package/dist/ranked-list.js +130 -0
- package/dist/ranked-list.js.map +1 -0
- package/dist/stat-block.d.ts +26 -0
- package/dist/stat-block.d.ts.map +1 -0
- package/dist/stat-block.js +92 -0
- package/dist/stat-block.js.map +1 -0
- package/dist/theme.d.ts +36 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +75 -0
- package/dist/theme.js.map +1 -0
- package/dist/tilted-showcase.d.ts +29 -0
- package/dist/tilted-showcase.d.ts.map +1 -0
- package/dist/tilted-showcase.js +106 -0
- package/dist/tilted-showcase.js.map +1 -0
- package/dist/trend-pill.d.ts +33 -0
- package/dist/trend-pill.d.ts.map +1 -0
- package/dist/trend-pill.js +83 -0
- package/dist/trend-pill.js.map +1 -0
- package/dist/zoom-rig.d.ts +27 -0
- package/dist/zoom-rig.d.ts.map +1 -0
- package/dist/zoom-rig.js +46 -0
- package/dist/zoom-rig.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// beat-sync — turn a BeatMap into motion.
|
|
2
|
+
//
|
|
3
|
+
// This is the MAPPING layer. @clipkit/music-analysis produces the facts (where
|
|
4
|
+
// the beats are); these helpers turn them into ordinary keyframes / pure
|
|
5
|
+
// expressions that drop onto any element. Nothing here reaches the runtime as a
|
|
6
|
+
// new concept — the output is plain protocol data, so renders stay deterministic
|
|
7
|
+
// with no audio dependency. (The agent supplies the taste: WHICH element gets
|
|
8
|
+
// WHICH accent.)
|
|
9
|
+
//
|
|
10
|
+
// Two tiers, matching the architecture:
|
|
11
|
+
// • pulseToTempo — Tier 1: a pure expression that breathes on the beat from
|
|
12
|
+
// just bpm + phase. Cheap, continuous, no per-beat data.
|
|
13
|
+
// • accentOnBeats — Tier 2: keyframes that punch a property on each detected
|
|
14
|
+
// beat (or downbeat), with anticipation and settle.
|
|
15
|
+
const round = (n) => Math.round(n * 1000) / 1000;
|
|
16
|
+
/**
|
|
17
|
+
* A pure Tier-A expression that pulses on the beat — a sharp rise exactly on
|
|
18
|
+
* each beat that decays before the next. Needs only `bpm` + `phase`, so it works
|
|
19
|
+
* off a synthesized {@link beatGrid} as happily as a detected map. Drop the
|
|
20
|
+
* result on any numeric property (`scale`, `opacity`, `blur_radius`, …):
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* { ...logo, scale: pulseToTempo(map, { amp: 0.06 }) }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function pulseToTempo(map, opts = {}) {
|
|
27
|
+
const baseline = opts.baseline ?? 1;
|
|
28
|
+
const amp = opts.amp ?? 0.08;
|
|
29
|
+
const decay = opts.decay ?? 6;
|
|
30
|
+
const rate = round((map.bpm / 60) * (opts.subdivision ?? 1)); // pulses/sec
|
|
31
|
+
const phase = round(map.phase);
|
|
32
|
+
// fract((t - phase)·rate) is the saw 0→1 across each pulse; exp(-decay·saw)
|
|
33
|
+
// is 1 at the beat, decaying after → a percussive pump.
|
|
34
|
+
return {
|
|
35
|
+
expr: `${round(baseline)} + ${round(amp)}*exp(-${round(decay)}*fract((t-${phase})*${rate}))`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Keyframes that punch a property on each beat — the discrete "hit" sync. Each
|
|
40
|
+
* marker gets an anticipation keyframe, a peak ON the beat (scaled by the
|
|
41
|
+
* marker's strength so downbeats land bigger), and a settle back to rest.
|
|
42
|
+
*
|
|
43
|
+
* Returns one {@link KeyframeAnimation}; push it onto an element's
|
|
44
|
+
* `keyframe_animations`. Times are in the element's local seconds — put the
|
|
45
|
+
* accented element at `time: 0` so they line up with the beat map's clock.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* { ...title, keyframe_animations: [accentOnBeats(map, { on: 'downbeats', amp: 0.22 })] }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function accentOnBeats(map, opts = {}) {
|
|
52
|
+
const property = opts.property ?? 'scale';
|
|
53
|
+
const base = opts.base ?? 1;
|
|
54
|
+
const amp = opts.amp ?? 0.18;
|
|
55
|
+
const easing = opts.easing ?? 'ease-out-cubic';
|
|
56
|
+
const minStrength = opts.minStrength ?? 0;
|
|
57
|
+
const markers = opts.on === 'downbeats' ? map.downbeats : map.beats;
|
|
58
|
+
// Keep the rise + settle inside one beat so adjacent accents never collide.
|
|
59
|
+
const interval = map.bpm > 0 ? 60 / map.bpm : Infinity;
|
|
60
|
+
const attack = Math.min(opts.attack ?? 0.05, interval * 0.3);
|
|
61
|
+
const settle = Math.min(opts.settle ?? 0.2, interval * 0.6);
|
|
62
|
+
const keyframes = [];
|
|
63
|
+
let lastTime = -Infinity;
|
|
64
|
+
// Push only if it keeps times strictly increasing and non-negative, so the
|
|
65
|
+
// sequence stays monotonic even for a beat sitting exactly at t=0.
|
|
66
|
+
const push = (time, value) => {
|
|
67
|
+
const t = round(time);
|
|
68
|
+
if (t < 0 || t <= lastTime)
|
|
69
|
+
return;
|
|
70
|
+
keyframes.push({ time: t, value: round(value), easing });
|
|
71
|
+
lastTime = t;
|
|
72
|
+
};
|
|
73
|
+
for (const m of markers) {
|
|
74
|
+
if (m.strength < minStrength)
|
|
75
|
+
continue;
|
|
76
|
+
// Anticipation seat at rest just before the hit (keeps the value flat
|
|
77
|
+
// between beats instead of ramping up across the whole gap), then the peak
|
|
78
|
+
// ON the beat, then the settle back to rest.
|
|
79
|
+
push(m.time - attack, base);
|
|
80
|
+
push(m.time, base + amp * m.strength);
|
|
81
|
+
push(m.time + settle, base);
|
|
82
|
+
}
|
|
83
|
+
// Seed a resting keyframe at t=0 so the value holds at `base` before the
|
|
84
|
+
// first hit (unless a beat already owns t=0).
|
|
85
|
+
if (keyframes.length === 0 || keyframes[0].time !== 0) {
|
|
86
|
+
keyframes.unshift({ time: 0, value: round(base), easing });
|
|
87
|
+
}
|
|
88
|
+
return { property, keyframes };
|
|
89
|
+
}
|
|
90
|
+
// ── Tier 2 (transitions): land MOTION EVENTS on the beat ─────────────────────
|
|
91
|
+
// This is the heart of "hit-syncing": entrances, exits, and screen-to-screen
|
|
92
|
+
// cuts whose moment of impact lands ON a beat. Unlike pulseToTempo (continuous,
|
|
93
|
+
// for music-visualizer pulsing), these sync the EVENTS a piece already needs —
|
|
94
|
+
// a logo arriving, a list ticking in, a screen changing — and otherwise leave
|
|
95
|
+
// the element still. They return plain {expr} / numbers (protocol values), so
|
|
96
|
+
// they drop straight onto an element's opacity / x / y.
|
|
97
|
+
/** Snap a time (seconds) to the nearest beat — or downbeat — in the map, so an
|
|
98
|
+
* authored moment locks to the grid instead of drifting near it. */
|
|
99
|
+
export function snapToBeat(map, t, which = 'beat') {
|
|
100
|
+
const markers = which === 'downbeat' ? map.downbeats : map.beats;
|
|
101
|
+
let best = t;
|
|
102
|
+
let bestD = Infinity;
|
|
103
|
+
for (const m of markers) {
|
|
104
|
+
const d = Math.abs(t - m.time);
|
|
105
|
+
if (d < bestD) {
|
|
106
|
+
best = m.time;
|
|
107
|
+
bestD = d;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return best;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Opacity {expr} that is fully present ON beat `enter` and (optionally) fully
|
|
114
|
+
* CLEARED by beat `exit` — both edges land on a beat. On a shared boundary the
|
|
115
|
+
* old screen is gone exactly as the new one arrives: a clean cut, not a muddy
|
|
116
|
+
* overlap. Pair with {@link slideOnBeat} for a slide arriving on the same beat.
|
|
117
|
+
*/
|
|
118
|
+
export function revealOnBeat(enter, opts = {}) {
|
|
119
|
+
const fi = opts.fadeIn ?? 0.28;
|
|
120
|
+
const inExpr = `linear(t,${round(enter - fi)},${round(enter)},0,1)`;
|
|
121
|
+
if (opts.exit == null)
|
|
122
|
+
return { expr: inExpr };
|
|
123
|
+
const fo = opts.fadeOut ?? 0.28;
|
|
124
|
+
return { expr: `(${inExpr} - linear(t,${round(opts.exit - fo)},${round(opts.exit)},0,1))` };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A coordinate {expr} for a slide that ARRIVES at `target` px on beat `enter`
|
|
128
|
+
* (coming from `target + from`), and optionally pushes back out so it has fully
|
|
129
|
+
* left BY beat `exit`. Use directly as an element's `x` or `y`. The arrival/
|
|
130
|
+
* departure — not a wobble — is the sync, so it reads on the beat without
|
|
131
|
+
* distracting while the element rests.
|
|
132
|
+
*/
|
|
133
|
+
export function slideOnBeat(target, enter, opts = {}) {
|
|
134
|
+
const from = opts.from ?? 60;
|
|
135
|
+
const dur = opts.dur ?? 0.45;
|
|
136
|
+
let expr = `${round(target)} + ${round(from)}*(1 - ease(t,${round(enter - dur)},${round(enter)},0,1))`;
|
|
137
|
+
if (opts.exit != null) {
|
|
138
|
+
const exitTo = opts.exitTo ?? from;
|
|
139
|
+
const exitDur = opts.exitDur ?? 0.4;
|
|
140
|
+
// push completes BY the exit beat (window ends on it) — leaves on the beat
|
|
141
|
+
expr += ` + ${round(exitTo)}*ease(t,${round(opts.exit - exitDur)},${round(opts.exit)},0,1)`;
|
|
142
|
+
}
|
|
143
|
+
return { expr };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=beat-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beat-sync.js","sourceRoot":"","sources":["../src/beat-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Camera } from '@clipkit/protocol';
|
|
2
|
+
export interface CameraOrbitProps {
|
|
3
|
+
/** Focal distance in px; smaller = stronger perspective. Default 1500. */
|
|
4
|
+
perspective?: number;
|
|
5
|
+
/** Yaw sweep: y_rotation runs from −yaw to +yaw degrees. Default 40. */
|
|
6
|
+
yaw?: number;
|
|
7
|
+
/** Constant downward tilt (x_rotation degrees) held through the move. Default 0. */
|
|
8
|
+
pitch?: number;
|
|
9
|
+
/** Dolly: z runs 0 → dolly px (+ = toward the viewer). Default 0. */
|
|
10
|
+
dolly?: number;
|
|
11
|
+
/** Truck: x runs 0 → truck px. Default 0. */
|
|
12
|
+
truck?: number;
|
|
13
|
+
/** Move length in seconds (the keyframe span). */
|
|
14
|
+
duration: number;
|
|
15
|
+
/** Ease the sweep in/out. Default true. */
|
|
16
|
+
ease?: boolean;
|
|
17
|
+
/** Projection origin (vanishing point). Defaults to canvas center. */
|
|
18
|
+
origin_x?: number | string;
|
|
19
|
+
origin_y?: number | string;
|
|
20
|
+
}
|
|
21
|
+
export declare function cameraOrbit(props: CameraOrbitProps): Camera;
|
|
22
|
+
//# sourceMappingURL=camera-orbit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-orbit.d.ts","sourceRoot":"","sources":["../src/camera-orbit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAQD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAa3D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// cameraOrbit — a ready-made scene camera move (CKP/1.0). Unlike the
|
|
2
|
+
// other patterns (which return an Element), this returns a `Camera` for
|
|
3
|
+
// `source.camera`: a keyframed pose that sweeps the viewpoint — orbit
|
|
4
|
+
// (yaw), tilt (pitch), dolly (z), truck (x) — over the composition.
|
|
5
|
+
// Pair it with content at varied `z` for parallax, depth-correct
|
|
6
|
+
// occlusion handles itself (§4.4.3).
|
|
7
|
+
function ramp(from, to, duration, easing) {
|
|
8
|
+
const end = { time: Math.max(0.1, duration), value: to };
|
|
9
|
+
if (easing)
|
|
10
|
+
end.easing = easing;
|
|
11
|
+
return [{ time: 0, value: from }, end];
|
|
12
|
+
}
|
|
13
|
+
export function cameraOrbit(props) {
|
|
14
|
+
const { duration } = props;
|
|
15
|
+
const easing = (props.ease ?? true) ? 'ease-in-out' : undefined;
|
|
16
|
+
const yaw = props.yaw ?? 40;
|
|
17
|
+
const cam = { perspective: props.perspective ?? 1500 };
|
|
18
|
+
if (props.origin_x !== undefined)
|
|
19
|
+
cam.origin_x = props.origin_x;
|
|
20
|
+
if (props.origin_y !== undefined)
|
|
21
|
+
cam.origin_y = props.origin_y;
|
|
22
|
+
if (yaw)
|
|
23
|
+
cam.y_rotation = ramp(-yaw, yaw, duration, easing);
|
|
24
|
+
if (props.pitch)
|
|
25
|
+
cam.x_rotation = props.pitch; // constant tilt
|
|
26
|
+
if (props.dolly)
|
|
27
|
+
cam.z = ramp(0, props.dolly, duration, easing);
|
|
28
|
+
if (props.truck)
|
|
29
|
+
cam.x = ramp(0, props.truck, duration, easing);
|
|
30
|
+
return cam;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=camera-orbit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-orbit.js","sourceRoot":"","sources":["../src/camera-orbit.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wEAAwE;AACxE,sEAAsE;AACtE,oEAAoE;AACpE,iEAAiE;AACjE,qCAAqC;AAwBrC,SAAS,IAAI,CAAC,IAAY,EAAE,EAAU,EAAE,QAAgB,EAAE,MAAe;IACvE,MAAM,GAAG,GAAa,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,EAAc,CAAC;IAC/E,IAAI,MAAM;QAAG,GAA2B,CAAC,MAAM,GAAG,MAAM,CAAC;IACzD,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAc,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;IAE5B,MAAM,GAAG,GAAW,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;IAC/D,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChE,IAAI,GAAG;QAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,gBAAgB;IAC/D,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChE,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Element } from '@clipkit/protocol';
|
|
2
|
+
import { type ColorName, type ThemeName } from './theme.js';
|
|
3
|
+
export interface CtaOutroProps {
|
|
4
|
+
id: string;
|
|
5
|
+
wordmark: string;
|
|
6
|
+
tagline?: string;
|
|
7
|
+
/** Button label, e.g. "Start free". */
|
|
8
|
+
cta: string;
|
|
9
|
+
color: ColorName;
|
|
10
|
+
theme?: ThemeName;
|
|
11
|
+
canvasWidth: number;
|
|
12
|
+
canvasHeight: number;
|
|
13
|
+
time: number;
|
|
14
|
+
duration: number;
|
|
15
|
+
layer: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function ctaOutro(props: CtaOutroProps): Element;
|
|
18
|
+
//# sourceMappingURL=cta-outro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cta-outro.d.ts","sourceRoot":"","sources":["../src/cta-outro.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAwB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CA0CtD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ctaOutro — closing card: serif wordmark, tagline, and a glass CTA pill.
|
|
2
|
+
//
|
|
3
|
+
// COMPONENT pattern: returns ONE plain `group`.
|
|
4
|
+
import { assignLayers } from './layers.js';
|
|
5
|
+
import { getFonts, getPalette } from './theme.js';
|
|
6
|
+
export function ctaOutro(props) {
|
|
7
|
+
const { id, wordmark, tagline, cta, color, canvasWidth: W, canvasHeight: H, time, duration, layer } = props;
|
|
8
|
+
const theme = props.theme ?? 'cinematic';
|
|
9
|
+
const palette = getPalette(theme, color);
|
|
10
|
+
const fonts = getFonts(theme);
|
|
11
|
+
const cx = W / 2, cy = H / 2;
|
|
12
|
+
const btnW = 220, btnH = 62;
|
|
13
|
+
const children = [
|
|
14
|
+
{
|
|
15
|
+
id: `${id}-wordmark`, type: 'text', text: wordmark, x: cx, y: cy - 60, x_anchor: '50%', y_anchor: '50%',
|
|
16
|
+
font_family: fonts.display, font_size: 88, font_weight: '700', letter_spacing: 8, fill_color: palette.text,
|
|
17
|
+
animations: [{ type: 'scale-in', duration: 1.0, easing: 'ease-out' }, { type: 'fade-in', duration: 0.6 }],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
if (tagline) {
|
|
21
|
+
children.push({
|
|
22
|
+
id: `${id}-tagline`, type: 'text', text: tagline, x: cx, y: cy + 6, x_anchor: '50%', y_anchor: '50%', time: 0.3,
|
|
23
|
+
font_family: fonts.sans, font_size: 24, letter_spacing: 2, fill_color: palette.textMuted,
|
|
24
|
+
animations: [{ type: 'fade-in', duration: 0.6 }],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// glass CTA pill (refracts the dark backdrop) + label
|
|
28
|
+
children.push({
|
|
29
|
+
id: `${id}-btn`, type: 'shape', shape: 'rectangle', x: cx, y: cy + 84, x_anchor: '50%', y_anchor: '50%', width: btnW, height: btnH, border_radius: btnH / 2,
|
|
30
|
+
fill_color: '#ffffff', time: 0.6,
|
|
31
|
+
effects: [{ type: 'glass', blur_radius: 6, refraction: 14, edge_highlight: 1, tint: palette.accent }],
|
|
32
|
+
animations: [{ type: 'scale-in', duration: 0.5, easing: 'ease-out-back' }, { type: 'fade-in', duration: 0.4 }],
|
|
33
|
+
}, {
|
|
34
|
+
id: `${id}-btn-label`, type: 'text', text: cta, x: cx, y: cy + 84, x_anchor: '50%', y_anchor: '50%', time: 0.75,
|
|
35
|
+
font_family: fonts.sans, font_size: 22, font_weight: '700', fill_color: palette.text,
|
|
36
|
+
animations: [{ type: 'fade-in', duration: 0.4 }],
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
id, type: 'group', layer, time, duration, x: 0, y: 0, width: W, height: H,
|
|
40
|
+
animations: [{ type: 'fade-out', time: 'end', duration: 0.5 }],
|
|
41
|
+
elements: assignLayers(children),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=cta-outro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cta-outro.js","sourceRoot":"","sources":["../src/cta-outro.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Element } from '@clipkit/protocol';
|
|
2
|
+
import { type RankedListItem } from './ranked-list.js';
|
|
3
|
+
import type { ColorName, ThemeName } from './theme.js';
|
|
4
|
+
interface SceneBase {
|
|
5
|
+
/** Id prefix for every produced element. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Accent / body color slot. */
|
|
8
|
+
color: ColorName;
|
|
9
|
+
theme?: ThemeName;
|
|
10
|
+
canvasWidth: number;
|
|
11
|
+
canvasHeight: number;
|
|
12
|
+
time: number;
|
|
13
|
+
duration: number;
|
|
14
|
+
layer: number;
|
|
15
|
+
/** Header title (e.g. "Top 10 videos"). */
|
|
16
|
+
title?: string;
|
|
17
|
+
/** Optional right-aligned date range in the header. */
|
|
18
|
+
dateRange?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface StatItem {
|
|
21
|
+
label: string;
|
|
22
|
+
/** Counts 0 → this over ~1s. */
|
|
23
|
+
current: number;
|
|
24
|
+
/** Previous-period value; if set, a trend pill is shown. */
|
|
25
|
+
previous?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface StatsSceneProps extends SceneBase {
|
|
28
|
+
/** 1–4 hero stats, laid out in a centered 1- or 2-column grid. */
|
|
29
|
+
stats: StatItem[];
|
|
30
|
+
}
|
|
31
|
+
/** Hero-stat scene: headerBar + a centered grid of spring-counted statBlocks. */
|
|
32
|
+
export declare function statsScene(props: StatsSceneProps): Element;
|
|
33
|
+
export interface BarItem {
|
|
34
|
+
label: string;
|
|
35
|
+
value: number;
|
|
36
|
+
previous?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface BarsSceneProps extends SceneBase {
|
|
39
|
+
/** 1–6 rows; bar widths normalize to the largest value. */
|
|
40
|
+
bars: BarItem[];
|
|
41
|
+
}
|
|
42
|
+
/** Bar-chart scene: headerBar + a centered vertical stack of barChartRows. */
|
|
43
|
+
export declare function barsScene(props: BarsSceneProps): Element;
|
|
44
|
+
export interface RankingSceneProps extends SceneBase {
|
|
45
|
+
/** Ranked entries; 1 column up to 6, then 2 columns. */
|
|
46
|
+
items: RankedListItem[];
|
|
47
|
+
}
|
|
48
|
+
/** Ranked-list scene: headerBar + a centered rankedList (auto 1/2 columns). */
|
|
49
|
+
export declare function rankingScene(props: RankingSceneProps): Element;
|
|
50
|
+
export interface PieItem {
|
|
51
|
+
label: string;
|
|
52
|
+
value: number;
|
|
53
|
+
/** Total the value is a share of (drives the displayed percentage). */
|
|
54
|
+
total: number;
|
|
55
|
+
previous?: number;
|
|
56
|
+
/** Optional logo image URL shown under the pie. */
|
|
57
|
+
logoUrl?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface PieSceneProps extends SceneBase {
|
|
60
|
+
/** 1–4 pie cards laid out in a row. Assumes a ~1080-tall canvas. */
|
|
61
|
+
cards: PieItem[];
|
|
62
|
+
}
|
|
63
|
+
/** Pie-card scene: headerBar + a row of pieCards. Tuned for H≈1080. */
|
|
64
|
+
export declare function pieScene(props: PieSceneProps): Element;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=data-scenes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-scenes.d.ts","sourceRoot":"","sources":["../src/data-scenes.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKvD,UAAU,SAAS;IACjB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,kEAAkE;IAClE,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAwC1D;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,2DAA2D;IAC3D,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAwCxD;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,wDAAwD;IACxD,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAkC9D;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,oEAAoE;IACpE,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CA+BtD"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// Data-viz SCENES — full-frame compositions that turn the element-level
|
|
2
|
+
// data patterns (headerBar + statBlock / barChartRow / rankedList / pieCard)
|
|
3
|
+
// into single `group` scenes the promo() composer can sequence, the same shape
|
|
4
|
+
// as introCard / heroReveal. This is what makes "make me a stats / chart /
|
|
5
|
+
// top-10 video" reachable: the caller supplies data, these handle the layout.
|
|
6
|
+
//
|
|
7
|
+
// Each returns ONE full-frame identity group (x:W/2, y:H/2, W×H) whose children
|
|
8
|
+
// use canvas coordinates — exactly like introCard — so the data patterns' own
|
|
9
|
+
// absolute x/y land correctly. headerBar frames every scene (white header strip
|
|
10
|
+
// + colored body); the data sits in the body area below it.
|
|
11
|
+
//
|
|
12
|
+
// Tuned for a 1920×1080 canvas (the create_promo default). pieScene in
|
|
13
|
+
// particular relies on pieCard's 1080-based vertical layout.
|
|
14
|
+
import { headerBar } from './header-bar.js';
|
|
15
|
+
import { statBlock } from './stat-block.js';
|
|
16
|
+
import { barChartRow } from './bar-chart-row.js';
|
|
17
|
+
import { rankedList } from './ranked-list.js';
|
|
18
|
+
import { pieCard } from './pie-card.js';
|
|
19
|
+
import { assignLayers } from './layers.js';
|
|
20
|
+
const HEADER_H = 216; // matches headerBar
|
|
21
|
+
const MARGIN = 80;
|
|
22
|
+
/** Wrap composed children in a full-frame identity group (cf. introCard). */
|
|
23
|
+
function sceneGroup(base, children) {
|
|
24
|
+
const W = base.canvasWidth;
|
|
25
|
+
const H = base.canvasHeight;
|
|
26
|
+
return {
|
|
27
|
+
id: base.id,
|
|
28
|
+
type: 'group',
|
|
29
|
+
layer: base.layer,
|
|
30
|
+
time: base.time,
|
|
31
|
+
duration: base.duration,
|
|
32
|
+
x: 0,
|
|
33
|
+
y: 0,
|
|
34
|
+
width: W,
|
|
35
|
+
height: H,
|
|
36
|
+
animations: [{ type: 'fade-out', time: 'end', duration: 0.5 }],
|
|
37
|
+
// The composer owns layer assignment: `children` is built back-to-front
|
|
38
|
+
// (frame behind, data pushed on top), so stamp dense layers with the
|
|
39
|
+
// front-most = layer 1. This overrides the builders' relative layerBase
|
|
40
|
+
// offsets with a correct, unique-per-container ordering (layer 1 = top).
|
|
41
|
+
elements: assignLayers(children),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The white header strip + colored body fill that frames every data scene. */
|
|
45
|
+
function frame(base) {
|
|
46
|
+
return headerBar({
|
|
47
|
+
id: `${base.id}-hdr`,
|
|
48
|
+
title: base.title ?? '',
|
|
49
|
+
...(base.dateRange ? { dateRange: base.dateRange } : {}),
|
|
50
|
+
bodyColor: base.color,
|
|
51
|
+
...(base.theme ? { theme: base.theme } : {}),
|
|
52
|
+
canvasWidth: base.canvasWidth,
|
|
53
|
+
canvasHeight: base.canvasHeight,
|
|
54
|
+
time: 0,
|
|
55
|
+
duration: base.duration,
|
|
56
|
+
layerBase: 1,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Hero-stat scene: headerBar + a centered grid of spring-counted statBlocks. */
|
|
60
|
+
export function statsScene(props) {
|
|
61
|
+
const { canvasWidth: W, canvasHeight: H, color, theme, duration } = props;
|
|
62
|
+
const contentX = MARGIN;
|
|
63
|
+
const contentW = W - 2 * MARGIN;
|
|
64
|
+
const bodyTop = HEADER_H;
|
|
65
|
+
const bodyH = H - HEADER_H;
|
|
66
|
+
const children = [...frame(props)];
|
|
67
|
+
const n = props.stats.length;
|
|
68
|
+
const cols = n === 1 ? 1 : 2;
|
|
69
|
+
const rows = Math.ceil(n / cols);
|
|
70
|
+
const colGap = 80;
|
|
71
|
+
const rowStride = 340;
|
|
72
|
+
const blockW = cols === 1 ? contentW : (contentW - colGap) / 2;
|
|
73
|
+
const gridH = rows * rowStride;
|
|
74
|
+
const startY = bodyTop + (bodyH - gridH) / 2;
|
|
75
|
+
props.stats.forEach((s, i) => {
|
|
76
|
+
const col = i % cols;
|
|
77
|
+
const row = Math.floor(i / cols);
|
|
78
|
+
children.push(...statBlock({
|
|
79
|
+
id: `${props.id}-stat${i}`,
|
|
80
|
+
current: s.current,
|
|
81
|
+
...(s.previous !== undefined ? { previous: s.previous } : {}),
|
|
82
|
+
label: s.label,
|
|
83
|
+
color,
|
|
84
|
+
...(theme ? { theme } : {}),
|
|
85
|
+
x: contentX + col * (blockW + colGap),
|
|
86
|
+
y: startY + row * rowStride,
|
|
87
|
+
width: blockW,
|
|
88
|
+
time: 0,
|
|
89
|
+
duration,
|
|
90
|
+
layerBase: 20 + i * 10,
|
|
91
|
+
}));
|
|
92
|
+
});
|
|
93
|
+
return sceneGroup(props, children);
|
|
94
|
+
}
|
|
95
|
+
/** Bar-chart scene: headerBar + a centered vertical stack of barChartRows. */
|
|
96
|
+
export function barsScene(props) {
|
|
97
|
+
const { canvasWidth: W, canvasHeight: H, color, theme, duration } = props;
|
|
98
|
+
const contentX = MARGIN;
|
|
99
|
+
const contentW = W - 2 * MARGIN;
|
|
100
|
+
const bodyTop = HEADER_H;
|
|
101
|
+
const bodyH = H - HEADER_H;
|
|
102
|
+
const children = [...frame(props)];
|
|
103
|
+
const n = props.bars.length;
|
|
104
|
+
const max = Math.max(...props.bars.map((b) => b.value), 1);
|
|
105
|
+
const rowH = 168;
|
|
106
|
+
const gap = 48;
|
|
107
|
+
const rowStride = rowH + gap;
|
|
108
|
+
const totalH = n * rowStride - gap;
|
|
109
|
+
const startY = bodyTop + (bodyH - totalH) / 2;
|
|
110
|
+
props.bars.forEach((b, i) => {
|
|
111
|
+
children.push(...barChartRow({
|
|
112
|
+
id: `${props.id}-bar${i}`,
|
|
113
|
+
value: b.value,
|
|
114
|
+
max,
|
|
115
|
+
...(b.previous !== undefined ? { previous: b.previous } : {}),
|
|
116
|
+
label: b.label,
|
|
117
|
+
color,
|
|
118
|
+
...(theme ? { theme } : {}),
|
|
119
|
+
x: contentX,
|
|
120
|
+
y: startY + i * rowStride,
|
|
121
|
+
width: contentW,
|
|
122
|
+
height: rowH,
|
|
123
|
+
time: 0,
|
|
124
|
+
duration,
|
|
125
|
+
staggerIndex: i,
|
|
126
|
+
layerBase: 20 + i * 10,
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
return sceneGroup(props, children);
|
|
130
|
+
}
|
|
131
|
+
/** Ranked-list scene: headerBar + a centered rankedList (auto 1/2 columns). */
|
|
132
|
+
export function rankingScene(props) {
|
|
133
|
+
const { canvasWidth: W, canvasHeight: H, color, theme, duration } = props;
|
|
134
|
+
const contentX = MARGIN;
|
|
135
|
+
const contentW = W - 2 * MARGIN;
|
|
136
|
+
const bodyTop = HEADER_H;
|
|
137
|
+
const bodyH = H - HEADER_H;
|
|
138
|
+
const children = [...frame(props)];
|
|
139
|
+
const n = props.items.length;
|
|
140
|
+
const cols = n > 6 ? 2 : 1;
|
|
141
|
+
const rowH = 130;
|
|
142
|
+
const itemsPerCol = cols === 2 ? Math.ceil(n / 2) : n;
|
|
143
|
+
const totalH = itemsPerCol * rowH;
|
|
144
|
+
const startY = bodyTop + (bodyH - totalH) / 2;
|
|
145
|
+
children.push(...rankedList({
|
|
146
|
+
id: `${props.id}-rank`,
|
|
147
|
+
items: props.items,
|
|
148
|
+
color,
|
|
149
|
+
...(theme ? { theme } : {}),
|
|
150
|
+
x: contentX,
|
|
151
|
+
y: startY,
|
|
152
|
+
width: contentW,
|
|
153
|
+
columns: cols,
|
|
154
|
+
rowHeight: rowH,
|
|
155
|
+
time: 0,
|
|
156
|
+
duration,
|
|
157
|
+
layerBase: 20,
|
|
158
|
+
}));
|
|
159
|
+
return sceneGroup(props, children);
|
|
160
|
+
}
|
|
161
|
+
/** Pie-card scene: headerBar + a row of pieCards. Tuned for H≈1080. */
|
|
162
|
+
export function pieScene(props) {
|
|
163
|
+
const { canvasWidth: W, color, theme, duration } = props;
|
|
164
|
+
const contentX = MARGIN;
|
|
165
|
+
const contentW = W - 2 * MARGIN;
|
|
166
|
+
const children = [...frame(props)];
|
|
167
|
+
const m = props.cards.length;
|
|
168
|
+
const slot = contentW / m;
|
|
169
|
+
props.cards.forEach((c, i) => {
|
|
170
|
+
children.push(...pieCard({
|
|
171
|
+
id: `${props.id}-pie${i}`,
|
|
172
|
+
value: c.value,
|
|
173
|
+
total: c.total,
|
|
174
|
+
...(c.previous !== undefined ? { previous: c.previous } : {}),
|
|
175
|
+
...(c.logoUrl ? { logoUrl: c.logoUrl } : {}),
|
|
176
|
+
label: c.label,
|
|
177
|
+
color,
|
|
178
|
+
...(theme ? { theme } : {}),
|
|
179
|
+
cx: contentX + slot * (i + 0.5),
|
|
180
|
+
time: 0,
|
|
181
|
+
duration,
|
|
182
|
+
staggerIndex: i,
|
|
183
|
+
layerBase: 20 + i * 20,
|
|
184
|
+
}));
|
|
185
|
+
});
|
|
186
|
+
return sceneGroup(props, children);
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=data-scenes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-scenes.js","sourceRoot":"","sources":["../src/data-scenes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Element } from '@clipkit/protocol';
|
|
2
|
+
export interface FlowLineProps {
|
|
3
|
+
id: string;
|
|
4
|
+
/** Strip centre (canvas coords). */
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
/** Strip length and thickness (px). */
|
|
8
|
+
length: number;
|
|
9
|
+
thickness: number;
|
|
10
|
+
/** Strip background colour. */
|
|
11
|
+
baseColor: string;
|
|
12
|
+
/** Moving stripe colour. */
|
|
13
|
+
stripeColor: string;
|
|
14
|
+
/** Scroll speed, px/s. Positive = stripes move left (bar appears to go right). Default 220. */
|
|
15
|
+
speed?: number;
|
|
16
|
+
/** Stripe slant in degrees. Default 22. */
|
|
17
|
+
angle?: number;
|
|
18
|
+
/** Stripe width (px); the gap matches it. Default 30. */
|
|
19
|
+
stripeWidth?: number;
|
|
20
|
+
/** Corner radius (px). Default = thickness/2 (full pill ends). */
|
|
21
|
+
radius?: number;
|
|
22
|
+
time: number;
|
|
23
|
+
duration: number;
|
|
24
|
+
track: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function flowLine(props: FlowLineProps): Element;
|
|
27
|
+
//# sourceMappingURL=flow-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-line.d.ts","sourceRoot":"","sources":["../src/flow-line.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CA4CtD"}
|