Morphing Card
ui-beats/morphing-cardFreeComponent
The MorphingCard component creates an engaging, interactive card that smoothly transitions between different shapes and content. It features elegant 3D rotations, customizable gradients, and a clean design that's perfect for showcasing key information or features in a visually striking manner.
Install it
npx shadcn@latest add https://uibeats.com/r/morphing-card.jsonSource
1import React, { useState, useEffect, useCallback } from "react";2import { motion, AnimatePresence } from "motion/react";3import { ArrowRight, Pause, Play } from "lucide-react";4import { useTheme } from "next-themes";56type Shape = "rectangle" | "circle" | "hexagon";78interface MorphingCardProps {9 width?: string;10 height?: string;11 contents: Array<{12 shape: Shape;13 title: string;14 description: string;15 }>;16 colorScheme?: {17 from: string;18 to: string;19 };20 autoPlay?: boolean;21 interval?: number;22}2324const shapeVariants = {25 rectangle: { borderRadius: "16px", rotate: 0 },26 circle: { borderRadius: "50%", rotate: 120 },27 hexagon: { borderRadius: "24% 76% 24% 76% / 32% 32% 68% 68%", rotate: 240 },28};2930const MorphingCard: React.FC<MorphingCardProps> = ({31 width = "300px",32 height = "300px",33 contents,34 colorScheme = { from: "#4F46E5", to: "#7C3AED" },35 autoPlay = true,36 interval = 3000,37}) => {38 const [currentIndex, setCurrentIndex] = useState(0);39 const [isPlaying, setIsPlaying] = useState(autoPlay);4041 const nextShape = useCallback(() => {42 setCurrentIndex((prevIndex) => (prevIndex + 1) % contents.length);43 }, [contents.length]);4445 useEffect(() => {46 let timer: NodeJS.Timeout;47 if (isPlaying) {48 timer = setInterval(nextShape, interval);49 }50 return () => clearInterval(timer);51 }, [isPlaying, interval, nextShape]);5253 const currentContent = contents[currentIndex];54 const { theme, systemTheme } = useTheme();5556 // `contents` is caller-supplied; an empty array would otherwise crash here.57 if (!currentContent) return null;5859 const currentTheme = theme === "system" ? systemTheme : theme;6061 return (62 <div className="relative" style={{ width, height }}>63 <motion.div64 className="absolute inset-0 cursor-pointer overflow-hidden rounded-2xl shadow-lg"65 style={{66 background: `linear-gradient(135deg, ${colorScheme.from}, ${colorScheme.to})`,67 }}68 animate={shapeVariants[currentContent.shape]}69 transition={{ duration: 0.8, ease: [0.4, 0, 0.2, 1] }}70 whileHover={{ scale: 1.05 }}71 whileTap={{ scale: 0.95 }}72 >73 {/* This empty div will handle the shape morphing */}74 </motion.div>75 <div className="absolute inset-0 flex items-center justify-center">76 <AnimatePresence mode="wait">77 <motion.div78 key={currentIndex}79 className="flex h-full w-full flex-col items-center justify-center p-6"80// … truncated
What it pulls in
npm packages
Files it writes
More from ui-beats
All 34 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Beamanimated-beam | ui-beats | Components | Free | 1 dep | |
| Animated Listanimated-list | ui-beats | Components | Free | 1 dep | |
| Border Beamborder-beam | ui-beats | Components | Free | 1 dep | |
| Bouncebounce | ui-beats | Components | Free | 1 dep | |
| Card Stackcard-stack | ui-beats | Components | Free | 1 dep | |
| Dockdock | ui-beats | Components | Free | 1 dep | |
| Fade Infade-in | ui-beats | Components | Free | 1 dep | |
| Fade In Unblurfade-in-unblur | ui-beats | Components | Free | 1 dep |
