JSFiddle - React, Tailwind, and code Playground

by carlhong

HTML

<div id="root">

</div>

CSS

.bubbles-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #000;
}

.bubble {
  position: absolute;
  border-radius: 50%;
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
  animation: pulse 5s infinite ease-in-out;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
}

React

import React from "react";
import ReactDOM from "react-dom";
import React, { useEffect, useRef } from "react";
import "./BubblesScreensaver.css";

const numBubbles = 50; // Total number of bubbles
const minBubbleSize = 50; // Minimum bubble diameter
const maxBubbleSize = 200; // Maximum bubble diameter
const speedMultiplier = 0.5; // Adjust movement speed

const BubblesScreensaver = () => {
  const containerRef = useRef(null);
  const bubbles = useRef([]);

  const getRandom = (min, max) => Math.random() * (max - min) + min;

  const createBubble = (containerWidth, containerHeight) => {
    const size = getRandom(minBubbleSize, maxBubbleSize);
    const position = {
      x: getRandom(0, containerWidth - size),
      y: getRandom(0, containerHeight - size),
    };
    const direction = {
      dx: getRandom(-1, 1),
      dy: getRandom(-1, 1),
    };

    const bubble = document.createElement("div");
    bubble.className = "bubble";
    bubble.style.width = `${size}px`;
    bubble.style.height = `${size}px`;
    bubble.style.left = `${position.x}px`;
    bubble.style.top = `${position.y}px`;
    bubble.style.background = `radial-gradient(circle, rgba(255, 255, 255, 0.8), rgba(0, 0, 255, 0.5))`;
    bubble.style.opacity = getRandom(0.5, 1);

    return { bubble, size, position, direction };
  };

  const updateBubbles = (containerWidth, containerHeight) => {
    bubbles.current.forEach(({ bubble, size, position, direction }) => {
      position.x += direction.dx * speedMultiplier;
      position.y += direction.dy * speedMultiplier;

      // Reverse direction on collision with container edges
      if (position.x <= 0 || position.x + size >= containerWidth) {
        direction.dx *= -1;
      }
      if (position.y <= 0 || position.y + size >= containerHeight) {
        direction.dy *= -1;
      }

      // Update DOM
      bubble.style.left = `${position.x}px`;
      bubble.style.top = `${position.y}px`;
    });
  };

  const animate = () => {
    const container...