Sparkles
A configurable sparkles component that can be used as a background or as a standalone component.
Aceternity
<script lang="ts">
import Sparkles from './Sparkles.svelte';
</script>
<div
class="flex h-[40rem] w-full flex-col items-center justify-center overflow-hidden rounded-md bg-black"
>
<h2 class="relative z-20 text-center text-3xl font-bold text-white md:text-7xl lg:text-9xl">
Aceternity
</h2>
<div class="relative h-40 w-[40rem]">
<!-- Gradients -->
<div
class="absolute inset-x-20 top-0 h-[2px] w-3/4 bg-gradient-to-r from-transparent via-indigo-500 to-transparent blur-sm"
/>
<div
class="absolute inset-x-20 top-0 h-px w-3/4 bg-gradient-to-r from-transparent via-indigo-500 to-transparent"
/>
<div
class="absolute inset-x-60 top-0 h-[5px] w-1/4 bg-gradient-to-r from-transparent via-sky-500 to-transparent blur-sm"
/>
<div
class="absolute inset-x-60 top-0 h-px w-1/4 bg-gradient-to-r from-transparent via-sky-500 to-transparent"
/>
<!-- Core component -->
<Sparkles
minSize={0.8}
maxSize={2}
particleDensity={300}
className="w-full h-full"
particleColor="#FFFFFF"
/>
<!-- Radial Gradient to prevent sharp edges -->
<div
class="absolute inset-0 h-full w-full bg-black [mask-image:radial-gradient(350px_200px_at_top,transparent_20%,white)]"
></div>
</div>
</div>
Installation
Install Dependencies
npm i svelte-motion clsx tailwind-merge
Add util file
src/lib/utils/cn.ts
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Copy the source code
src/lib/components/ui/Sparkles/Sparkles.svelte
<script lang="ts">
import { cn } from '@/utils';
import { Motion } from 'svelte-motion';
let randomMove = () => Math.random() * 4 - 2;
export let minSize: number = 0.6;
export let maxSize: number = 1.5;
export let speed: number = 3;
export let particleColor: string = '#ffffff';
export let particleDensity: number | undefined = 200;
export let className: string | undefined = undefined;
function getRandomValue() {
return minSize + Math.random() * (maxSize - minSize);
}
</script>
<div class={cn('relative h-48', className)}>
<div class="absolute inset-0">
{#each [...Array(particleDensity)] as _, i (`star-${i}`)}
<Motion
let:motion
animate={{
top: `calc(${Math.random() * 100}% + ${randomMove()}px)`,
left: `calc(${Math.random() * 100}% + ${randomMove()}px)`,
opacity: Math.random(),
scale: [1, 1.2, 0]
}}
transition={{
duration: Math.random() * 10 + speed,
repeat: Infinity,
ease: 'linear'
}}
>
<span
use:motion
class="inline-block"
style={`position: absolute; width: ${getRandomValue()}px; height: ${getRandomValue()}px; background-color: ${particleColor}; border-radius: 50%; top: ${Math.random() * 100}%; left: ${Math.random() * 100}%;`}
></span>
</Motion>
{/each}
</div>
</div>
src/lib/components/ui/Sparkles/index.ts
import Sparkles from './Sparkles.svelte';
export { Sparkles };
Props
Sparkles
Prop | Type | Description |
---|---|---|
id | string | undefined | The id of the sparkles component. |
className | string | undefined | The class name of the sparkles component. |
background | string | undefined | The background color of the sparkles component. |
particleSize | number | undefined | The size of the particles. |
minSize | number | undefined | The minimum size of the particles. |
maxSize | number | undefined | The maximum size of the particles. |
speed | number | undefined | The speed of the particles. |
particleColor | string | undefined | The color of the particles. |
particleDensity | number | undefined | The density of the particles. |