brackt/app/components/marketing/BracketDecor.tsx

137 lines
5.6 KiB
TypeScript

import { BRACKT_GRADIENT_START, BRACKT_GRADIENT_END } from "~/lib/brand";
export function BracketDecor({ flip = false, mobileTall = false }: { flip?: boolean; mobileTall?: boolean }) {
const base = flip ? "r" : "l";
const id = mobileTall ? `${base}-m` : base;
const W = 399;
const H = mobileTall ? 2000 : 560;
const pad = 36;
const spacing = (H - 2 * pad) / 7;
const r1Ys = Array.from({ length: 8 }, (_, i) => pad + i * spacing);
const r2Ys = [0, 1, 2, 3].map((i) => (r1Ys[i * 2] + r1Ys[i * 2 + 1]) / 2);
const r3Ys = [0, 1].map((i) => (r2Ys[i * 2] + r2Ys[i * 2 + 1]) / 2);
const champY = (r3Ys[0] + r3Ys[1]) / 2;
const x0 = 4;
const x1 = 77;
const x2 = 161;
const x3 = 252;
const gradId = `grad-${id}`;
const glowId = `glow-${id}`;
const dotsGlowId = `dots-glow-${id}`;
const finalsGlowId = `finals-glow-${id}`;
const finalsHaloId = `finals-halo-${id}`;
const finalsFadeMaskGradId = `finals-fade-mask-grad-${id}`;
const finalsFadeMaskId = `finals-fade-mask-${id}`;
const finalsLineGlowId = `finals-line-glow-${id}`;
return (
<svg
viewBox={`0 0 ${W} ${H}`}
style={{
position: "absolute",
top: "50%",
transform: `translateY(-52%)${flip ? " scaleX(-1)" : ""}`,
[flip ? "right" : "left"]: 0,
pointerEvents: "none",
height: mobileTall ? "auto" : "75vh",
width: mobileTall ? "32vw" : "auto",
}}
>
<defs>
<linearGradient id={gradId} x1="0" y1="0" x2="0" y2={H} gradientUnits="userSpaceOnUse">
<stop offset="0%" stopColor={BRACKT_GRADIENT_START} />
<stop offset="100%" stopColor={BRACKT_GRADIENT_END} />
</linearGradient>
<filter id={glowId} x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<filter id={finalsGlowId} filterUnits="userSpaceOnUse"
x={x2 - 15} y={r3Ys[0] - 15} width={x3 - x2 + 30} height={r3Ys[1] - r3Ys[0] + 30}>
<feGaussianBlur stdDeviation="7" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<filter id={finalsHaloId} filterUnits="userSpaceOnUse"
x={x2 - 40} y={r3Ys[0] - 40} width={x3 - x2 + 80} height={r3Ys[1] - r3Ys[0] + 80}>
<feGaussianBlur stdDeviation="16" />
</filter>
<linearGradient id={finalsFadeMaskGradId} x1={x3} y1="0" x2={W} y2="0" gradientUnits="userSpaceOnUse">
<stop offset="0%" stopColor="white" />
<stop offset="50%" stopColor="white" />
<stop offset="100%" stopColor="white" stopOpacity="0" />
</linearGradient>
<mask id={finalsFadeMaskId} maskUnits="userSpaceOnUse" x={x3} y={champY - 20} width={W - x3} height={40}>
<rect x="0" y="0" width={W} height={H} fill={`url(#${finalsFadeMaskGradId})`} />
</mask>
<filter id={finalsLineGlowId} filterUnits="userSpaceOnUse" x={x3 - 10} y={champY - 15} width={W - x3 + 20} height={30}>
<feGaussianBlur stdDeviation="3" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<filter id={dotsGlowId} x="-200%" y="-200%" width="500%" height="500%">
<feGaussianBlur stdDeviation="5" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<g filter={`url(#${finalsHaloId})`} stroke={`url(#${gradId})`} strokeWidth={2} fill="none" opacity={0.75}>
{r3Ys.map((midY) => (
<line key={midY} x1={x2} y1={midY} x2={x3} y2={midY} />
))}
<line x1={x3} y1={r3Ys[0]} x2={x3} y2={r3Ys[1]} />
</g>
<g filter={`url(#${finalsGlowId})`} stroke={`url(#${gradId})`} strokeWidth={1.5} fill="none">
{r3Ys.map((midY) => (
<line key={midY} x1={x2} y1={midY} x2={x3} y2={midY} />
))}
<line x1={x3} y1={r3Ys[0]} x2={x3} y2={r3Ys[1]} />
</g>
<g filter={`url(#${glowId})`} stroke={`url(#${gradId})`} strokeWidth={1.5} fill="none">
{r1Ys.map((y) => (
<g key={y}>
<circle cx={x0} cy={y} r={3} fill={`url(#${gradId})`} stroke="none" filter={`url(#${dotsGlowId})`} />
<line x1={x0} y1={y} x2={x1} y2={y} />
</g>
))}
{r2Ys.map((midY, i) => (
<g key={midY}>
<line x1={x1} y1={r1Ys[i * 2]} x2={x1} y2={r1Ys[i * 2 + 1]} />
<circle cx={x1} cy={midY} r={3} fill={`url(#${gradId})`} stroke="none" filter={`url(#${dotsGlowId})`} />
<line x1={x1} y1={midY} x2={x2} y2={midY} />
</g>
))}
{r3Ys.map((midY, i) => (
<g key={midY}>
<line x1={x2} y1={r2Ys[i * 2]} x2={x2} y2={r2Ys[i * 2 + 1]} />
<circle cx={x2} cy={midY} r={3} fill={`url(#${gradId})`} stroke="none" filter={`url(#${dotsGlowId})`} />
<line x1={x2} y1={midY} x2={x3} y2={midY} />
</g>
))}
<line x1={x3} y1={r3Ys[0]} x2={x3} y2={r3Ys[1]} />
<circle cx={x3} cy={champY} r={3} fill={`url(#${gradId})`} stroke="none" filter={`url(#${dotsGlowId})`} />
</g>
<line
x1={x3} y1={champY} x2={W} y2={champY}
stroke={`url(#${gradId})`}
strokeWidth={1.5}
fill="none"
filter={`url(#${finalsLineGlowId})`}
mask={`url(#${finalsFadeMaskId})`}
/>
</svg>
);
}