feat(registry): curtain-reveal transition - #4323
miguel-heygen wants to merge 1 commit into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
cca23bb to
f3cda9e
Compare
f3cda9e to
c9ed6ac
Compare
|
Rendered demo (rendered via devbox headless Chrome since ai-miga was down for this branch). curtain-reveal-fixed.mp4 |
Agents often search for "curtain" or "stage reveal" and find nothing built for it in the catalog. Adds a component where two pleated stage curtains gather outward from center, like real velvet bunching at the tieback, to reveal slotted content underneath.
c9ed6ac to
548de3f
Compare
terencecho
left a comment
There was a problem hiding this comment.
Reviewed at 548de3fd.
Scope. 11 files: registry/components/curtain-reveal/{curtain-reveal.html, demo.html, registry-item.json} + docs/catalog/components/curtain-reveal.mdx + entries in docs.json, catalog-index.json, local-vectors.json/bin, catalog-gallery-data.mdx, and the new preview JSON blob. Additive; no touch outside the curtain-reveal item.
Component correctness (curtain-reveal.html).
- Deterministic. No
Math.random, no wall clock, norequestAnimationFrame, noDate.now. Pleat texture is a staticrepeating-linear-gradient. Scalloped hem viahemPolygon(scallops, ampPct, baseY)samplessin(t * PI * scallops) * ampPctat 25 fixed points (STEPS = 24,iinclusive of both ends) — same trim every render. - Envelope clamped to
data-duration.IN = Math.min(IN_BASE, duration)whereduration = Math.max(0.001, parseFloat(root.dataset.duration || "2.4")), so the fixed-IN case reduces to a fully-compressed part whendata-duration < IN_BASE. The two curtainfromTotweens haveduration: INand start at0, so they land at exactlyIN. - Spotlight sub-tween mathematically pinned to end at IN, not past it.
spotlightStart = IN * 0.25,spotlightDuration = Math.min(IN * 0.85, IN - spotlightStart).IN - spotlightStart = 0.75 * IN,min(0.85 * IN, 0.75 * IN) = 0.75 * IN, so the spotlight ends atspotlightStart + spotlightDuration = 0.25 * IN + 0.75 * IN = INexactly. The uncapped version (duration = IN * 0.85) would land atIN * 1.10and, on adata-duration < IN_BASEmount, escape pastdata-duration. The clamp is right and the comment above it names the exact failure mode it defuses. tl.set({}, {}, duration)anchors timeline length so GSAP's auto-extend doesn't push pastdata-duration.- Tone table is safe.
Object.prototype.hasOwnProperty.call(toneTable, vars.tone)guards against prototype pollution — avars.tone = "toString"won't resolvetoneTable[tone]to a stringified function. Falls back to"red"for unknown values. - Slot pattern. Uses
hostDoc.querySelector('template[data-slot="curtain-reveal-stage"]')at document level (templates never render in-place, so the caller's markup is inert until this primitive imports it). Falls back to the built-in.cvr-stage-defaultcard if no slot template is present.defaultMark.remove()beforeappendChild(hostDoc.importNode(...))— no double-render. - Mount contract. Registers one paused timeline under literal
"curtain-reveal"key.#rootisposition: absolute; inset: 0; container-type: size; isolation: isolate;— CSScqw/cqminunits size correctly against the host box, nodata-width/data-heightrequired. - No listeners, timers, observers → no teardown needed beyond the runtime's element removal.
Demo (demo.html). Standalone composition mounting the primitive full-bleed via data-composition-src, navy tone with pelmet off — exercises the non-default variable path. Slots a procedural inline-SVG stage scene so the demo ships nothing licensed (matches the grade-split-reveal pattern). Correctly reaches into the template's content via template.content.getElementById(...) rather than document.getElementById (inert templates aren't in the live document).
Catalog-drift check. Cleaner scope than #4331 — docs.json only bumps the Motion & effects (94 → 95) and Effects (53 → 54) tag counts and inserts catalog/components/curtain-reveal alphabetically between confetti and cut-the-curve. catalog-index.json inserts a single entry alphabetically between cursor-glyph-trail and cut-the-curve. local-vectors.json inserts curtain-reveal alphabetically. No unrelated drift folded in. catalogArtifact.revision bumps to 2c3b540a….
Registry.json placement. curtain-reveal appended at the end of items[] after warm-grain — note this is different from #4331's shape (which reorders the 8 hyperframes:example items to the top). Both PRs bump the artifact revision from 01f77564 (main) to their own hashes, and both pass check:catalog-drift at their heads, so each is internally consistent. Whichever merges first will define the resting order, and the second will rebase-regen through the artifact script. Non-blocking on this PR; loop-owner concern to sequence merges.
CI at head. Rollup SUCCESS. All Studio / Test / Producer / SDK / captures / catalog / lint / format / typecheck / build / windows / analyze / codeql green.
Body hygiene. Author's determinism claim + spotlight-clamp reasoning are both verified in the source. Independent adversarial review recorded (report on file). Rendered demo capture attached. [ ] Seen by home and Miguel before merge is your process, not a stamp gate.
Approving.
— tai
What
Adds
curtain-revealto the catalog: two pleated stage curtains that gather outward from center, the way real velvet bunches at the tieback, revealing the stage underneath. A static pelmet frames the top; a soft spotlight can bloom in as the curtains part.Why
"Curtain" returns zero results on the catalog's word-tier search today; agents asking for a physical theatre-curtain reveal have nothing to point at.
Look
Each curtain is a pleated panel (a repeating linear-gradient standing in for fabric folds) with a closed-form sine-wave scalloped hem sampled at a fixed point count, clipped via
clip-path. Both curtains part on one authored GSAP tween each with explicitfromToendpoints; an optional pelmet (its own scalloped trim) stays static, and an optional spotlight glow blooms in as they part.Structure
Copies the catalog item layout from
registry/components/ink-bleed-reveal/— slot-mount pattern atregistry/components/ink-bleed-reveal/ink-bleed-reveal.html:233-247,registry-item.jsonshape, docs page structure fromdocs/catalog/components/grade-split-reveal.mdx.Determinism
No physics state: the scalloped hem is a closed-form sine sample, both curtain tweens have explicit endpoints, no
Math.random/wall clock/requestAnimationFrameanywhere. The spotlight sub-tween is clamped so it always ends at or before the curtain-open envelope, so a very short composition (below the base open duration, with no hold) never runs past its declareddata-duration.Rendered demo capture is attached above (rendered via devbox headless Chrome since ai-miga was mid-outage team-wide).
Test plan
comment-checkclean againstorigin/main