A product visual plays like a moving magazine cover, with large type sharing the frame and layered imagery adding subtle editorial depth.
import MagazineCoverProductHero from '@crazygl/hero-magazine-cover-product';
export default function Page() {
return (
<MagazineCoverProductHero
heading={"Issue\nNo. 01"}
backgroundImage="https://example.com/cover.jpg"
layer1Image="https://example.com/cutout.png"
overallRotation={4}
/>
);
}Provide a background image (full-frame base) and up to three layer images (Layer 1–3; a transparent PNG lets cut-out subjects float cleanly). Leave a layer's image empty to hide it.
X / Y / Z (depth) / Scale. Spread the three Z values across ~0–1 for clear front-to-back depth.overallOffsetX/Y, overallScale, overallRotation (tilt the whole set; default 4°).loadDelay (entrance cascade), hoverSpread (pop on hover), cameraParallax (pointer-driven camera sweep).contentAlign, paddingX/Y, heading font.npm install @crazygl/hero-magazine-cover-productThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import MagazineCoverProductHero from '@crazygl/hero-magazine-cover-product';
export default function Landing() {
return (
<MagazineCoverProductHero />
);
}The wrapper renders static HTML on the server and only initialises the canvas after hydration, so search engines see your copy.
// app/page.tsx — works in SSR-first frameworks (Next, Remix, Astro, etc.)
'use client';
import MagazineCoverProductHero from '@crazygl/hero-magazine-cover-product';
export default function Page() {
return (
<section>
<MagazineCoverProductHero
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}