岛屿菜单
一粒导航药丸分两步展开成菜单。它先长高——一块黑板从药丸上立起来,药丸的三个控件依然钉在板的底部;然后变宽;直到盒子长到菜单的尺寸,菜单才在盒子里现身:链接一个接一个,邮箱跟在后面,图片最后。
高度和宽度放在同一个时钟上,是一个矩形在缩放,眼睛读成一次 zoom,跟不住。先一个轴、再另一个轴,是一个东西在展开,而且顺序本身携带信息:先向上,说明菜单是从药丸里长出来的,而不是凭空出现的。
但两个轴不能首尾相接。第一段走完再启动第二段,盒子会在转角处停死一下再重新起步,读起来是两段动画。让第二段在第一段的最后三分之一处接上,转角就变成了曲线。
出去的时候顺序必须翻转。一个先长高再变宽的菜单,收起时应该先缩宽再缩矮,否则它离开路上经过的形状是它进来时从未有过的形状,关闭读起来就像另一个东西离开了。内容在两个方向上都先走,因为盒子不应该围着一圈还在的文字改变尺寸。
药丸的控件从头到尾没有移动。它们钉在盒子的底部,随它一起升起来,所以该关闭的时候,读者的手还停在打开它的那个按钮上。按钮的图标在和盒子同一个时钟里从胶囊变成方块,文字从 Menu 变成 Close。
用 React + motion/react 做一个会展开成菜单的导航药丸:初始是 340×52 的近黑圆角胶囊(圆角 26px),上面是品牌字、Menu 字样和一个小图标。点击后分三步打开——(1) 盒子先只变高度(0.36s cubic-bezier(0.4,0,0.2,1) 长到 280px、圆角收到 22px),像一块黑板从药丸上立起来,Menu 控件钉在盒子底部随之上升;(2) 宽度在高度走完约 70% 时启动(同样 0.36s,长到 460px),两个轴刻意重叠 30%——首尾相接的话盒子会在转角处停死再重新起步,读起来是两段动画而不是一个形状在展开,让第二段在第一段的最后三分之一处接上,转角就变成了曲线;(3) 盒子到达菜单尺寸后内容才进入:三个链接依次从下方滑入(每个间隔 50ms,y 10→0 配合 blur(4px)→0),然后一行邮箱地址,最后一张图片卡片。关闭时顺序整个翻转:内容先整体退出(0.2s),再缩宽度、再缩高度,保证出去路上经过的形状都是进来时出现过的形状;控件图标在同一时钟内从胶囊形变成方块,文字从 Menu 变为 Close,Escape 键随时可关。色板只允许近黑底、纸白文字和暖灰,唯一强调是 hover 时的半透明纸白。