// floating-glossy-label-pills — Glossy Pills Carousel 高光胶囊横滑走廊(motion-lab 定稿转原生 Remotion) // 白底四角强调色雾霭,四块浅灰 dashboard 占位 mockup(三栏卡片 / 折线图仪表盘 / // 列表表格 / 表单+开关列表)横向排队,各顶一枚高光强调色胶囊标签(Feature A–D); // 轨道环形循环,任一拍居中面板左右都露出相邻面板边缘。开场有上一拍收尾余量 // (偏左 11px 缓归位),随后轨道三拍向右换位(t≈0.20/0.483/0.688,inOutCubic, // 第一拍带长尾)——居中者放大清晰,两侧缩至 0.62、下沉变淡微模糊;t≈0.717 黑色 // 描白边光标右上硬现,减速斜滑向左下,t≈0.90 停在末位胶囊右端。 // 整卡唯一色相来源是 ACCENT 及其深浅档,按项目品牌色替换即换肤。 // 设计坐标 480×270(DesignStage 等比放大),参数表数值以此坐标系标定。 import React from 'react'; import { DesignStage, E, lerp, rand, seg, useT } from '../../_fixtures/Motion'; export const FLOATING_GLOSSY_LABEL_PILLS_DURATION = 120; // 4000ms @30fps // ── 模板强调色:实际使用时按项目品牌色替换这一组变量 ── const ACCENT = '#7a8699'; // 中性蓝灰做默认演示色 const ACCENT_LIGHT = '#a8b2c0', ACCENT_DEEP = '#4c5666'; const A_RGB = '122,134,153', AL_RGB = '168,178,192', AD_RGB = '76,86,102'; const F = '-apple-system,BlinkMacSystemFont,sans-serif'; // 逐帧实测(480×270 裁切系): // 居中面板 x 105-357(W≈252)、top=75,下缘正好压住画面底 → 真高 H≈195 // 邻位(静止)面板 x -70..86(缩到 0.62)、top=126 → 缩放 + 下沉 51px // 相邻两块中心距 SP≈232 // 内部 UI 按 330×255 的内容坐标书写,再整体等比 scale 到 252×195 const CW = 330, CH = 255, CS = 252 / CW; const W = Math.round(CW * CS), H = Math.round(CH * CS), SP = 232; const PANEL_TOP = 75; // ── 通用占位(wireframe / skeleton)零件:全部只用灰条 + 色块,不写具体文案 ── const TITLE = '#a8adb5', TEXT = '#d4d7dd', FAINT = '#e3e5ea', LINE = '#eceef1'; // 骨架条:默认圆角 min(h/2, 3) const Skel: React.FC<{ x: number; y: number; w: number; h: number; col: string; r?: number }> = ({ x, y, w, h, col, r }) => (
); // 窗口顶栏:强调色方块 + 字标灰条 + 右侧两枚圆点(各页面通用 chrome) const Topbar: React.FC = () => (
); // 左侧导航:一条高亮项 + 若干灰条 const Sidebar: React.FC = () => (
{Array.from({ length: 8 }, (_, i) => ( ))}
); // 1) 三栏卡片占位(居中标题 + 三张卡:标题条/大字块/文本骨架/按钮块) const BCards: React.FC = () => ( <> {Array.from({ length: 3 }, (_, i) => (
{Array.from({ length: 5 }, (_, k) => ( ))}
))} ); // 2) 仪表盘占位(四枚数值卡 + 折线图占位) const BDash: React.FC = () => ( <> {Array.from({ length: 4 }, (_, i) => (
))}
{Array.from({ length: 5 }, (_, i) => ( ))}
); // 3) 列表 / 表格占位(小统计条 + 多行骨架 + 状态色块) const BTable: React.FC = () => ( <> {Array.from({ length: 4 }, (_, i) => (
))} {Array.from({ length: 7 }, (_, i) => (
{/* 状态色块保留功能色(异常淡红 / 正常淡绿) */}
))} ); // 4) 表单 + 开关列表占位(左侧字段框,右侧头像色块行 + 开关) const BForm: React.FC = () => ( <> {Array.from({ length: 3 }, (_, i) => (
))} {Array.from({ length: 3 }, (_, i) => ( ))} {Array.from({ length: 4 }, (_, i) => (
1 ? 22 : 0), width: 100, height: 22 }}>
{/* 开关保留功能色(开=蓝 / 关=灰) */}
))} ); // 四组:胶囊 + 占位 mockup 横向排队(i 越大越靠左,滑入中央越晚),轨道循环 const GROUPS: { txt: string; Body: React.FC }[] = [ { txt: 'Feature A', Body: BCards }, { txt: 'Feature B', Body: BDash }, { txt: 'Feature C', Body: BTable }, { txt: 'Feature D', Body: BForm }, ]; // 雾块静态参数(位置 / 颜色) const FOGS = [ { left: '68%', top: '8%', rgb: AD_RGB }, { left: '4%', top: '60%', rgb: A_RGB }, { left: '40%', top: '82%', rgb: AL_RGB }, ]; // 轨道三拍:起点 t≈0.20 / 0.483 / 0.688,inOutCubic 缓起→中段冲→缓收; // 第一拍明显更慢且带长尾(到 t≈0.48 才完全收住),后两拍干脆些。 const BEATS = [ { b: 0.200, d: 0.185, tail: 0.28 }, // 第 1 位 → 第 2 位 { b: 0.483, d: 0.150, tail: 0 }, // 第 2 位 → 第 3 位 { b: 0.688, d: 0.150, tail: 0 }, // 第 3 位 → 第 4 位 ]; export const FloatingGlossyLabelPills: React.FC = () => { const t = useT(); // 开场有上一拍的收尾余量:t=0 时轨道偏左 11px,t≈0.19 归位 let trackX = -11 * (1 - seg(t, 0, 0.19, E.outQuart)); for (const B of BEATS) { const p = B.tail ? 0.85 * seg(t, B.b, B.b + B.d, E.inOutCubic) + 0.15 * seg(t, B.b, B.b + B.tail, E.outCubic) : seg(t, B.b, B.b + B.d, E.inOutCubic); trackX += p * SP; } const N = GROUPS.length, RING = N * SP; // 光标:t≈0.717 于右上(x≈403,y≈36)一帧硬现,减速斜滑向左下, // t≈0.90 抵达末位胶囊右端附近(x≈281,y≈56)后几乎静止 const cp = seg(t, 0.717, 0.90, E.outQuart); return (
{/* 漂移雾块 */} {FOGS.map(({ left, top, rgb }, i) => (
))} {GROUPS.map(({ txt, Body }, i) => { // 环形轨道:面板绕 4 位循环,保证任一拍都有左右邻居各露一截在画面边缘 let wx = trackX - i * SP; wx = ((wx % RING) + RING * 1.5) % RING - RING / 2; const d = Math.min(1, Math.abs(wx) / SP); // 0=正居中,1=已到邻位 const close = 1 - d; const sc = lerp(close, 0.62, 1); // 邻位实测缩到 0.62 return (
0.5 ? 2 : 1, }} > {/* 面板:等比缩小 + 顶边随 d 线性下沉(斜率 ≈80px) */}
{/* 胶囊:实测中心 y 从 45(居中)沉到 102(邻位),比面板沉得更多, 离心时贴近面板顶边 —— 单独一条更陡的下沉曲线 */}
{txt}
); })} {/* 黑色描白边光标(结尾划向末位胶囊,macOS 指针样式) */}
); };