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({ targCounterAnimation
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: 'relatiSpotlightCursor
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] = useStaPixelCursor
Animations & Cursors