[{"data":1,"prerenderedAt":128},["ShallowReactive",2],{"works":3,"work-\u002Fanimation\u002Fdither-ripple-avatar":71},[4,22,39,55],{"path":5,"title":6,"short":7,"description":8,"cover":9,"date":10,"source":11,"author":12,"authorShort":13,"origin":14,"stack":15,"tags":17,"type":20,"no":21},"\u002Fui\u002Fpaper-scroll","纸张滚动效果","纸张滚动","文字在纸上流动，纸张的边缘与阴影保持原位。","\u002Fimages\u002Fcovers\u002Fpaper.jpg","2026-10-05","https:\u002F\u002Fseg6.space\u002F","seg6.space",null,"recreation",[16],"css",[18,19],"滚动","纸张","ui","001",{"path":23,"title":24,"short":25,"description":26,"cover":27,"date":28,"source":29,"author":30,"authorShort":13,"origin":14,"stack":31,"tags":33,"type":37,"no":38},"\u002Fanimation\u002Fdither-ripple-avatar","抖动像素波纹头像","像素波纹头像","指针划过时像素被推开再弹回，点击激起向外扩散的波环。每个像素都是一个带弹簧的粒子。","\u002Fimages\u002Fcovers\u002Favatar.jpg","2026-10-08","https:\u002F\u002Fadixcode.com\u002F","adixcode.com",[32],"canvas",[34,35,36],"头像","粒子","指针交互","animation","002",{"path":40,"title":41,"short":42,"description":43,"cover":44,"date":45,"source":46,"author":47,"authorShort":48,"origin":14,"stack":49,"tags":50,"type":37,"no":54},"\u002Fanimation\u002Fclaude-micro-interactions","Claude 风格的文字显现与输入框交互","Claude 风格微交互","逐字模糊消解、输入框的悬浮边框，以及聚焦时的双环反馈。","\u002Fimages\u002Fcovers\u002Fclaude.jpg","2026-10-14","https:\u002F\u002Fclaude-storybook.bystanderss.chatgpt.site\u002F","Claude Design System Storybook","Claude Storybook",[16],[51,52,53],"文字动画","输入框","聚焦状态","003",{"path":56,"title":57,"short":13,"description":58,"cover":59,"date":60,"source":61,"author":62,"authorShort":63,"origin":14,"stack":64,"tags":65,"type":20,"no":70},"\u002Fui\u002Fgrain-gradient-cover","颗粒渐变封面","几团糊开的色块，上面撒一层 1px 的灰色颗粒。拆解 ElevenLabs 博客封面的做法，做成一个可以导出图片的生成器。","\u002Fimages\u002Fcovers\u002Fgrain.jpg","2026-10-24","https:\u002F\u002Fx.com\u002Fianneo_ai\u002Fstatus\u002F2113225499556381172","Ian (@ianneo_ai)","X @ianneo_ai",[32],[66,67,68,69],"渐变","噪点","封面","背景","004",{"id":72,"title":24,"author":30,"authorShort":13,"body":73,"cover":27,"date":28,"description":26,"extension":120,"icon":13,"meta":121,"navigation":122,"origin":14,"path":23,"seo":123,"short":25,"source":29,"stack":124,"stem":125,"tags":126,"__hash__":127},"animation\u002Fanimation\u002Fdither-ripple-avatar.md",{"type":74,"value":75,"toc":116},"minimark",[76,80,83,92,95,98,102,105],[77,78,79],"p",{},"把指针移过头像，像素会被推开，移走后再弹回原位。点击，或用手指轻触，会激起一圈向外扩散的波纹。头像停在视口里时，每秒还会自己泛起一圈。",[81,82],"dither-ripple-avatar",{},[77,84,85,86,91],{},"灵感来自 ",[87,88,30],"a",{"href":29,"rel":89},[90],"nofollow"," 的头像卡片，但实现是重新写的。头像被缩成约 100 列，每个不透明像素变成一个粒子，保留原色。每个粒子有基准位置和位移，位移每帧向目标值靠近 12%，所以推开和回弹都带惯性。",[77,93,94],{},"指针是一个半径 100px 的排斥场，推力按三次方衰减。波纹是一个以 225px\u002Fs 扩散的环，带宽 ±37px，675ms 内线性消失；同时存在多个波纹时推力会叠加。动画只在有东西在动时才跑，全部静止后自动停止。",[77,96,97],{},"系统开启「减少动态效果」时，推力降到四分之一，并关闭自动波纹。",[99,100,101],"h2",{"id":101},"提示词",[77,103,104],{},"复制给 Claude、ChatGPT 或编码 agent，可以复现本页的头像。需要准备一张透明背景的头像 PNG。",[106,107,113],"pre",{"className":108,"code":110,"language":111,"meta":112},[109],"language-text","用 Canvas 2D 把一张透明背景的头像做成可交互的像素粒子：指针划过时像素被推开再弹回，点击激起向外扩散的波环。不依赖外部库。\n\n1. 采样：把图片中间最大的正方形画到一个 N×N 的离屏 canvas 上（N = 容器边长 \u002F 4.5，限制在 56–128 之间，imageSmoothingQuality 设为 \"high\"），用 getImageData 读回。透明度低于 128 的像素丢掉，其余每个像素变成一个粒子，保留原色。粒子的基准位置取像素中心，按「容器边长 \u002F N」放大，整体在容器里居中。\n2. 数据：粒子有上万个，用 Float32Array 分别存基准 x、y 和位移 dx、dy，颜色打包成一个 Uint32（小端序写成 A\u003C\u003C24 | B\u003C\u003C16 | G\u003C\u003C8 | R）。不要用对象数组。\n3. 受力：每帧给每个粒子算一个目标位移，指针和所有波纹的力相加。\n   - 指针排斥：半径 100px。t = 1 − 距离 \u002F 100，推力 = t³ × 40px，方向从指针指向粒子的当前位置（基准 + 位移）。先比较距离的平方，在范围内才开方。\n   - 波纹：点击或触摸抬起时在该点生成。环的半径 = 225px\u002Fs × 经过时间；离环中心线 37px 以内的粒子被向外推，推力 = (1 − 离环距离 \u002F 37) × (1 − 经过时间 \u002F 675ms) × 20px。675ms 后删除。最多同时 12 个；有 n 个波纹时，波纹推力整体乘 1 + 0.5 × (n − 1)。\n4. 弹簧：位移每帧向目标位移靠近 12%（按 60fps 定义）。换算成与帧率无关：ease = 1 − 0.88^(dt × 60)，dt 最多按 0.05 秒算。位移小于 0.01px 时直接归零。\n5. 绘制：复用一个 ImageData，每帧清零后把每个粒子画成边长等于放大倍数的实心方块（乘 devicePixelRatio，四舍五入对齐，相邻方块不留缝），最后 putImageData 一次。不要对每个粒子调用 fillRect。\n6. 循环按需运行：有粒子还在动、有波纹、或指针在上面时才请求下一帧，全部静止就停止。容器在视口内时，每秒在随机位置自动激起一个波纹；滚出视口就停止。\n7. 触屏：canvas 设 touch-action: none。pointerup 时激起波纹；非鼠标指针抬起后取消排斥；pointercancel 也取消排斥。容器尺寸变化后防抖 150ms 再重新采样。\n8. prefers-reduced-motion：所有力乘 0.25，关闭自动波纹。\n","text","",[114,115,110],"code",{"__ignoreMap":112},{"title":112,"searchDepth":117,"depth":117,"links":118},2,[119],{"id":101,"depth":117,"text":101},"md",{},true,{"title":24,"description":26},[32],"animation\u002Fdither-ripple-avatar",[34,35,36],"_klJgHLz49L05pWD9c3MLPQb7yUCt0KZBDs3vsV2Fx4",1793078289885]