[{"data":1,"prerenderedAt":525},["ShallowReactive",2],{"\u002F2026\u002Fanimejs-experience":3,"surround-\u002F2026\u002Fanimejs-experience":514},{"id":4,"title":5,"body":6,"categories":488,"date":492,"description":493,"draft":494,"extension":495,"image":496,"meta":497,"navigation":499,"path":500,"permalink":501,"published":501,"readingTime":502,"recommend":507,"references":501,"seo":508,"sitemap":509,"stem":510,"tags":511,"type":512,"updated":492,"__hash__":513},"content\u002Fposts\u002F2026\u002Fanimejs-experience.md","anime.js 使用体验：为什么我又开始认真看前端动画库",{"type":7,"value":8,"toc":473},"minimark",[9,18,25,33,43,50,55,60,66,69,79,85,89,141,146,152,163,168,171,177,180,184,190,207,214,217,220,228,232,245,248,268,274,278,284,287,319,325,329,332,335,346,349,366,372,379,383,406,412,426,429,432,435,441,447,453,470],[10,11,14],"alert",{"title":12,"type":13},"写在前面","info",[15,16,17],"p",{},"这篇文章基于 anime.js 官方文档与我当前在这个博客里的实际接入体验来写，主要关注的是 v4 这一代 API 的设计和使用感受，而不是和所有动画库做一轮全面横评。",[15,19,20,21,24],{},"前端动画这件事，我以前一直是又喜欢、又有点克制。",[22,23],"br",{},"\n喜欢是因为它确实能让页面更有生命力，克制是因为大多数时候，动画一旦写得太重，就很容易从“增强体验”变成“抢走注意力”。",[15,26,27,28,32],{},"所以这次重新看 ",[29,30,31],"code",{"code":31},"anime.js","，我最关心的并不是“它能不能做出很炫的效果”，而是两件更实际的事：",[34,35,36,40],"ul",{},[37,38,39],"li",{},"它现在的 API 还顺不顺手",[37,41,42],{},"它适不适合放进一个真实在维护的 Nuxt 博客里",[44,45],"link-card",{"description":46,"icon":47,"link":48,"title":49},"官方站点与演示入口，包含主页、文档、easings 编辑器与学习资源。","https:\u002F\u002Fanimejs.com\u002Ffavicon.ico","https:\u002F\u002Fanimejs.com\u002F","anime.js 官网",[44,51],{"description":52,"icon":47,"link":53,"title":54},"v4 官方文档，重点包括安装、模块导入、Scope、WAAPI、Layout、Text、SVG 和实用工具。","https:\u002F\u002Fanimejs.com\u002Fdocumentation\u002F","anime.js Documentation",[56,57,59],"h2",{"id":58},"我为什么会重新注意到-animejs","我为什么会重新注意到 anime.js",[15,61,62,63,65],{},"这次并不是因为我要专门做一个动画项目，而是因为我想给博客右侧的信息卡片加一点更自然的动态反馈。",[22,64],{},"\n如果只是简单地补几个 CSS transition，很多时候只能做到“有变化”，但做不到“有节奏”。而一旦想把多个元素串起来，像延迟、交错、回弹、批量控制这些需求就会马上出现。",[15,67,68],{},"我在当前项目里最先落地的是这一句：",[70,71,77],"pre",{"className":72,"code":74,"language":75,"meta":76},[73],"language-ts","import { animate, stagger } from 'animejs'\n","ts","",[29,78,74],{"__ignoreMap":76},[15,80,81,82,84],{},"它被我放在了访客信息卡片里，用来控制地图、节点和连线出现时的时序。",[22,83],{},"\n从这个切入点往下走，我才开始真正把 v4 的文档重新看了一遍。",[56,86,88],{"id":87},"animejs-现在最吸引我的几个点","anime.js 现在最吸引我的几个点",[90,91,92],"card-list",{},[34,93,94,100,110,117],{},[37,95,96,99],{},[29,97,98],{"code":98},"v4"," 的模块化导入明显更顺手了，主模块和子路径都能直接用。",[37,101,102,105,106,109],{},[29,103,104],{"code":104},"Scope"," 这套设计很适合组件化项目，尤其适合 ",[29,107,108],{"code":108},"Vue \u002F React \u002F Nuxt"," 这种场景。",[37,111,112,113,116],{},"它没有把 ",[29,114,115],{"code":115},"WAAPI"," 当成对立面，而是反过来帮你把原生动画 API 用得更舒服。",[37,118,119,120,123,124,127,128,127,131,127,134,127,137,140],{},"除了最常见的 ",[29,121,122],{"code":122},"animate()","，它还有 ",[29,125,126],{"code":126},"timeline","、",[29,129,130],{"code":130},"utils",[29,132,133],{"code":133},"svg",[29,135,136],{"code":136},"text",[29,138,139],{"code":139},"layout"," 这些更完整的能力。",[142,143,145],"h3",{"id":144},"_1-模块优先这件事真的很对胃口","1. 模块优先这件事，真的很对胃口",[15,147,148,149,151],{},"我现在更喜欢的库，基本都有一个共同点：",[22,150],{},"\n不是把所有东西揉成一个巨大的默认导出，而是把功能拆得足够清楚，按需拿来用。",[15,153,154,155,158,159,162],{},"anime.js v4 这一点做得很明确。官方文档里直接把它描述成 ",[29,156,157],{"code":157},"modules-first API","，而且强调了 ",[29,160,161],{"code":161},"tree shaking"," 支持。你既可以这样导入：",[70,164,166],{"className":165,"code":74,"language":75,"meta":76},[73],[29,167,74],{"__ignoreMap":76},[15,169,170],{},"也可以按子路径拆开：",[70,172,175],{"className":173,"code":174,"language":75,"meta":76},[73],"import { animate } from 'animejs\u002Fanimation'\nimport { stagger } from 'animejs\u002Futils'\n",[29,176,174],{"__ignoreMap":76},[15,178,179],{},"这类设计的好处不是“语法更酷”，而是它让动画库更像一个可以组合的工具箱，而不是一个必须整体接受的黑盒。",[56,181,183],{"id":182},"_2-scope-让我觉得它更像现代前端项目里的工具","2. Scope 让我觉得它更像现代前端项目里的工具",[15,185,186,187,189],{},"如果只是做一个孤立的 demo，很多动画库都很好用。",[22,188],{},"\n但一旦回到真实项目，问题马上会变成：",[34,191,192,195,198,204],{},[37,193,194],{},"组件卸载以后怎么清理",[37,196,197],{},"响应式布局变化以后怎么重建",[37,199,200,203],{},[29,201,202],{"code":202},"prefers-reduced-motion"," 怎么处理",[37,205,206],{},"不同 root 下的元素怎么隔离",[15,208,209,210,213],{},"anime.js v4 的 ",[29,211,212],{"code":212},"createScope()"," 就是在处理这一层问题。官方文档里对 Scope 的描述很直白：它可以响应 media query、使用自定义 root、共享默认参数，还能成批回收实例。",[15,215,216],{},"这让我觉得它不只是一个“补间动画函数”，而是一套有工程意识的动画组织方式。",[15,218,219],{},"如果你本来就在做组件化项目，这种感觉会很明显：",[34,221,222,225],{},[37,223,224],{},"动画不再只是“某个元素动一下”",[37,226,227],{},"而是“这个组件的动画生命周期怎么和组件本身绑在一起”",[56,229,231],{"id":230},"_3-它对-waapi-的态度很成熟","3. 它对 WAAPI 的态度很成熟",[15,233,234,235,237,238,240,241,244],{},"我挺喜欢 anime.js 官方在 ",[29,236,115],{"code":115}," 这块的方向。",[22,239],{},"\n它不是说“别用原生 Web Animations API，来用我的”，而是直接提供了 ",[29,242,243],{"code":243},"waapi.animate()"," 这套增强层。",[15,246,247],{},"官方文档里提到，它在 WAAPI 之上补了很多使用层面的体验改进，比如：",[34,249,250,253,256,259,262,265],{},[37,251,252],{},"更合理的默认值",[37,254,255],{},"多目标动画",[37,257,258],{},"默认单位",[37,260,261],{},"函数式值",[37,263,264],{},"单独 transform 属性",[37,266,267],{},"spring 和自定义 easing",[15,269,270,271,273],{},"对我来说，这种思路比单纯造一套完全平行的新轮子更有说服力。",[22,272],{},"\n因为浏览器原生能力迟早会越来越强，而一个成熟的动画库，真正重要的是它怎么把这些能力组织得更顺手。",[56,275,277],{"id":276},"_4-它不像只会做元素飞来飞去","4. 它不像只会做“元素飞来飞去”",[15,279,280,281,283],{},"我重新看文档时还有个明显感受：",[22,282],{},"\nanime.js 现在已经不是我早几年印象里那个“写几个 translate \u002F opacity 很方便”的库了。",[15,285,286],{},"它现在的能力面明显更宽，官方文档里能直接看到这些分区：",[34,288,289,293,297,301,305,310,314],{},[37,290,291],{},[29,292,126],{"code":126},[37,294,295],{},[29,296,130],{"code":130},[37,298,299],{},[29,300,133],{"code":133},[37,302,303],{},[29,304,136],{"code":136},[37,306,307],{},[29,308,309],{"code":309},"waapi",[37,311,312],{},[29,313,139],{"code":139},[37,315,316],{},[29,317,318],{"code":318},"scope",[15,320,321,322,324],{},"这意味着它已经不只是拿来做局部点缀。",[22,323],{},"\n如果你愿意，它其实可以参与页面进入、批量排序、文字拆分、滚动驱动、布局切换这些更完整的交互层。",[56,326,328],{"id":327},"在这个博客里我现在是怎么开始用它的","在这个博客里，我现在是怎么开始用它的",[15,330,331],{},"我没有一上来就拿它重做全站动画，而是只放在一个足够局部、又能看出节奏感的地方：右侧访客信息卡片。",[15,333,334],{},"当前这部分主要用了：",[34,336,337,341],{},[37,338,339],{},[29,340,122],{"code":122},[37,342,343],{},[29,344,345],{"code":345},"stagger()",[15,347,348],{},"做的事情也比较克制：",[34,350,351,354,357,360,363],{},[37,352,353],{},"地图淡入",[37,355,356],{},"地区高亮",[37,358,359],{},"弧线路径出现",[37,361,362],{},"粒子沿路径移动",[37,364,365],{},"统计信息分批出现",[15,367,368,369,371],{},"我喜欢这种起步方式。",[22,370],{},"\n因为它不会让整个站一下子“动画味”太重，但足够让我判断一件事：这套库在真实项目里是不是顺手。",[15,373,374,375],{},"到目前为止，我的答案是：",[376,377,378],"strong",{},"顺手，而且继续往下加也有空间。",[56,380,382],{"id":381},"我觉得-animejs-适合什么场景","我觉得 anime.js 适合什么场景",[90,384,385],{},[34,386,387,390,397,403],{},[37,388,389],{},"你已经有一个组件化项目，想补自然一点的交互动效。",[37,391,392,393,396],{},"你需要 ",[29,394,395],{"code":395},"timeline \u002F stagger \u002F utility"," 这类比 CSS 更强一点的组织能力。",[37,398,399,400,402],{},"你不想完全绕开原生能力，希望 ",[29,401,115],{"code":115}," 也能一起用起来。",[37,404,405],{},"你想做的是“有节奏的体验增强”，而不是满屏飞来飞去的视觉噪音。",[15,407,408,409,411],{},"如果你只是做一两个简单 hover，CSS 当然还是最轻的方案。",[22,410],{},"\n但如果你开始需要：",[34,413,414,417,420,423],{},[37,415,416],{},"多元素联动",[37,418,419],{},"批量交错",[37,421,422],{},"可回收的组件动画",[37,424,425],{},"与滚动、布局、文字拆分结合",[15,427,428],{},"那 anime.js 就会很快显出价值。",[56,430,431],{"id":431},"我目前的判断",[15,433,434],{},"如果只用一句话总结我这次的感受，我会这么说：",[436,437,438],"blockquote",{},[15,439,440],{},"anime.js 现在最可贵的地方，不是它“还能做动画”，而是它已经越来越像一套适合现代前端项目的动画工具系统。",[15,442,443,444,446],{},"它保留了早年那个上手快、写起来顺的优点，但 v4 又明显往工程化、多模块和组件环境靠了一步。",[22,445],{},"\n这一步对我来说，比单纯多出几个炫技效果更重要。",[15,448,449,450,452],{},"至少在这个博客里，我已经愿意继续把它用下去了。",[22,451],{},"\n下一步如果我继续往下做，大概率会去试：",[34,454,455,460,464,467],{},[37,456,457],{},[29,458,459],{"code":459},"createTimeline()",[37,461,462],{},[29,463,212],{"code":212},[37,465,466],{},"更自然的页面进入动画",[37,468,469],{},"更轻一点的滚动触发效果",[15,471,472],{},"如果后面真的把它用深了，我还会再写第二篇，聊聊 anime.js 在真实 Nuxt 页面里的取舍，而不是只停留在“它看起来很强”这一步。",{"title":76,"searchDepth":474,"depth":474,"links":475},4,[476,478,482,483,484,485,486,487],{"id":58,"depth":477,"text":59},2,{"id":87,"depth":477,"text":88,"children":479},[480],{"id":144,"depth":481,"text":145},3,{"id":182,"depth":477,"text":183},{"id":230,"depth":477,"text":231},{"id":276,"depth":477,"text":277},{"id":327,"depth":477,"text":328},{"id":381,"depth":477,"text":382},{"id":431,"depth":477,"text":431},[489,490,491],"开发","前端","动效","2026-03-24 20:30:00","记录我在这个博客里上手 anime.js v4 的第一轮体验，从模块化导入、Scope、WAAPI 增强到实际适合的使用场景，看看这套动画库现在为什么依然值得写。",false,"md","https:\u002F\u002Fimages.opxqo.com\u002Fblog\u002Fa7eff176-a7b2-4137-83f8-1b7919329d45.png",{"slots":498},{},true,"\u002F2026\u002Fanimejs-experience",null,{"text":503,"minutes":504,"time":505,"words":506},"10 min read",9.195,551700,1839,1,{"title":5,"description":493},{"loc":500},"posts\u002F2026\u002Fanimejs-experience",[],"tech","dv62Ie-mfx-s6hriiFVrh_1ZHUUPwKpnlbPIqeYF-mY",[515,520],{"title":516,"path":517,"stem":518,"date":519,"type":512,"children":-1},"QClaw 使用体验：把微信变成远程工作的入口，好不好用？","\u002F2026\u002Fqclaw-experience","posts\u002F2026\u002Fqclaw-experience","2026-03-23 22:40:00",{"title":521,"path":522,"stem":523,"date":524,"type":512,"children":-1},"Hermes 日志 001：把开发节奏真正跑起来","\u002F2026\u002Fhermes-log-001","posts\u002F2026\u002Fhermes-log-001","2026-04-13 11:35:00",1776089807508]