Images dissolve into each other with a soft melt. Step the index with a button. Tune duration and intensity.
1.1s
0.55
2.4
0.35
tsx
"use client"import { useState } from "react"import { Morph } from "@/components/motion/morph"import { Button } from "@/components/ui/button"const IMAGES = [ "/assets/brand/demos/attachments/attachment-1.png", "/assets/brand/demos/attachments/attachment-2.png", "/assets/brand/demos/attachments/attachment-3.png", "/assets/brand/demos/attachments/attachment-4.png"]export function Example() { const [index, setIndex] = useState(0) return ( <div className="flex flex-col items-center gap-6"> <Morph items={IMAGES} index={index} duration={1.1} intensity={0.55} scale={2.4} aberration={0.35} className="aspect-[4/3] w-full max-w-md" /> <Button variant="outline" onClick={() => setIndex((current) => (current + 1) % IMAGES.length)} > Morph </Button> </div> )}Installation
npx @arctis-sh/@arctis-sh/ui@latest add morphUsage
import { useState } from "react"import { Morph } from "@/components/motion/morph"import { Button } from "@/components/ui/button"const [index, setIndex] = useState(0)<> <Morph items={["/one.png", "/two.png", "/three.png"]} index={index} className="aspect-[4/3] w-full max-w-md" /> <Button onClick={() => setIndex((i) => (i + 1) % 3)}>Morph</Button></>API Reference
Morph
| Prop | Type | Default |
|---|---|---|
| items | (string | { src: string; alt?: string })[] |
| index | number | 0 |
| duration | number | 1.1 |
| intensity | number | 0.55 |
| scale | number | 2.4 |
| aberration | number | 0.35 |
| drift | number | 0.4 |
| overlayColor | string | "#05060a" |
| radius | number | 16 |
| className | string | — |
Also accepts the other native div attributes. Duration is in seconds. Uses ogl for the WebGL melt.