Frontend Lab
← 回到所有模式
PC06🧭 Navigation · 導航Dock

Floating Dock

浮動 Dock

難度 ★★★★標籤 dock · magnify · macOS3 min read

模式簡述

Floating Dock:macOS 風格的浮動工具列,滑鼠靠近會放大圖標。視覺上很 ‘Apple’,操作上其實要克制。

預設|等寬 icon 排列

Claude Code Prompt

💬 Claude Code Prompt
參考:PC06 floating-dock
組件:FloatingDock.tsx

Floating Dock:macOS 風格的浮動工具列,滑鼠靠近會放大圖標。視覺上很 ‘Apple’,操作上其實要克制。

限制:
- magnify 太誇張
- 鄰居沒跟著推開
- 移開後沒復原動畫

完整程式碼

FloatingDock.tsx
"use client";
import { useRef, useState } from "react";
import { motion, useMotionValue, useSpring, useTransform } from "framer-motion";
import { Home, Folder, Search, Settings, User, Mail, Music } from "lucide-react";

type State = "idle" | "hover";

const ICONS = [Home, Folder, Search, Mail, Music, User, Settings];

function DockIcon({
Icon,
mouseX,
}: {
Icon: typeof Home;
mouseX: ReturnType<typeof useMotionValue<number>>;
}) {
const ref = useRef<HTMLDivElement>(null);
const distance = useTransform(mouseX, (v) => {
  const bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 };
  return v - bounds.x - bounds.width / 2;
});
const widthSync = useTransform(distance, [-100, 0, 100], [36, 56, 36]);
const width = useSpring(widthSync, { mass: 0.1, stiffness: 200, damping: 14 });

return (
  <motion.div
    ref={ref}
    style={{ width, height: width }}
    className="grid aspect-square place-items-center rounded-lg bg-background/60 border border-border/60"
  >
    <Icon className="h-1/2 w-1/2 text-muted-foreground" />
  </motion.div>
);
}

export function FloatingDock({ state = "idle" }: { state?: State }) {
const mouseX = useMotionValue(state === "hover" ? 200 : Infinity);
return (
  <div className="grid h-[200px] w-full max-w-md place-items-end">
    <motion.div
      onMouseMove={(e) => mouseX.set(e.clientX)}
      onMouseLeave={() => mouseX.set(Infinity)}
      className="mb-4 flex items-end gap-2 rounded-2xl border border-border bg-background/50 px-3 py-2 backdrop-blur"
    >
      {ICONS.map((Icon, i) => (
        <DockIcon key={i} Icon={Icon} mouseX={mouseX} />
      ))}
    </motion.div>
  </div>
);
}

何時用

  • ✅ 想做 macOS 風格的 portfolio / brand 站
  • ✅ 工具列項目 ≤ 8 個
  • ✅ 桌面端為主

何時別用

  • ❌ 手機端(沒 hover,magnify 無意義)
  • ❌ 需要文字標籤(dock 太擠塞不下)
  • ❌ 嚴肅商務介面(太花俏)

我踩過的坑

  1. magnify 太誇張:放大 2x 看起來像玩具,1.4x 剛好。

  2. 鄰居沒跟著推開:應該整個 row 重新排列,否則重疊。

  3. 移開後沒復原動畫:spring 還原比直接跳更舒服。

相關模式

  • PC07
  • PG10

搜尋

按 ⌘K 隨時開啟