MelonBlog

使用framer-motion实现一个悬浮球组件

最近在使用shadcn ui 这个库,非常喜欢这个库的UI风格,黑白简约风格,但是当我想要一个悬浮球功能的时候,我发现shadcn ui没有提供,所以我就自己通过framer-motion库实现了一个简单的悬浮球组件


基于next.js + framer-motion库,图标使用的是lucide-react


'use client';
import {useState} from 'react';
import {motion, AnimatePresence} from 'framer-motion';
import {ChevronUp, Menu, X} from 'lucide-react';
export default function FloatingBall() {
  const [open, setOpen] = useState(false);
  const handleBackToTop = () => {
    window.scrollTo({top: 0, behavior: 'smooth'});
    setOpen(false);
  };
  return (
    <div className="fixed bottom-6 right-6 z-50">
      {/* Action Buttons */}
      <AnimatePresence>
        {open && (
          <motion.div
            className="flex flex-col items-end space-y-3 mb-4"
            initial={{opacity: 0, y: 20}}
            animate={{opacity: 1, y: 0}}
            exit={{opacity: 0, y: 20}}
          >
            <button
              onClick={handleBackToTop}
              className="p-3 bg-black text-white rounded-full shadow-md hover:bg-black/80 transition"
              title="返回顶部"
            >
              <ChevronUp size={20}/>
            </button>
            {/* 你可以在这里添加更多按钮 */}
          </motion.div>
        )}
      </AnimatePresence>
      {/* Main Ball Button */}
      <button
        onClick={() => setOpen(!open)}
        className="p-3 bg-black text-white rounded-full shadow-lg hover:bg-black/80 transition"
        title="菜单"
      >
        {open ? <X size={20}/> : <Menu size={20}/>}
      </button>
    </div>
  );
}