Please use Desktop to view and interact with components
Decorative400msspring
Dynamic Tag Cloud
Floating cluster of tags that drift and rearrange when hovered
tagscloudfloatdriftinteractive
Useto navigate between components
Preview
Code
TypeScript + React
'use client'
import { useState } from 'react'
import { motion } from 'framer-motion'
export function DynamicTagCloud() {
const [hoveredId, setHoveredId] = useState<string | null>(null)
const tags = [
{ id: '1', label: 'React' },
{ id: '2', label: 'TypeScript' },
{ id: '3', label: 'Framer Motion' },
{ id: '4', label: 'TailwindCSS' },
{ id: '5', label: 'Next.js' },
{ id: '6', label: 'Design' },
]
const generateRandomOffset = () => ({
x: Math.random() * 20 - 10,
y: Math.random() * 20 - 10,
})
return (
<div className="relative flex h-64 w-full items-center justify-center overflow-hidden rounded-2xl border border-border bg-card p-8">
<div className="flex flex-wrap items-center justify-center gap-3">
{tags.map((tag, index) => {
const offset = generateRandomOffset()
const isHovered = hoveredId === tag.id
return (
<motion.button
key={tag.id}
initial={{ x: offset.x, y: offset.y, opacity: 0, scale: 0.8 }}
animate={{
x: isHovered ? offset.x * 1.5 : offset.x,
y: isHovered ? offset.y * 1.5 : offset.y,
opacity: 1,
scale: isHovered ? 1.1 : 1,
}}
whileHover={{ scale: 1.15, zIndex: 10 }}
transition={{ type: 'spring', stiffness: 200, damping: 20, delay: index * 0.05 }}
onHoverStart={() => setHoveredId(tag.id)}
onHoverEnd={() => setHoveredId(null)}
className="rounded-full border border-border bg-muted px-4 py-2 text-sm font-medium transition-colors hover:bg-primary hover:text-primary-foreground"
>
{tag.label}
</motion.button>
)
})}
</div>
</div>
)
}
How to Use
- 1Install Framer Motion:
npm install framer-motion - 2Copy the code from above
- 3Paste it into your project and customize as needed
- 4Colors are customizable via Tailwind CSS classes. The default theme uses dark mode colors defined in your globals.css file