← vibesdk
src/components/shared/FloatingBackgroundIcons.tsx
8.2 KB
Download file
import type { CSSProperties, ComponentType } from 'react';
import {
RocketLaunch,
GlobeHemisphereWest,
Code,
Sparkle,
Lightning,
Cloud,
type IconProps,
} from '@phosphor-icons/react';
import { cn } from '@cloudflare/kumo';
type FloatingIcon = {
Icon: ComponentType<IconProps>;
left: string;
top: string;
size: string;
rot: string;
op: number;
dur: string;
delay: string;
bob: string;
color: string;
};
const FLOATING_ICONS: readonly FloatingIcon[] = [
// rocket
{
Icon: RocketLaunch,
left: '6%',
top: '10%',
size: '3.4rem',
rot: '-16deg',
op: 0.28,
dur: '7.5s',
delay: '0s',
bob: '-8px',
color: '#f6821f',
},
{
Icon: RocketLaunch,
left: '72%',
top: '62%',
size: '1.7rem',
rot: '22deg',
op: 0.2,
dur: '6.4s',
delay: '1.4s',
bob: '-5px',
color: '#f6821f',
},
{
Icon: RocketLaunch,
left: '40%',
top: '84%',
size: '2.3rem',
rot: '-8deg',
op: 0.22,
dur: '8.1s',
delay: '2.2s',
bob: '-7px',
color: '#fb923c',
},
{
Icon: RocketLaunch,
left: '88%',
top: '28%',
size: '1.4rem',
rot: '12deg',
op: 0.18,
dur: '5.8s',
delay: '0.8s',
bob: '-4px',
color: '#f97316',
},
{
Icon: RocketLaunch,
left: '28%',
top: '38%',
size: '1.9rem',
rot: '-24deg',
op: 0.2,
dur: '7.1s',
delay: '3s',
bob: '-6px',
color: '#ea580c',
},
{
Icon: RocketLaunch,
left: '56%',
top: '6%',
size: '1.3rem',
rot: '28deg',
op: 0.17,
dur: '6s',
delay: '1.7s',
bob: '-4px',
color: '#fdba74',
},
{
Icon: RocketLaunch,
left: '16%',
top: '92%',
size: '2.6rem',
rot: '4deg',
op: 0.21,
dur: '8.8s',
delay: '0.4s',
bob: '-7px',
color: '#f6821f',
},
// globe
{
Icon: GlobeHemisphereWest,
left: '78%',
top: '8%',
size: '3.6rem',
rot: '14deg',
op: 0.26,
dur: '8.2s',
delay: '0.5s',
bob: '-10px',
color: '#3b82f6',
},
{
Icon: GlobeHemisphereWest,
left: '14%',
top: '48%',
size: '1.6rem',
rot: '-20deg',
op: 0.2,
dur: '6.9s',
delay: '1.8s',
bob: '-5px',
color: '#60a5fa',
},
{
Icon: GlobeHemisphereWest,
left: '52%',
top: '18%',
size: '2.1rem',
rot: '6deg',
op: 0.18,
dur: '7.7s',
delay: '2.6s',
bob: '-6px',
color: '#2563eb',
},
{
Icon: GlobeHemisphereWest,
left: '30%',
top: '88%',
size: '2.8rem',
rot: '-12deg',
op: 0.22,
dur: '9s',
delay: '1.1s',
bob: '-8px',
color: '#38bdf8',
},
{
Icon: GlobeHemisphereWest,
left: '94%',
top: '42%',
size: '1.5rem',
rot: '18deg',
op: 0.19,
dur: '6.3s',
delay: '2.9s',
bob: '-5px',
color: '#93c5fd',
},
{
Icon: GlobeHemisphereWest,
left: '44%',
top: '66%',
size: '1.8rem',
rot: '-8deg',
op: 0.17,
dur: '7.4s',
delay: '0.9s',
bob: '-4px',
color: '#1d4ed8',
},
{
Icon: GlobeHemisphereWest,
left: '2%',
top: '68%',
size: '2.4rem',
rot: '10deg',
op: 0.21,
dur: '8.5s',
delay: '1.5s',
bob: '-7px',
color: '#3b82f6',
},
// code
{
Icon: Code,
left: '20%',
top: '72%',
size: '3rem',
rot: '8deg',
op: 0.24,
dur: '6.8s',
delay: '0.9s',
bob: '-7px',
color: '#22c55e',
},
{
Icon: Code,
left: '64%',
top: '36%',
size: '1.5rem',
rot: '-18deg',
op: 0.2,
dur: '5.6s',
delay: '2s',
bob: '-4px',
color: '#4ade80',
},
{
Icon: Code,
left: '8%',
top: '30%',
size: '2rem',
rot: '16deg',
op: 0.19,
dur: '7.2s',
delay: '0.3s',
bob: '-6px',
color: '#16a34a',
},
{
Icon: Code,
left: '90%',
top: '78%',
size: '2.4rem',
rot: '-6deg',
op: 0.22,
dur: '8.4s',
delay: '1.6s',
bob: '-7px',
color: '#86efac',
},
{
Icon: Code,
left: '48%',
top: '48%',
size: '1.4rem',
rot: '24deg',
op: 0.16,
dur: '6.1s',
delay: '2.7s',
bob: '-3px',
color: '#22c55e',
},
{
Icon: Code,
left: '76%',
top: '48%',
size: '2rem',
rot: '-14deg',
op: 0.2,
dur: '7.6s',
delay: '0.6s',
bob: '-5px',
color: '#15803d',
},
{
Icon: Code,
left: '34%',
top: '28%',
size: '1.7rem',
rot: '4deg',
op: 0.18,
dur: '5.9s',
delay: '3.2s',
bob: '-4px',
color: '#4ade80',
},
// sparkle
{
Icon: Sparkle,
left: '86%',
top: '48%',
size: '2.6rem',
rot: '-12deg',
op: 0.28,
dur: '5.9s',
delay: '0.4s',
bob: '-9px',
color: '#a855f7',
},
{
Icon: Sparkle,
left: '36%',
top: '6%',
size: '1.5rem',
rot: '20deg',
op: 0.22,
dur: '6.2s',
delay: '1.5s',
bob: '-5px',
color: '#c084fc',
},
{
Icon: Sparkle,
left: '58%',
top: '74%',
size: '3.2rem',
rot: '-4deg',
op: 0.2,
dur: '7.8s',
delay: '2.4s',
bob: '-8px',
color: '#9333ea',
},
{
Icon: Sparkle,
left: '4%',
top: '82%',
size: '1.8rem',
rot: '14deg',
op: 0.24,
dur: '5.4s',
delay: '0.7s',
bob: '-6px',
color: '#d8b4fe',
},
{
Icon: Sparkle,
left: '62%',
top: '52%',
size: '1.3rem',
rot: '-26deg',
op: 0.18,
dur: '6.6s',
delay: '1.9s',
bob: '-4px',
color: '#e9d5ff',
},
{
Icon: Sparkle,
left: '22%',
top: '58%',
size: '2.2rem',
rot: '8deg',
op: 0.2,
dur: '7.3s',
delay: '2.5s',
bob: '-6px',
color: '#a855f7',
},
{
Icon: Sparkle,
left: '96%',
top: '16%',
size: '1.6rem',
rot: '-10deg',
op: 0.19,
dur: '5.5s',
delay: '3.1s',
bob: '-5px',
color: '#c084fc',
},
// lightning
{
Icon: Lightning,
left: '4%',
top: '40%',
size: '3.1rem',
rot: '22deg',
op: 0.26,
dur: '6.4s',
delay: '1.2s',
bob: '-7px',
color: '#eab308',
},
{
Icon: Lightning,
left: '70%',
top: '14%',
size: '1.6rem',
rot: '-14deg',
op: 0.2,
dur: '5.7s',
delay: '2.1s',
bob: '-5px',
color: '#facc15',
},
{
Icon: Lightning,
left: '46%',
top: '54%',
size: '2.2rem',
rot: '10deg',
op: 0.18,
dur: '7s',
delay: '0.6s',
bob: '-6px',
color: '#ca8a04',
},
{
Icon: Lightning,
left: '82%',
top: '88%',
size: '2.7rem',
rot: '-22deg',
op: 0.22,
dur: '8s',
delay: '1.9s',
bob: '-8px',
color: '#fde047',
},
{
Icon: Lightning,
left: '38%',
top: '42%',
size: '1.4rem',
rot: '30deg',
op: 0.17,
dur: '5.3s',
delay: '2.8s',
bob: '-4px',
color: '#eab308',
},
{
Icon: Lightning,
left: '12%',
top: '16%',
size: '1.9rem',
rot: '-6deg',
op: 0.2,
dur: '6.7s',
delay: '1s',
bob: '-5px',
color: '#fbbf24',
},
{
Icon: Lightning,
left: '54%',
top: '92%',
size: '2rem',
rot: '16deg',
op: 0.19,
dur: '7.9s',
delay: '0.2s',
bob: '-6px',
color: '#a16207',
},
// cloud
{
Icon: Cloud,
left: '48%',
top: '40%',
size: '1.7rem',
rot: '-8deg',
op: 0.16,
dur: '9s',
delay: '1s',
bob: '-4px',
color: '#38bdf8',
},
{
Icon: Cloud,
left: '24%',
top: '18%',
size: '2.9rem',
rot: '6deg',
op: 0.22,
dur: '8.6s',
delay: '0.2s',
bob: '-7px',
color: '#0ea5e9',
},
{
Icon: Cloud,
left: '68%',
top: '82%',
size: '3.4rem',
rot: '-10deg',
op: 0.2,
dur: '9.4s',
delay: '2.8s',
bob: '-6px',
color: '#7dd3fc',
},
{
Icon: Cloud,
left: '92%',
top: '58%',
size: '1.9rem',
rot: '18deg',
op: 0.18,
dur: '7.3s',
delay: '1.3s',
bob: '-5px',
color: '#0284c7',
},
{
Icon: Cloud,
left: '42%',
top: '76%',
size: '1.5rem',
rot: '-16deg',
op: 0.17,
dur: '8s',
delay: '2.3s',
bob: '-4px',
color: '#bae6fd',
},
{
Icon: Cloud,
left: '84%',
top: '36%',
size: '2.3rem',
rot: '4deg',
op: 0.2,
dur: '9.2s',
delay: '0.8s',
bob: '-6px',
color: '#0ea5e9',
},
{
Icon: Cloud,
left: '60%',
top: '28%',
size: '1.6rem',
rot: '12deg',
op: 0.16,
dur: '7.5s',
delay: '3.3s',
bob: '-3px',
color: '#38bdf8',
},
];
export function FloatingBackgroundIcons({
className,
}: React.HTMLAttributes<'div'>) {
return (
<div className={cn('run-app-icons', className)} aria-hidden>
{FLOATING_ICONS.map(
(
{ Icon, left, top, size, rot, op, dur, delay, bob, color },
i,
) => (
<span
key={i}
style={
{
left,
top,
fontSize: size,
'--rot': rot,
'--op': op,
'--dur': dur,
'--delay': delay,
'--bob': bob,
'--icon-color': color,
} as CSSProperties
}
>
<Icon weight="duotone" />
</span>
),
)}
</div>
);
}