Docs
Circuit Pulse

Circuit Pulse

A modern tech-themed animated circuit component with pulsing dots and glowing paths.

Installation

Copy the following code to your project.

import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
import {
  Code2,
  Database,
  GitBranch,
  Terminal,
  LucideIcon,
  Blocks,
  Braces,
  Bug,
  FileCode2,
  Github,
  Container,
  Webhook,
  PackageOpen,
  Globe2,
} from "lucide-react";
 
interface CircuitPulseProps {
  className?: string;
  color?: string;
}
 
const pulseVariants = {
  dot1: {
    initial: { y: "-50%", x: "-50%" },
    animate: {
      y: ["-50%", "30%", "30%"],
      transition: {
        duration: 5,
        times: [0, 0.3, 1],
        repeat: Infinity,
        repeatDelay: 2,
        ease: "easeInOut",
      },
    },
  },
  dot2: {
    initial: { y: "-50%", x: "-50%" },
    animate: {
      y: ["-50%", "9.5%", "9.5%"],
      x: ["-50%", "-50%", "9.5%"],
      transition: {
        duration: 4,
        times: [0, 0.5, 1],
        repeat: Infinity,
        repeatDelay: 1.5,
        ease: "easeInOut",
      },
    },
  },
  dot3: {
    initial: { y: "-50%", x: "-50%" },
    animate: {
      y: ["-50%", "30%", "30%"],
      transition: {
        duration: 3.5,
        times: [0, 0.4, 1],
        repeat: Infinity,
        repeatDelay: 2.5,
        ease: "easeInOut",
      },
    },
  },
  dot4: {
    initial: { y: "-50%", x: "-50%" },
    animate: {
      y: ["-50%", "9.5%", "9.5%"],
      x: ["-50%", "-50%", "9.5%"],
      transition: {
        duration: 4.5,
        times: [0, 0.6, 1],
        repeat: Infinity,
        repeatDelay: 1.8,
        ease: "easeInOut",
      },
    },
  },
  glow: {
    initial: { opacity: 0.3 },
    animate: {
      opacity: [0.3, 0.6, 0.3],
      transition: { duration: 2, repeat: Infinity },
    },
  },
};
 
interface IconConfig {
  Icon: LucideIcon;
  position: string;
}
 
const icons: IconConfig[] = [
  { Icon: Github, position: "rotate-0" },
  { Icon: Code2, position: "rotate-45" },
  { Icon: Terminal, position: "rotate-90" },
  { Icon: Database, position: "rotate-135" },
  { Icon: Blocks, position: "rotate-180" },
  { Icon: Container, position: "rotate-[225deg]" },
  { Icon: FileCode2, position: "rotate-[270deg]" },
  { Icon: PackageOpen, position: "rotate-[315deg]" },
];
 
export function CircuitPulse({
  className,
  color = "#ff4545",
}: CircuitPulseProps) {
  return (
    <div className={cn("relative h-[80vmin] w-[80vmin]", className)}>
      <div className="absolute inset-0 overflow-hidden rounded-3xl"></div>
      {[...Array(8)].map((_, i) => (
        <div
          key={i}
          className={cn(
            "pointer-events-none absolute h-1/2 w-1/2",
            i < 4
              ? "left-1/2 top-0 origin-bottom -translate-x-1/2"
              : "left-0 top-0 origin-bottom-right",
            i === 1 && "rotate-90",
            i === 2 && "rotate-180",
            i === 3 && "rotate-[270deg]",
            i === 5 && "-scale-x-100",
            i === 6 && "-scale-100",
            i === 7 && "-scale-y-100",
          )}
        >
          <motion.div
            className={cn(
              "opacity-50",
              i < 4
                ? "h-full w-[calc(50%+1px)] border-r"
                : "absolute left-[calc(30%-1px)] top-[30%] h-[60%] w-[70%] rounded-br-xl border-b border-l",
            )}
            style={{ borderColor: color }}
            variants={pulseVariants.glow}
            initial="initial"
            animate="animate"
          />
          <motion.div
            className={cn(
              "absolute h-full w-full",
              i < 2
                ? "left-1/2 top-[10%]"
                : i < 4
                  ? "left-1/2 top-[10%]"
                  : i < 6
                    ? "left-[30%] top-[30%]"
                    : "left-[30%] top-[30%]",
            )}
            variants={
              i < 2
                ? pulseVariants.dot1
                : i < 4
                  ? pulseVariants.dot3
                  : i < 6
                    ? pulseVariants.dot2
                    : pulseVariants.dot4
            }
            initial="initial"
            animate="animate"
          >
            <motion.div
              className="absolute left-1/2 top-1/2 h-[9px] w-[9px] -translate-x-1/2 -translate-y-1/2 rounded-full"
              style={{
                backgroundColor: color,
                boxShadow: `0 0 10px ${color}`,
              }}
              variants={pulseVariants.glow}
            />
          </motion.div>
          <div
            className={cn(
              "absolute flex h-[40px] w-[40px] items-center justify-center rounded-full",
              i < 4
                ? "left-1/2 top-0 -translate-x-1/2"
                : "left-[30%] top-[30%] -translate-x-1/2 -translate-y-1/2",
            )}
            style={{
              backgroundColor: color,
              boxShadow: `0 0 15px ${color}`,
            }}
          >
            <div className={icons[i].position}>
              {React.createElement(icons[i].Icon, {
                className: "h-5 w-5 text-white",
              })}
            </div>
          </div>
        </div>
      ))}
      <div className="absolute left-1/2 top-1/2 h-[25%] w-[25%] -translate-x-1/2 -translate-y-1/2">
        <motion.div
          className="absolute left-1/2 top-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 rounded-full bg-black/90 shadow-lg"
          variants={pulseVariants.glow}
          initial="initial"
          animate="animate"
        />
        <motion.div
          className="absolute left-1/2 top-1/2 flex h-32 w-32 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full"
          style={{
            backgroundColor: color,
            boxShadow: `0 0 20px ${color}`,
          }}
        >
          <Globe2 className="size-16 text-white" />
        </motion.div>
      </div>
    </div>
  );
}

Update the import paths to match your project setup.

import CircuitPulse from "@/components/ui/circuit-pulse";

Usage

export default function Example() {
  return (
    <div className="relative min-h-[400px]">
      <CircuitPulse />
    </div>
  );
}

Examples

Custom Color

You can customize the color of the circuit paths and dots.

<CircuitPulse color="#4545ff" />

Background Integration

For the best visual effect, place the component in a container with a gradient background:

<div className="relative z-30 grid min-h-screen grid-cols-1 gap-8 overflow-hidden bg-linear-to-b from-background via-background to-black/50 p-8">
  <div className="relative flex min-h-[400px] items-center justify-center">
    <CircuitPulse />
  </div>
</div>

Props

PropertyTypeDefaultDescription
colorstring#ff4545The color of the circuit paths, dots, and icons. Accepts any valid CSS color value.
classNamestring-Additional CSS classes to apply to the root element.

Features

  • Four unique dot animations with different timing patterns
  • Glowing paths and dots with customizable colors
  • Responsive design that scales with container
  • Dark mode compatible
  • Eight tech-themed icons arranged in a circuit pattern
  • Smooth transitions and animations

Accessibility

The component is purely decorative and does not require any interaction. All animations are subtle and should not trigger motion sickness.