DESIGN NOTES
为什么值得收藏
- 根部抽细节奏以根部为锚点画连接曲线(双圆切线贝塞尔),根部半径随拖拽距离从初始值(如 8px)线性抽细,这是手感关键
- 断裂阈值拖拽距离超过阈值(如 80-120px)时丝线断裂,气泡带粒子消散动画消失,未达阈值则 ease-out 回弹归位约 200ms
- 跟手位移气泡 1:1 跟随手指,丝的形态每帧根据距离实时重算
UI 组件
结合原始资料,按需应用到自己的设计中。
实现一个未读标记拖拽粘连组件(原生 HTML/CSS/JS,零依赖,单文件交付):
【效果描述】用户在消息列表项上看到未读红点气泡,手指/鼠标按住并拖出时,气泡与原位置之间拉出一条果冻状粘连丝线:丝线根部锚定在原始位置,越拖越细、气泡端保持圆润,呈现拉丝质感;拖拽距离超过阈值时丝线瞬间断裂,气泡伴随粒子飞散动画消散,未读标记被消除;未达阈值松手则气泡带着丝线回弹归位,仿佛被橡皮筋拉回。整个过程气泡 1:1 跟手,丝线形态每帧实时重算,手感流畅有粘性。
【交互参数】
- 触发:pointerdown 落在红点气泡上(hit area 不小于 44×44px)即开始拖拽,pointermove 更新位置,pointerup/cancel 结算结果;气泡中心与指针 1:1 同步,无延迟无缓动。
- 气泡:半径 10px,红色圆点内含未读数字(可选);粘连丝线用双圆切线贝塞尔绘制——以原锚点小圆与拖拽气泡大圆的外公切线方向为边,四条曲线围成闭合 path。
- 根部半径抽细公式:r = max(8 - distance × 0.08, 1.5),即初始 8px,每拖 1px 减 0.08px,下限 1.5px;distance 为当前指针与锚点的欧氏距离。
- 断裂阈值:distance > 100px 时丝线断裂(可作为可调参数暴露,合理区间 80–120px)。断裂后气泡播放 300ms 消散动画:气泡本身 scale 1→0.3、opacity 1→0,同时从气泡边缘向外飞散 6 个半径 2–3px 的小粒子,粒子初速度方向均匀分布在 360°,位移 30–50px,缓动用 cubic-bezier(0.22, 0.61, 0.36, 1)。
- 回弹:distance ≤ 100px 松手,气泡从当前位置回弹至锚点,时长 200ms,缓动 cubic-bezier(0.25, 0.46, 0.45, 0.94)(ease-out),丝线随气泡位置每帧重算、根部半径同步恢复至 8px。
- 边界情况:拖拽距离为 0 时不绘制丝线只显示气泡;pointercancel(如来电打断)按未达阈值处理执行回弹;锚点元素被滚动或布局变化时实时更新锚点坐标;断裂后气泡从 DOM 移除或置 display:none,且不再响应事件;同一次拖拽中 preventDefault 阻止页面滚动(touch-action: none)。
【使用示例】
- 消息列表未读消除:在每行末尾放置 <span class="uw-sticky-dot" data-unread="3"></span>,初始化 StickyUnread.init(document.querySelector('.chat-list')),拖拽断裂后派发自定义事件 uw:cleared(detail 含被消除元素),业务方监听后调用接口标记已读。可按项目替换:红点颜色、阈值 100px、消散粒子数量。
- 全局通知角标清理:在 App 图标角标上挂载同类实例,把气泡半径调为 8px、阈值调为 80px,断裂动画后同步清空角标数字。
【实现要点】
1. DOM/画布结构:气泡为普通 DOM 元素(便于渲染数字),粘连丝线与粒子动画用一块覆盖视口的 <canvas>(position:fixed, inset:0, pointer-events:none, z-index 置顶)绘制;或退化为单气泡场景用 SVG path,二者选一并说明理由。
2. 初始化:对每个 .uw-sticky-dot 记录其 getBoundingClientRect 中心作为锚点,绑定 pointerdown;监听 scroll/resize 更新锚点。
3. 拖拽循环:pointerdown 后创建 canvas 全屏层并启动 requestAnimationFrame 循环;每帧计算 distance 与单位方向向量,按双圆切线几何计算两侧切点:设锚点圆心 A、半径 rA=8-d×0.08,气泡圆心 B、半径 rB=10,用角度 θ = atan2(B-A) ± acos((rB-rA)/d) 求切点,连成闭合 path(A 侧两点圆弧 + 两条切线 + B 侧两点圆弧)填充红色;同步用 transform: translate 更新气泡 DOM 位置,保证 1:1 跟手。
4. 断裂分支:distance 超阈值后停止画丝线,在 canvas 上生成 6 个粒子(随机角度、随机 30–50px 位移),用 rAF 驱动位移动画 300ms 后销毁 canvas、移除气泡、dispatch uw:cleared。
5. 回弹分支:记录松手位置,rAF 插值 200ms 回锚点,期间丝线照常绘制、根部半径随插值距离恢复,归位后销毁 canvas。
6. 事件清理:每次拖拽结束移除 pointermove/pointerup 监听,canvas 确保被移除,避免内存泄漏。
【质量要求】
- 不污染全局样式:所有样式写入组件自带 <style>,类名与 CSS 变量一律加 uw- 前缀(如 .uw-sticky-dot、.uw-sticky-canvas),不设置任何全局标签样式,z-index 使用局部可控值。
- prefers-reduced-motion 时禁用动画:检测到媒体查询命中时,取消丝线绘制与粒子飞散,拖拽超过阈值直接消除气泡、未超阈值直接瞬移归位,保留功能去掉动效。
- 注释标出可调参数:在 JS 顶部集中定义并以注释说明——断裂阈值 THRESHOLD = 100、初始根部半径 ROOT_RADIUS = 8、抽细系数 0.08、回弹时长 200、消散时长 300、粒子数量 6、气泡半径 10、主题色,均支持通过初始化选项覆盖。
【参考资源】
- 资料详情:https://ui.undoai.cn/components/sticky-unread-drag/
- 效果快照:https://ui.undoai.cn/components/sticky-unread-drag/cover.png
- Demo 源码:https://ui.undoai.cn/components/sticky-unread-drag/demo.html将提示词与你的页面背景、技术栈和目标尺寸一起交给代码助手。实现后对照原图检查布局和状态,再验证键盘、触控和减少动态效果。
展开后加载源代码
查看 Markdown 全文,复制或下载 design.md 后交给开发者使用。
# 未读标记拖拽粘连 — design.md 内容版本:sha256:adffbe4ac763b1a38ddede6bf7a844178580fec3f78d9a992b012a4e54a980e3 本文件由当前元数据、实现摘要和实际文件列表确定性生成。元数据记录是资料声明;未提供的数值不作推断。实现建议须在后续开发中选择和验收。 ## 元数据记录 - 资产:components/sticky-unread-drag;语义类型:interaction。 - 分类:交互模式。 - 标签:粘连拉丝、锚点抽细、阈值断裂、气泡消除。 - 场景:未读消息消除、通知红点拖拽、气泡提示关闭、角标清理。 - 平台:未提供。 - 风格:未提供。 ### 亮点声明 - 根部抽细节奏:以根部为锚点画连接曲线(双圆切线贝塞尔),根部半径随拖拽距离从初始值(如 8px)线性抽细,这是手感关键 - 断裂阈值:拖拽距离超过阈值(如 80-120px)时丝线断裂,气泡带粒子消散动画消失,未达阈值则 ease-out 回弹归位约 200ms - 跟手位移:气泡 1:1 跟随手指,丝的形态每帧根据距离实时重算 ### 实际文件与参考资源 - `cover.png`(sha256:12ff6d51ef4147222c17c3991ec296079e0fd81747b743cc3204217d8e6921d7) - `demo.html`(sha256:10b9899facd1dca32131c325ebb32eedf42425e6c6f7172e30e141b2f113987a) - `meta.yml` - 实现摘要:sha256:10b9899facd1dca32131c325ebb32eedf42425e6c6f7172e30e141b2f113987a。 ## 未提供 - 未结构化记录的精确色值、字号、间距、断点、动效时长与状态转换参数不作推断;亮点中的数值属于元数据声明,demo 的存在与摘要不代表浏览器行为已验收。 ## 实现建议 - 按正常、悬停、聚焦、激活、禁用、加载、成功和错误状态定义适用的状态表。 - 使用语义化元素,验证键盘操作、焦点可见性、触控目标和减少动效偏好。 - 以 demo.html 为实现参考,逐项验证交互、窄屏布局、文本溢出和错误恢复;具体参数由实现与验收确认。
在完整提示词后补充你的要求;生成提示词不会创建新资产。
DESIGN NOTES
GOOD FOR