Files
hyperframes/skills/hyperframes-animation/rules/hacker-flip-3d.md
WaterrrForever 853256403b feat(skills): c2v mining pass — 7 new blueprints, 10 new rules, compacted recipe corpus (#2680)
* 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.
2026-07-21 17:28:55 +08:00

5.5 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
hacker-flip-3d Character-level 3D rotation with random glyph substitution for a decryption reveal effect.
tags
text, 3d, reveal, decode, hacker, randomization, perspective

Hacker Flip 3D Reveal

Characters flip down from 90° in 3D while cycling through pseudo-random glyphs, then settle on the target character — a "decryption" / airport flap-display reveal. Resolves to a short target word (typically a brand or label).

How It Works

Each character gets its own per-char tween from rotateX: 90deg (hidden, hinged at the bottom edge) to 0deg (upright), staggered across the word. Below REVEAL_THRESHOLD progress the char displays a seeded pseudo-random glyph that reshuffles every few frames; past it, the real target character clicks into place — so the eye catches the right letter just as the flip settles. A hidden ghost copy of the full word reserves layout width so narrow flicker glyphs never shift the line.

Recipe

<!-- inside a standard scene clip (hyperframes-core) -->
<div class="hacker-text-wrap" id="hacker-text" data-target="{phrase}">
  <!-- ghost row + per-char spans injected by the setup script -->
</div>
/* the scene root (or nearest 3D ancestor) MUST set perspective: 1500px */
.hacker-text-wrap {
  font-family: {monoFont}; /* monospace so flicker glyphs hold width */
  font-weight: 900;
  font-size: HACKER_FONT_SIZE;
  position: relative; /* ghost stacks absolutely behind the live row */
}
.hacker-char {
  display: inline-block;
  transform-origin: bottom; /* flap-display hinge */
  transform-style: preserve-3d;
}
.hacker-ghost {
  opacity: 0;
  pointer-events: none;
  position: absolute;
  inset: 0 auto auto 0;
}
const wrap = document.getElementById("hacker-text");
const targetWord = wrap.dataset.target;
const GLYPHS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*";

// Ghost row (reserves width) + live per-char spans
const ghost = document.createElement("div");
ghost.className = "hacker-ghost";
ghost.textContent = targetWord;
wrap.appendChild(ghost);
const charEls = [...targetWord].map((ch) => {
  const span = document.createElement("span");
  span.className = "hacker-char";
  span.textContent = ch === " " ? " " : ch;
  span.dataset.target = ch;
  wrap.appendChild(span);
  return span;
});

// Index-seeded hash — same frame always yields the same glyph
function pseudoGlyph(seed) {
  const h = ((seed * 9301 + 49297) % 233280) / 233280;
  return GLYPHS[Math.floor(h * GLYPHS.length)];
}

charEls.forEach((el, i) => {
  const state = { p: 0 };
  tl.to(
    state,
    {
      p: 1,
      duration: FLIP_DURATION,
      ease: "power3.out",
      onUpdate: () => {
        if (state.p < REVEAL_THRESHOLD) {
          el.textContent = pseudoGlyph(i * 1000 + Math.floor(state.p * 100));
        } else {
          el.textContent = el.dataset.target === " " ? " " : el.dataset.target;
        }
        el.style.transform = `rotateX(${90 - state.p * 90}deg)`;
        el.style.opacity = Math.min(1, state.p * 2);
      },
    },
    i * CHAR_STAGGER,
  );
});

Variations

  • Top-down hingetransform-origin: top for a falling-flap look.
  • Center spintransform-origin: center reads as a barrel roll, not a flap.
  • Number-only pool — restrict GLYPHS to digits for a price / countdown decode.
  • Two-pass decode — chain two FLIP_DURATION tweens with different glyph pools (symbols → letters → real) for a longer reveal.

Values

token range notes
HACKER_FONT_SIZE 610% of viewport min-dimension the flip IS the focal beat; ghost must use the identical size
FLIP_DURATION 0.41.0s under 0.4s the flicker phase has no time; over 1.0s drags
CHAR_STAGGER 0.030.08s total decode = CHAR_STAGGER × (chars 1) + FLIP_DURATION — fit the phase budget
REVEAL_THRESHOLD 0.50.7 lower reveals too early (no tension); higher reads as a hard end-reveal
FLICKER_RATE 36 frames per glyph swap <3 looks like noise; >6 looks like discrete typing

Reference: ../../examples/proof-logo-chain.html (163px, 0.55s, 0.033s, 0.6).

Critical Constraints

  • perspective on the scene root REQUIRED — without parent perspective, rotateX renders as a 2D squash, not a 3D flip; transform-style: preserve-3d on each char.
  • Ghost placeholder with identical content + font must back the live chars — without it, narrow glyphs shift the layout mid-flicker (monospace preferred; the ghost makes a proportional face recoverable).
  • Flicker seed = char index + quantized progress — the same frame must show the same glyph.
  • Flicker rate ≥ ~3 frames per swap; onUpdate work stays O(1) per char per frame.
  • Center the flip dead-center and add NO decorative chrome (timestamp lines, "// AUTH" tags, status dots) — the flip is the beat. A necessary secondary label is BIG typography (5672px caps + tracking) in the same stack, never a tiny corner annotation.

See also

card-morph-anchor (flip reveals a phrase, card morphs into the next shot) · counting-dynamic-scale (the numeric counterpart).