85453da49f
regression / regression-shards (style-16-prod style-9-prod style-17-prod iframe-render-compat variables-prod mp4-h265-sdr, shard-4) (push) Has been cancelled
regression / regression-shards (style-4-prod style-11-prod style-2-prod animejs-adapter typegpu-adapter parallel-capture-regression, shard-5) (push) Has been cancelled
regression / regression-shards (style-7-prod style-8-prod style-10-prod css-spinner-render-compat webm-transparency mp4-h264-sdr webm-vp9, shard-3) (push) Has been cancelled
regression / regression-shards (sub-composition-video style-18-prod raf-ball-render-compat font-variant-numeric sub-comp-t0 sub-comp-id-selector, shard-7) (push) Has been cancelled
Windows render verification / Detect changes (push) Has been cancelled
Windows render verification / Preflight (lint + format) (push) Has been cancelled
Windows render verification / Render on windows-latest (push) Has been cancelled
Windows render verification / Tests on windows-latest (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Fallow audit (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Producer: integration tests (push) Has been cancelled
CI / Producer: unit tests (push) Has been cancelled
CI / File size check (push) Has been cancelled
CI / Test: skills (push) Has been cancelled
CI / Skills: manifest in sync (push) Has been cancelled
CI / CLI: npx shim (macos-latest) (push) Has been cancelled
CI / CLI: npx shim (ubuntu-latest) (push) Has been cancelled
CI / CLI: npx shim (windows-latest) (push) Has been cancelled
CI / SDK: unit + contract + smoke (push) Has been cancelled
CI / Test: runtime contract (push) Has been cancelled
CI / Studio: load smoke (push) Has been cancelled
CI / Smoke: global install (push) Has been cancelled
CI / CLI smoke (required) (push) Has been cancelled
CI / Semantic PR title (push) Has been cancelled
Player perf / Detect changes (push) Has been cancelled
Player perf / Preflight (lint + format) (push) Has been cancelled
Player perf / player-perf (push) Has been cancelled
Player perf / Perf: drift (push) Has been cancelled
Player perf / Perf: fps (push) Has been cancelled
Player perf / Perf: parity (push) Has been cancelled
Player perf / Perf: scrub (push) Has been cancelled
Player perf / Perf: load (push) Has been cancelled
preview-regression / Detect changes (push) Has been cancelled
preview-regression / Preflight (lint + format) (push) Has been cancelled
preview-regression / Preview parity (push) Has been cancelled
preview-regression / preview-regression (push) Has been cancelled
regression / regression (push) Has been cancelled
regression / Detect changes (push) Has been cancelled
regression / Preflight (lint + format) (push) Has been cancelled
regression / regression-shards (hdr-regression style-5-prod style-3-prod mov-prores, shard-1) (push) Has been cancelled
regression / regression-shards (overlay-montage-prod style-12-prod chat missing-host-comp-id png-sequence portrait-edge-bleed, shard-6) (push) Has been cancelled
regression / regression-shards (style-13-prod style-6-prod vignelli-stacking gsap-letters-render-compat audio-mux-parity, shard-8) (push) Has been cancelled
regression / regression-shards (style-15-prod hdr-hlg-regression style-1-prod many-cuts vfr-screen-recording render-symlinked-assets, shard-2) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Docs / Validate docs (push) Has been cancelled
Sync skills to ClawHub / Publish changed skills (push) Has been cancelled
100 lines
3.1 KiB
HTML
Vendored
100 lines
3.1 KiB
HTML
Vendored
<!--
|
||
Parallax Zoom — center card scales up while siblings parallax outward.
|
||
|
||
Inspired by the eBay Playbook hero transition: a grid of cards collapses
|
||
as the focal card grows to fill the frame.
|
||
|
||
Usage:
|
||
1. Wrap your card grid with class="parallax-zoom-grid".
|
||
2. Mark each card with class="parallax-zoom-card".
|
||
3. Add data-pz-row="0|1|2|..." and data-pz-col="0|1|2|..." per card
|
||
so the snippet knows each card's grid offset.
|
||
4. Mark the focal card with data-pz-focus="true" — this is the one
|
||
that scales up to fill the frame.
|
||
5. Drive --pz-progress 0 → 1 on the .parallax-zoom-grid from your
|
||
composition's paused GSAP timeline (see example at bottom).
|
||
|
||
Tunable CSS variables on .parallax-zoom-grid:
|
||
- --pz-focus-scale (default 6) maximum scale of the focused card
|
||
- --pz-sibling-push (default 900px) outward translation strength
|
||
- --pz-sibling-fade (default 1) sibling opacity falloff (0–1)
|
||
-->
|
||
|
||
<style>
|
||
.parallax-zoom-grid {
|
||
--pz-progress: 0;
|
||
--pz-focus-scale: 6;
|
||
--pz-sibling-push: 900px;
|
||
--pz-sibling-fade: 1;
|
||
position: relative;
|
||
}
|
||
|
||
.parallax-zoom-card {
|
||
transform-origin: center center;
|
||
will-change: transform, opacity;
|
||
transform: translate3d(
|
||
calc(var(--pz-dx, 0px) * var(--pz-progress)),
|
||
calc(var(--pz-dy, 0px) * var(--pz-progress)),
|
||
0
|
||
)
|
||
scale(calc(1 - var(--pz-progress) * 0.4));
|
||
opacity: calc(1 - var(--pz-progress) * var(--pz-sibling-fade));
|
||
}
|
||
|
||
.parallax-zoom-card[data-pz-focus="true"] {
|
||
z-index: 10;
|
||
transform: translate3d(0, 0, 0)
|
||
scale(calc(1 + var(--pz-progress) * (var(--pz-focus-scale) - 1)));
|
||
opacity: 1;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
(function () {
|
||
const grids = document.querySelectorAll(".parallax-zoom-grid");
|
||
|
||
grids.forEach((grid) => {
|
||
const cards = Array.from(grid.querySelectorAll(".parallax-zoom-card"));
|
||
if (cards.length === 0) return;
|
||
|
||
let focal = cards.find((c) => c.dataset.pzFocus === "true");
|
||
if (!focal) {
|
||
focal = cards[Math.floor(cards.length / 2)];
|
||
focal.dataset.pzFocus = "true";
|
||
}
|
||
|
||
const focusRow = Number(focal.dataset.pzRow ?? 0);
|
||
const focusCol = Number(focal.dataset.pzCol ?? 0);
|
||
const push = parseFloat(getComputedStyle(grid).getPropertyValue("--pz-sibling-push")) || 900;
|
||
|
||
cards.forEach((card) => {
|
||
if (card === focal) return;
|
||
const row = Number(card.dataset.pzRow ?? 0);
|
||
const col = Number(card.dataset.pzCol ?? 0);
|
||
const dCol = col - focusCol;
|
||
const dRow = row - focusRow;
|
||
const mag = Math.hypot(dCol, dRow) || 1;
|
||
const nx = (dCol / mag) * push * mag;
|
||
const ny = (dRow / mag) * push * mag;
|
||
card.style.setProperty("--pz-dx", `${nx}px`);
|
||
card.style.setProperty("--pz-dy", `${ny}px`);
|
||
});
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
<!--
|
||
Timeline integration example (paste into your composition's GSAP timeline):
|
||
|
||
tl.fromTo(
|
||
".parallax-zoom-grid",
|
||
{ "--pz-progress": 0 },
|
||
{
|
||
"--pz-progress": 1,
|
||
duration: 2.4,
|
||
ease: "power2.inOut",
|
||
},
|
||
1.0, // start time in seconds
|
||
);
|
||
-->
|