Xingfing

Bubble website12

Heroes 1

About

bubble animation website

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Bubble website12 to your project and fits it to your theme.

Code

How Bubble website12 is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import React, { useEffect, useRef } from 'react';

const ColorBallsPage: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const animationFrameId = useRef<number>();
  // Ball type
  type Ball = {
    x: number;
    y: number;
    radius: number;
    color: string;
    vx: number;
    vy: number;
  };
  const ballsCount = 20;
  const balls = useRef<Ball[]>([]);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // Resize canvas to fill window
    const resize = () => {
      if (canvas) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      }
    };
    resize();
    window.addEventListener('resize', resize);

    const colors = [
      '#FF6B6B',
      '#FFD93D',
      '#6BCB77',
      '#4D96FF',
      '#FF8C42',
      '#9D4EDD',
      '#00B8A9',
      '#F6416C',
      '#FF9B54',
      '#44AF69',
    ];

    // Initialize balls
    balls.current = [];
    for (let i = 0; i < ballsCount; i++) {
      const radius = Math.random() * 20 + 15;
      const x = Math.random() * (canvas.width - radius * 2) + radius;
      const y = Math.random() * (canvas.height - radius * 2) + radius;
      const color = colors[i % colors.length];
      const vx = (Math.random() - 0.5) * 1.5;
      const vy = (Math.random() - 0.5) * 1.5;
      balls.current.push({ x, y, radius, color, vx, vy });
    }

    // Animation function
    const animate = () => {
      if (!ctx) return;

      ctx.clearRect(0, 0, canvas.width, canvas.height);

      balls.current.forEach((ball) => {
        // Move ball
        ball.x += ball.vx;
        ball.y += ball.vy;

        // Bounce on edges
        if (ball.x + ball.radius > canvas.width) {
          ball.x = canvas.width - ball.radius;
          ball.vx *= -1;
        }
        if (ball.x - ball.radius < 0) {
          ball.x = ball.radius;
          ball.vx *= -1;
        }
        if (ball.y + ball.radius > canvas.height) {
          ball.y = canvas.height - ball.radius;
          ball.vy *= -1;
        }
        if (ball.y - ball.radius < 0) {
          ball.y = ball.radius;
          ball.vy *= -1;
        }

        // Draw ball
        const gradient = ctx.createRadialGradient(
          ball.x,
          ball.y,
          ball.radius * 0.3,
          ball.x,
          ball.y,
          ball.radius
        );
        gradient.addColorStop(0, ball.color);
        gradient.addColorStop(1, 'transparent');
        ctx.fillStyle = gradient;
        ctx.beginPath();
        ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
        ctx.fill();
      });

      animationFrameId.current = requestAnimationFrame(animate);
    };

    animate();

    return () => {
      window.removeEventListener('resize', resize);
      if (animationFrameId.current) cancelAnimationFrame(animationFrameId.current);
    };
  }, []);

  return (
    <>
      <canvas
        ref={canvasRef}
        style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100vw',
          height: '100vh',
          zIndex: -1,
          background:
            'linear-gradient(135deg, #4b6cb7 0%, #182848 100%)',
          display: 'block',
        }}
      />
      <div
        style={{
          minHeight: '100vh',
          color: '#fff',
          fontFamily:
            "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          padding: '2rem',
          textAlign: 'center',
          userSelect: 'none',
        }}
      >
        <h1
          style={{
            fontSize: '3rem',
            letterSpacing: '2px',
            textShadow: '2px 2px 6px rgba(0,0,0,0.4)',
            marginBottom: '0.5rem',
          }}
        >
          My Cool Website
        </h1>
        <p
          style={{
            fontSize: '1.25rem',
            color: '#cbd5e1',
            marginBottom: '2rem',
          }}
        >
          Welcome to a clean and modern front page
        </p>
        <button
          onClick={() => alert('You clicked the button!')}
          style={{
            padding: '0.75rem 2rem',
            fontSize: '1.2rem',
            color: '#182848',
            background: '#f6f6f6',
            borderRadius: '30px',
            border: 'none',
            cursor: 'pointer',
            boxShadow: '0 5px 15px rgba(246,246,246,0.6)',
            transition: 'background 0.3s ease, color 0.3s ease',
            userSelect: 'none',
          }}
          onMouseEnter={e => {
            (e.currentTarget as HTMLButtonElement).style.background = '#d1d5db';
            (e.currentTarget as HTMLButtonElement).style.color = '#0f172a';
          }}
          onMouseLeave={e => {
            (e.currentTarget as HTMLButtonElement).style.background = '#f6f6f6';
            (e.currentTarget as HTMLButtonElement).style.color = '#182848';
          }}
        >
          Get Started
        </button>
        <footer
          style={{
            marginTop: 'auto',
            fontSize: '0.9rem',
            color: '#94a3b8',
            marginTop: '3rem',
            userSelect: 'text',
          }}
        >
          &copy; 2025 My Cool Website. All rights reserved
          
        </footer>
      </div>
    </>
  );
};

export default ColorBallsPage;

More by Xingfing

View all
  • animal version12@

    animal version12@

More in Heroes

View all
  • SaaS Template

    SaaS Template

    2.4K
  • Responsive Hero Banner

    Responsive Hero Banner

    2K
  • Hero

    Hero

    1.2K
  • Centered Hero with Image Fan

    Centered Hero with Image Fan

    932
  • Editorial Collage Hero

    Editorial Collage Hero

    431
  • Glass Fold

    Glass Fold

    213
  • HeroSectionWithGradient

    HeroSectionWithGradient

    336
  • Minimalist Hero Fashion

    Minimalist Hero Fashion

    285