Dynamic gauge

Animate the needle of a gauge based on a dynamic value. Useful for speedometer-like gadgets that need to react to data.

Try it out by moving the slider.

Options

Markers off
Gradient on
Colored needle
Colors, minimal
Colors, markers
Full colors

Example: Speedometer

Use with live display of speed in a dashboard style. These use the Orbitron font for the numbers and units.

214
km/h
134
mph

Source code: dashboard

import { cn } from "@/lib/utils";
import DynamicGauge from "@/components/dynamic-gauge";

export function Speedometer({ value }: { value: number }) {
  return (
    <div
      className={cn(
        "inline-flex justify-center items-center gap-4 sm:gap-8 text-foreground",
        "border-4 rounded-full border-foreground bg-accent py-3 sm:py-6 px-12 mx-auto",
      )}
    >
      <DynamicGauge
        className="w-18 sm:w-28 sm:mx-auto"
        hideMarkers
        value={value}
      />
      <div className="w-24 sm:w-40 font-orbitron text-3xl sm:text-5xl font-medium">
        {value.toFixed(0)}
        <br />
        km/h
      </div>
    </div>
  );
}

Source code: dashboard with glow

import { cn } from "@/lib/utils";
import DynamicGauge from "@/components/dynamic-gauge";
import chroma from "chroma-js";

export function Speedometer({ value }: { value: number }) {
  const scale = chroma.scale([
    "oklch(0.723 0.219 149.579)", // --color-green-500
    "oklch(0.795 0.184 86.047)", // --color-yellow-500
    "oklch(0.637 0.237 25.331)", // --color-red-500
  ]);

  return (
    <div
      className={cn(
        "inline-flex justify-center items-center gap-4 sm:gap-8 text-foreground",
        "border-4 rounded-full border-foreground bg-accent py-3 sm:py-6 px-12 mx-auto",
      )}
      style={{
        boxShadow: `0 0 ${Math.floor((30 * value) / 100).toString()}px ${scale(value / 100).css()}`,
      }}
    >
      <DynamicGauge
        className="w-18 sm:w-28 sm:mx-auto"
        hideMarkers
        value={value}
      />
      <div className="w-24 sm:w-40 font-orbitron text-3xl sm:text-5xl font-medium">
        {value.toFixed(0)}
        <br />
        km/h
      </div>
    </div>
  );
}

Installation