motion实现layout share动画

34 阅读1分钟

懒得码字了

import { motion, AnimatePresence, LayoutGroup } from 'motion/react'
import { useState } from 'react'

const list = [
  'https://picsum.photos/id/10/800/400',
  'https://picsum.photos/id/32/1200/300',
  'https://picsum.photos/id/73/600/1000',
  'https://picsum.photos/id/98/900/1080',
  'https://picsum.photos/id/78/1200/300',
  'https://picsum.photos/id/67/600/1000'
]

export default function App() {
  const [selectedItem, setSelectedItem] = useState('')
  return (
    <LayoutGroup>
      <div className="grid grid-cols-6 gap-4">
        {list.map(item => (
          <motion.img layoutId={item} key={item} src={item} className="rounded-2xl size-100 object-cover" onClick={() => setSelectedItem(item)} />
        ))}
      </div>

      <AnimatePresence>{selectedItem && <Detail item={selectedItem} onClose={() => setSelectedItem('')} />}</AnimatePresence>
    </LayoutGroup>
  )
}

function Detail({ item, onClose }: { item: string; onClose: () => void }) {
  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      className="fixed inset-0 z-9999 bg-black/40 backdrop-blur-sm flex items-center justify-center" 
    >
      <motion.img
        className="object-scale-down rounded-2xl"
        layoutId={item}
        src={item}
        onClick={onClose}
      />
    </motion.div>
  )
}