mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
* feat(skills): c2v mining pass over animation blueprints and rules Compacts ~45 existing animation rules/blueprints into tighter recipe form (net -3.4k lines) and adds 17 mined from the c2v corpus: - 7 blueprints: agent-progress-theater, camera-journey, fixed-anchor-cycle, panel-edit-live-sync, prompt-type-submit-generate, transcript-scroll-artifact-reveal, zoom-out-workspace-reveal - 10 rules: 3d-camera-flight, anchored-layout-expand, chart-scrub-readout, chromatic-glitch, control-target-sync, cursor-drag, gradient-text-sweep, multi-cursor-choreography, particle-burst, theme-crossfade-morph Both indexes updated. * feat(skills): sync product-launch script bank with mined blueprint roles The role->blueprint script bank in product-launch-video/story-design.md is kept 1:1 with blueprints-index role declarations, which the c2v mining pass expanded. Adds the 25 missing entries (script-shape descriptor + example lines + pattern): 13 for the 7 new blueprints, 12 for role widenings on 7 existing ones (cursor-ui-demo, dataviz-countup, titlecard-reveal, et al.), and states the 1:1 sync contract in the bank's intro. * docs(skills): cover constellation-hub scatter-drift variant in the script bank Review follow-up on #2680: the SOCIAL_PROOF constellation-hub entry patterned only the orbit shape; the c2v pass added a scatter-drift end-card variant with the opposite geometry (no hub, no ring). Adds an example line and extends the pattern so a scatter-drift beat's VO isn't steered toward the orbit shape.
89 lines
4.2 KiB
Markdown
89 lines
4.2 KiB
Markdown
---
|
||
name: center-outward-expansion
|
||
description: Elements start clustered at screen center and expand outward to their final positions, driven by a shared progress value.
|
||
metadata:
|
||
tags: expansion, scatter, center, reveal, layout, sync, burst
|
||
---
|
||
|
||
# Center-Outward Expansion
|
||
|
||
Elements begin at one shared center point and radiate outward to their final positions — the entry beat itself, or motion driven by another animation's progress (a counting number, a beat). Flat 2D cousin of [depth-scatter-assemble.md](depth-scatter-assemble.md) (per-element 3D cloud): here every element shares the SAME origin.
|
||
|
||
## How It Works
|
||
|
||
Each element carries its final offset as `data-target-x/y`. Its position lerps between center and target: `x = targetX × progress`. Self-centering is baked as `xPercent/yPercent: -50` so the tweened `x`/`y` are pure offsets from the stage center. Standalone burst = per-item staggered `fromTo`; driven burst = one shared proxy (see Variations).
|
||
|
||
## Recipe
|
||
|
||
```html
|
||
<!-- inside a standard scene clip (hyperframes-core) -->
|
||
<div class="burst-wrap">
|
||
<div class="burst-item" data-target-x="-360" data-target-y="-180">{itemA}</div>
|
||
<div class="burst-item" data-target-x="360" data-target-y="-180">{itemB}</div>
|
||
<div class="burst-item" data-target-x="0" data-target-y="360">{itemC}</div>
|
||
</div>
|
||
```
|
||
|
||
```css
|
||
.burst-wrap {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
.burst-item {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%; /* GSAP xPercent/yPercent -50 bakes the centering; x/y tween the offset */
|
||
will-change: transform;
|
||
}
|
||
```
|
||
|
||
```js
|
||
document.querySelectorAll(".burst-item").forEach((el, i) => {
|
||
tl.fromTo(
|
||
el,
|
||
{ xPercent: -50, yPercent: -50, x: 0, y: 0, scale: 0.6, opacity: 0 },
|
||
{
|
||
x: Number(el.dataset.targetX),
|
||
y: Number(el.dataset.targetY),
|
||
scale: 1,
|
||
opacity: 1,
|
||
duration: EXPAND_DUR,
|
||
ease: EXPAND_EASE,
|
||
},
|
||
ENTRY_AT + i * STAGGER,
|
||
);
|
||
});
|
||
```
|
||
|
||
## Variations
|
||
|
||
- **Synced to a driver (chord)**: when the burst shadows a counter / beat, drop the stagger and drive all items from ONE 0→1 proxy tween with the driver's exact duration AND ease; `onUpdate` writes `translate(-50%,-50%) translate(targetX*p, targetY*p)` per item — the two read as one beat.
|
||
- **Partially-spread start**: with 6+ items the full cluster piles up — start from `{ x: targetX * START_PROGRESS, ... }`.
|
||
- **Idle micro-float**: hand off to [sine-wave-loop.md](sine-wave-loop.md) after landing instead of freezing.
|
||
|
||
## Values
|
||
|
||
| token | range | notes |
|
||
| -------------- | -------------------- | ---------------------------------------------------------------- |
|
||
| ITEM_COUNT | 3–8 | > 8 = visual chaos mid-expansion; low counts want wider spread |
|
||
| EXPAND_DUR | 1.0–1.8s | must equal the driver's duration in the synced variant |
|
||
| EXPAND_EASE | `power3.out` default | `power2.out` gentler, `expo.out` dramatic stop; NEVER `in` eases |
|
||
| STAGGER | 0.04–0.08s | tighter = chord; looser = lazy arpeggio |
|
||
| ENTRY_AT | 0–0.5s | a beat of compositional quiet before the burst |
|
||
| START_PROGRESS | 0–0.5 | 0 = dramatic full cluster; ~0.3 avoids the pile-up |
|
||
|
||
## Critical Constraints
|
||
|
||
- **Tween `x`/`y` over the baked `xPercent/yPercent: -50`** — mutating `left`/`top` fights the centering and causes pixel jitter.
|
||
- **Out-easing only** — `in` easings read as items being sucked back mid-air.
|
||
- **No other absolute-positioned siblings inside `.burst-wrap`** — they'd steal the centered baseline.
|
||
- **❗ The burst IS the beat** — don't park a "real headline" label below it (the eye snaps to the label and ignores the burst). If a label is needed, reveal it post-burst in the same stack.
|
||
- Synced variant: identical duration + ease as the driver, or the chord falls apart.
|
||
|
||
## See also
|
||
|
||
`counting-dynamic-scale` (the classic chord driver) · `depth-scatter-assemble` (3D per-element cloud) · `card-morph-anchor` (burst out of a morphed card) · `sine-wave-loop` (post-landing life).
|