← Components/Animations & Cursors

ParticleBackground

particlebackground-1779388705646.tsx
'use client';
import { useEffect, useRef } from 'react';

export default function ParticleBackground({ children }) {
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;

    const particles = Array.from({ length: 60 }, () => ({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      vx: (Math.random() - 0.5) * 0.4,
      vy: (Math.random() - 0.5) * 0.4,
      size: Math.random() * 2 + 0.5,
      opacity: Math.random() * 0.5 + 0.1,
    }));

    let frame;
    const draw = () => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      particles.forEach(p => {
        p.x += p.vx; p.y += p.vy;
        if (p.x < 0 || p.x > canvas.width) p.vx *= -1;
        if (p.y < 0 || p.y > canvas.height) p.vy *= -1;
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(201,168,76,${p.opacity})`;
        ctx.fill();
      });
      particles.forEach((p, i) => {
        for (let j = i + 1; j < particles.length; j++) {
          const dx = p.x - particles[j].x, dy = p.y - particles[j].y;
          const dist = Math.sqrt(dx * dx + dy * dy);
          if (dist < 100) {
            ctx.beginPath();
            ctx.moveTo(p.x, p.y);
            ctx.lineTo(particles[j].x, particles[j].y);
            ctx.strokeStyle = `rgba(201,168,76,${0.1 * (1 - dist / 100)})`;
            ctx.stroke();
          }
        }
      });
      frame = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(frame);
  }, []);

  return (
    <div style={{ position: 'relative', width: '100%', height: '300px', background: '#0A0A0A', borderRadius: '16px', overflow: 'hidden' }}>
      <canvas ref={canvasRef} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }} />
      <div style={{ position: 'relative', zIndex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', fontFamily: 'system-ui, sans-serif' }}>
        {children || <h2 style={{ color: '#F5F5F0', fontSize: '28px', fontWeight: 700 }}>Particle Universe</h2>}
      </div>
    </div>
  );
}

Component info

CategoryAnimations & Cursors
Frameworkreact
TierFREE
Views0
Copies0

About

Canvas-based floating particle animation background

More from Animations & Cursors

'use client'
import { useState, useEffect, useRef } from 'react'

interface AnimatedNumberProps {
  target: number
  duration?: number
  prefix?: string
  suffix?: string
  decimals?: number
  onComplete?: () => void
}

function AnimatedNumber({ targ
CounterAnimation
Animations & Cursors
import React from 'react';
import { motion } from 'framer-motion';

interface MorphCursorProps {
  children: React.ReactNode;
}

const MorphCursor: React.FC<MorphCursorProps> = ({ children }) => {
  const [cursorType, setCursorType] = React.useState(
MorphCursor
Animations & Cursors
import React from 'react';

interface SpotlightCursorProps {
  children: React.ReactNode;
}

const SpotlightCursor: React.FC<SpotlightCursorProps> = ({ children }) => {
  return (
    <div className="spotlight-cursor" style={{
      position: 'relati
SpotlightCursor
Animations & Cursors
import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';

interface PixelCursorProps {
  color: string;
}

const PixelCursor: React.FC<PixelCursorProps> = ({ color }) => {
  const [mousePosition, setMousePosition] = useSta
PixelCursor
Animations & Cursors