shadimage
grootstudio
blockanimated-barssource: ok · refreshed

Animated Bars

A dynamic background component with pulsating, gradient bars that create a fluid energy effect.

npx shadcn add "https://grootstudio.vercel.app/r/animated-bars.json"
free

Visual style

gradient

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Files1 · source cached 10/8/2026, 3:00:58 AM

registry/radix-nova/animated-bars/animated-bars.tsx
"use client";

import React from 'react';
import { cn } from "@/lib/utils";

interface AnimatedBarsProps {
    numBars?: number;
    gradientFrom?: string;
    gradientTo?: string;
    animationDuration?: number;
    className?: string;
}

const GradientBars: React.FC<AnimatedBarsProps> = ({
    numBars = 20,
    gradientFrom = '#f43f5e',
    gradientTo = 'transparent',
    animationDuration = 3,
    className = '',
}) => {
    const calculateHeight = (index: number, total: number) => {
        const position = index / (total - 1);
        const maxHeight = 100;
        const minHeight = 40;

        const center = 0.5;
        const distanceFromCenter = Math.abs(position - center);
        const heightPercentage = Math.pow(distanceFromCenter * 2, 1.5);

        return minHeight + (maxHeight - minHeight) * heightPercentage;
    };

    return (
        <>
            <style>{`
        @keyframes fluidWave {
          0% { 
            transform: scaleY(var(--initial-scale)); 
            opacity: 0.4;
            filter: brightness(1);
          }
          50% { 
            transform: scaleY(calc(var(--initial-scale) * 1.15)); 
            opacity: 0.8;
            filter: brightness(1.2);
          }
          100% { 
            transform: scaleY(calc(var(--initial-scale) * 0.9)); 
            opacity: 0.5;
            filter: brightness(0.9);
          }
        }
      `}</style>

            <div className={cn("absolute inset-0 z-0 overflow-hidden pointer-events-none", className)}>
                <div
                    className="flex h-full items-end"
                    style={{
                        width: '100%',
                        transform: 'translateZ(0)',
                        backfaceVisibility: 'hidden',
                    }}
                >
                    {Array.from({ length: numBars }).map((_, index) => {
                        const height = calculateHeight(index, numBars);
                        return (
                            <div
                                key={index}
                                className="relative"
                                style={{
                                    flex: 1,
                                    marginLeft: index === 0 ? '0' : '-1px',
                                    height: '100%',
                                    background: `linear-gradient(to top, ${gradientFrom}, ${gradientTo})`,
                                    transform: `scaleY(${height / 100})`,
                                    transformOrigin: 'bottom',
                                    animation: `fluidWave ${animationDuration}s ease-in-out infinite alternate`,
                                    animationDelay: `-${index * (animationDuration / numBars)}s`,
                                    // @ts-ignore
                                    '--initial-scale': height / 100,
                                }}
                            />
                        );
                    })}
                </div>
            </div>
        </>
    );
};

interface AnimatedBarsBackgroundProps {
    numBars?: number;
    gradientFrom?: string;
    gradientTo?: string;
    animationDuration?: number;
    backgroundColor?: string;
    children?: React.ReactNode;
    className?: string;
}

export function AnimatedBars({
    numBars = 12,
    gradientFrom = '#f43f5e',
    gradientTo = 'transparent',
    animationDuration = 4,
    backgroundColor,
    children,
    className,
}: AnimatedBarsBackgroundProps) {
    return (
        <section
            className={cn("relative min-h-[400px] w-full flex flex-col items-center justify-center overflow-hidden rounded-lg border bg-background", className)}
            style={backgroundColor ? { backgroundColor } : undefined}
        >
            <GradientBars
                numBars={numBars}
                gradientFrom={gradientFrom}
                gradientTo={gradientTo}
                animationDuration={animationDuration}
            />

            {children && (
                <div className="relative z-10 w-full h-full flex items-center justify-center px-4">
                    {children}
                </div>
            )}
        </section>
    );
}

More from grootstudio

Browse all components in this library →