Skip to main content
This snippet demonstrates how to create an animated histogram (bar chart) with spring animations, glowing effects, and dynamic value labels.

What This Snippet Demonstrates

  • Creating bar charts with @remotion/shapes
  • Spring animations with staggered delays
  • Dynamic height calculations based on data values
  • Glowing effects using CSS filters
  • Animated counter text that scales with the bars

Complete Code

import { AbsoluteFill, useCurrentFrame, useVideoConfig, spring } from "remotion";
import { Rect } from "@remotion/shapes";

export const MyAnimation = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  const data = [
    { label: "Mon", value: 65, color: "#6366f1" },
    { label: "Tue", value: 85, color: "#8b5cf6" },
    { label: "Wed", value: 45, color: "#a855f7" },
    { label: "Thu", value: 95, color: "#d946ef" },
    { label: "Fri", value: 75, color: "#ec4899" },
  ];

  const maxValue = Math.max(...data.map(d => d.value));
  const barWidth = 80;

  return (
    <AbsoluteFill
      style={{
        backgroundColor: "#0a0a0a",
        justifyContent: "center",
        alignItems: "flex-end",
        padding: 60,
        paddingBottom: 100,
      }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "flex-end",
          gap: 24,
          height: 400,
          width: "100%",
          justifyContent: "center",
        }}
      >
        {data.map((item, i) => {
          const delay = i * 10;
          const progress = spring({
            frame: frame - delay,
            fps,
            config: { damping: 15, stiffness: 100 },
          });

          const height = Math.max(1, (item.value / maxValue) * 300 * progress);

          return (
            <div key={i} style={{ textAlign: "center", position: "relative" }}>
              <div style={{ position: "relative", height, width: barWidth }}>
                <Rect
                  width={barWidth}
                  height={height}
                  fill={item.color}
                  cornerRadius={12}
                  style={{ filter: `drop-shadow(0 0 8px ${item.color}50)` }}
                />
                <span
                  style={{
                    position: "absolute",
                    top: 10,
                    left: "50%",
                    transform: "translateX(-50%)",
                    color: "#fff",
                    fontSize: 18,
                    fontWeight: "bold",
                    opacity: progress,
                    fontFamily: "system-ui, sans-serif",
                  }}
                >
                  {Math.round(item.value * progress)}
                </span>
              </div>
              <div
                style={{
                  color: "#888",
                  fontSize: 16,
                  marginTop: 12,
                  fontFamily: "system-ui, sans-serif",
                }}
              >
                {item.label}
              </div>
            </div>
          );
        })}
      </div>
    </AbsoluteFill>
  );
};

Key Concepts

Staggered Animation

Each bar animates in sequence with a 10-frame delay:
const delay = i * 10;
const progress = spring({
  frame: frame - delay,
  fps,
  config: { damping: 15, stiffness: 100 },
});

Dynamic Height Calculation

Bar heights are normalized to the maximum value and scaled by progress:
const maxValue = Math.max(...data.map(d => d.value));
const height = Math.max(1, (item.value / maxValue) * 300 * progress);

Glowing Effect

The drop shadow uses the bar’s color with 50% opacity:
style={{ filter: `drop-shadow(0 0 8px ${item.color}50)` }}

Animated Counter

The value text counts up as the bar grows:
{Math.round(item.value * progress)}

When to Use This Pattern

  • Presenting business metrics and analytics
  • Showing weekly or monthly performance data
  • Visualizing survey results or poll data
  • Creating data-driven social media content
  • Educational content about statistics and data visualization
  • Product demos showing usage trends

Customization Tips

  • Replace the data array with your own dataset
  • Adjust the delay multiplier for faster/slower staggered animation
  • Change barWidth and maximum height (currently 300) to fit your composition
  • Customize colors to match your brand palette
  • Add gridlines or axis labels for more detailed charts
  • Use different spring configs for different animation feels

Build docs developers (and LLMs) love