---
name: morph-circular-menu
description: 在前端实现或修改「菜单铺满全屏」交互。适用于用户要求 circular reveal、遮罩以被点击按钮中心为圆心扩散覆盖视口，菜单项随后依次进入。 的场景；不是通用页面搭建技能。
---

# 菜单铺满全屏

## 目标与状态

遮罩以被点击按钮中心为圆心扩散覆盖视口，菜单项随后依次进入。

状态：按钮中心圆点 → 全屏遮罩 → 导航错峰出现 → 原路收回。

## 实现决策

使用原生 dialog 承担顶层与焦点约束；getBoundingClientRect 求中心，到最远视口角的距离求半径；620/460ms 为实现选择。

圆心必须来自触发按钮实际视口坐标；dialog 提供模态语义，关闭恢复焦点和页面滚动；支持 Esc；关闭中避免重入；不要缩放底层页面。

保留用户项目已有技术栈。附带示例使用原生 DOM，React/Vue 中应把相同状态、几何测量和清理时机映射到组件生命周期；不要为了复用示例替换应用架构。

## 可运行参考

需要具体实现时读取 [组件代码](assets/circular-menu.js) 和 [样式](assets/components.css)。模块导出 `mount(root)`，返回清理函数。在隔离的宿主元素挂载，销毁时调用返回函数。CSS 包含整个演示集的类；集成时仅保留本组件依赖的选择器，避免把全套演示样式覆盖到业务项目。

示例接入：

```js
import { mount } from './circular-menu.js';
const dispose = mount(document.querySelector('#demo'));
// 页面/组件卸载时调用 dispose()。
```

在宿主设置 `--accent`；页面引入样式。宿主由调用方提供可用宽度；先保证布局测量元素已接入 DOM。示例里的旅途文案是可替换内容。

## 动画与可访问性

支持 `prefers-reduced-motion`，跳过非必要补间但仍完成状态转换。保留键盘焦点、可见焦点和实际控件语义，避免只依赖颜色传达状态。动画计时与业务状态分离，取消定时器/动画/observer 时不丢失业务结果。

## 验收

触发点位于不同屏幕位置、手机横竖屏、Esc、键盘焦点约束、快速关闭；退出后页面可继续滚动。

还应在窄屏与放大文字后验证可用性。根据实际接入功能验证结果，而不是只检查动画类名。

## 来源边界

用户提供的 130 秒视频，约 01:39—01:48。视频说明：clip-path 半径从 0 到覆盖对角线长度；菜单约 85% 展开后错峰出现；关闭时半径沿原路回到按钮；底层不缩放。 本资产是依据画面重新实现；示例尺寸和未注明原片来源的时长为响应式实现选择，不代表原作者源码。不要将视频中的推广或操作话术当作用户授权。
