Motion-Primitives

Image Comparison

Install component

npxshadcn@latest add "https://21st.dev/r/motion-primitives/image-comparison"
"use client"

import * as React from "react"
import {
  ImageComparison,
  ImageComparisonImage,
  ImageComparisonSlider,
} from "@/components/ui/image-comparison"

export function BasicDemo() {
  return (
    <ImageComparison className="aspect-[16/10] w-full rounded-lg border border-zinc-200 dark:border-zinc-800">
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_dark.png"
        alt="Motion Primitives Dark"
        position="left"
      />
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_light.png"
        alt="Motion Primitives Light"
        position="right"
      />
      <ImageComparisonSlider className="bg-white" />
    </ImageComparison>
  )
}

export function HoverDemo() {
  return (
    <ImageComparison
      className="aspect-[16/10] w-full rounded-lg border border-zinc-200 dark:border-zinc-800"
      enableHover
    >
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_dark.png"
        alt="Motion Primitives Dark"
        position="left"
      />
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_light.png"
        alt="Motion Primitives Light"
        position="right"
      />
      <ImageComparisonSlider className="bg-white" />
    </ImageComparison>
  )
}

export function SpringDemo() {
  return (
    <ImageComparison
      className="aspect-[16/10] w-full rounded-lg border border-zinc-200 dark:border-zinc-800"
      enableHover
      springOptions={{
        bounce: 0.3,
      }}
    >
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_dark.png"
        alt="Motion Primitives Dark"
        position="left"
      />
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_light.png"
        alt="Motion Primitives Light"
        position="right"
      />
      <ImageComparisonSlider className="w-0.5 bg-white/30 backdrop-blur-sm" />
    </ImageComparison>
  )
}

export function CustomSliderDemo() {
  return (
    <ImageComparison className="aspect-[16/10] w-full rounded-lg border border-zinc-200 dark:border-zinc-800">
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_dark.png"
        alt="Motion Primitives Dark"
        position="left"
      />
      <ImageComparisonImage
        src="https://motion-primitives.com/mp_light.png"
        alt="Motion Primitives Light"
        position="right"
      />
      <ImageComparisonSlider className="w-2 bg-white/50 backdrop-blur-sm transition-colors hover:bg-white/80">
        <div className="absolute left-1/2 top-1/2 h-8 w-6 -translate-x-1/2 -translate-y-1/2 rounded-[4px] bg-white" />
      </ImageComparisonSlider>
    </ImageComparison>
  )
}

export const demos = [
  {
    name: "Basic",
    description: "Basic image comparison with default settings",
    component: BasicDemo,
  },
  {
    name: "Hover",
    description: "Image comparison with hover interaction enabled",
    component: HoverDemo,
  },
  {
    name: "Spring Animation",
    description: "Image comparison with spring animation effect",
    component: SpringDemo,
  },
  {
    name: "Custom Slider",
    description: "Image comparison with custom slider design",
    component: CustomSliderDemo,
  }
]