A slowly rotating crystal prism (3D ray-marched rounded cube) with your logo suspended inside as a glowing emissive mesh. Per-channel IOR refraction on the cube faces splits white light into rainbow seams; caustic highlights pool on the virtual floor; soft bloom on the inner emission.
import CrystalLogoPrism from '@crazygl/hero-crystal-logo-prism';
export default function Page() {
return (
<CrystalLogoPrism
heading="Held in crystal."
logo="https://crazygl.com/samples/crazygl.svg"
logoEmission="#9be5ff"
dispersion={0.055}
ior={1.5}
/>
);
}heading / subheading, or switch contentType to two-columns / custom node.logo (SVG/PNG; sampled to an alpha mask), logoEmission color, logoBrightness.crystalSize, crystalRound edge round-off, crystalCenterX lateral position, rotSpeed, tiltX.ior (green channel), dispersion rainbow spread, fresnel rim, specGloss, absorbHex inner tint.causticStrength, causticHex, bloom on the inner logo.bgTop, bgBottom, vignette, pointerParallax.npm install @crazygl/hero-crystal-logo-prismThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import LogoInsideACrystal from '@crazygl/hero-crystal-logo-prism';
export default function Landing() {
return (
<LogoInsideACrystal />
);
}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 LogoInsideACrystal from '@crazygl/hero-crystal-logo-prism';
export default function Page() {
return (
<section>
<LogoInsideACrystal
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}