[{"data":1,"prerenderedAt":365},["ShallowReactive",2],{"navigation_docs":3,"-examples-timeline-storyboard":137,"-examples-timeline-storyboard-surround":335,"preview-examples\u002Fshowcase\u002Ftimeline-storyboard\u002FTimelineStoryboardDemo.vue-false":340,"mdc--3dzbel-key":341},[4,30,74,98,127],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",{"title":26,"path":27,"stem":28,"icon":29},"Performance","\u002Fgetting-started\u002Fperformance","1.getting-started\u002F4.performance","i-lucide-gauge",{"title":31,"icon":6,"path":32,"stem":33,"children":34,"page":6},"Composables","\u002Fcomposables","2.composables",[35,39,44,49,54,59,64,69],{"title":11,"path":36,"stem":37,"icon":38},"\u002Fcomposables\u002Fintroduction","2.composables\u002F0.introduction","i-lucide-box",{"title":40,"path":41,"stem":42,"icon":43},"useAnimate","\u002Fcomposables\u002Fuse-animate","2.composables\u002F1.use-animate","i-ph-play-circle",{"title":45,"path":46,"stem":47,"icon":48},"useWaapiAnimate","\u002Fcomposables\u002Fuse-waapi-animate","2.composables\u002F2.use-waapi-animate","i-ph-lightning",{"title":50,"path":51,"stem":52,"icon":53},"useAnimatable","\u002Fcomposables\u002Fuse-animatable","2.composables\u002F3.use-animatable","i-ph-cube",{"title":55,"path":56,"stem":57,"icon":58},"useSplitText","\u002Fcomposables\u002Fuse-split-text","2.composables\u002F4.use-split-text","i-ph-text-t",{"title":60,"path":61,"stem":62,"icon":63},"useScrambleText","\u002Fcomposables\u002Fuse-scramble-text","2.composables\u002F5.use-scramble-text","i-ph-shuffle",{"title":65,"path":66,"stem":67,"icon":68},"useDraggable","\u002Fcomposables\u002Fuse-draggable","2.composables\u002F6.use-draggable","i-ph-hand-grabbing",{"title":70,"path":71,"stem":72,"icon":73},"useAnimeTimeline","\u002Fcomposables\u002Fuse-anime-timeline","2.composables\u002F7.use-anime-timeline","i-ph-list-numbers",{"title":75,"path":76,"stem":77,"children":78,"page":6},"Misc","\u002Fmisc","4.misc",[79,83,88,93],{"title":11,"path":80,"stem":81,"icon":82},"\u002Fmisc\u002Fintroduction","4.misc\u002F0.introduction","i-ph-puzzle-piece",{"title":84,"path":85,"stem":86,"icon":87},"Easings","\u002Fmisc\u002Feasings","4.misc\u002F1.easings","i-ph-chart-line",{"title":89,"path":90,"stem":91,"icon":92},"Utils","\u002Fmisc\u002Futils","4.misc\u002F2.utils","i-ph-wrench",{"title":94,"path":95,"stem":96,"icon":97},"Proxies","\u002Fmisc\u002Fproxies","4.misc\u002F3.proxies","i-ph-plugs-connected",{"title":99,"icon":6,"path":100,"stem":101,"children":102,"page":6},"Examples","\u002Fexamples","5.examples",[103,107,112,117,122],{"title":11,"path":104,"stem":105,"icon":106},"\u002Fexamples\u002Fintroduction","5.examples\u002F0.introduction","i-ph-shapes",{"title":108,"path":109,"stem":110,"icon":111},"Timeline storyboard","\u002Fexamples\u002Ftimeline-storyboard","5.examples\u002F1.timeline-storyboard","i-ph-film-strip",{"title":113,"path":114,"stem":115,"icon":116},"Drag to bin","\u002Fexamples\u002Fdrag-to-bin","5.examples\u002F2.drag-to-bin","i-ph-trash",{"title":118,"path":119,"stem":120,"icon":121},"Loading sequence","\u002Fexamples\u002Floading-sequence","5.examples\u002F3.loading-sequence","i-ph-spinner-gap",{"title":123,"path":124,"stem":125,"icon":126},"Text magnet","\u002Fexamples\u002Ftext-scatter","5.examples\u002F4.text-scatter","i-ph-magnet",{"title":128,"icon":6,"path":129,"stem":130,"children":131,"page":6},"Updates","\u002Fchanges","6.changes",[132],{"title":133,"path":134,"stem":135,"icon":136},"Changelog","\u002Fchanges\u002Fchangelog","6.changes\u002F1.changelog","i-ph-clock-counter-clockwise",{"id":138,"title":108,"body":139,"description":328,"extension":329,"links":330,"meta":331,"navigation":332,"path":109,"seo":333,"stem":110,"__hash__":334},"docs\u002F5.examples\u002F1.timeline-storyboard.md",{"type":140,"value":141,"toc":322},"minimark",[142,146,151,156,159,163,177,188,195,199,308],[143,144,145],"p",{},"Four cards each perform their own signature move, then join for a closing\nwave. The whole thing plays, pauses, restarts and scrubs from a single\ncontrol, the way an editor cuts separately-shot clips onto one timeline.",[147,148],"render-code-block-preview",{":code":149,"src":150},"false","examples\u002Fshowcase\u002Ftimeline-storyboard\u002FTimelineStoryboardDemo.vue",[152,153,155],"h2",{"id":154},"whats-happening","What's happening",[143,157,158],{},"Each card plays its own short move, like four dancers who each learned a\nseparate routine. Those routines are lined up on one shared timeline, the\nway a video editor lines up clips on one track, and the four finish together\nwith a rippling bow. Drag the scrub bar and you move through all of it at\nonce, so halfway through you might catch Card 02 mid-flip while Card 03\nhasn't started yet.",[152,160,162],{"id":161},"how-its-built","How it's built",[143,164,165,166,172,173,176],{},"The goal was to write and tune each card's routine without worrying about\nthe other three, so each one gets its own\n",[167,168,169],"a",{"href":71},[170,171,70],"code",{},", built with\n",[170,174,175],{},"autoplay: false"," so it sits ready but doesn't play on its own. The closing\nwave is a fifth timeline of the same kind, staggered across all four boxes\nat once.",[143,178,179,180,183,184,187],{},"Those five get dropped onto a sixth, master timeline with\n",[170,181,182],{},".sync(childTimeline, offsetMs)",", where ",[170,185,186],{},"offsetMs"," is how far into the\nmaster that routine starts. The offsets climb (0ms, 350ms, 850ms, 1450ms),\nso each card starts a beat after the last one, and the wave lands at 2300ms\nonce the solos are done.",[143,189,190,191,194],{},"From there, the play, pause, and scrub controls only ever talk to that one\nmaster timeline. Calling ",[170,192,193],{},".seek(progress * duration)"," on it is enough to\nscrub every card at once, because they're all riding the same clock.",[152,196,198],{"id":197},"building-it-yourself","Building it yourself",[200,201,202,214,249,259,283,289],"ol",{},[203,204,205,206,210,211,213],"li",{},"Give each card its own ",[167,207,208],{"href":71},[170,209,70],{}," instance, created with ",[170,212,175],{},", and author its keyframes independently of the others.",[203,215,216,217,220,221,224,225,220,227,230,231,234,235,238,239,242,243,245,246,248],{},"Optionally split each card into two nested elements: an outer \"mover\" ",[170,218,219],{},"div"," for ",[170,222,223],{},"y"," (position), and an inner \"rotator\" ",[170,226,219],{},[170,228,229],{},"scale"," and ",[170,232,233],{},"rotate",". This isn't required. Anime.js keeps one shared transform cache per element, so two separate ",[170,236,237],{},".add()"," calls for position and rotation would still merge cleanly into one ",[170,240,241],{},"transform"," even on a single ",[170,244,219],{},". The split is there for organization: position steps and rotation steps rarely share the same step count or duration, so giving each its own element keeps the two ",[170,247,237],{}," calls independent and easy to read, instead of forcing one keyframe schedule to fit both.",[203,250,251,252,254,255,258],{},"Add one more ",[170,253,175],{}," timeline for a closing move that covers every card at once, using ",[170,256,257],{},"stagger()"," on the shared selector rather than per-card offsets.",[203,260,261,262,264,265,267,268,271,272,275,276,275,279,282],{},"Create a final ",[170,263,70],{},", also ",[170,266,175],{},", to act as the master. Give it ",[170,269,270],{},"onUpdate"," for progress reporting and ",[170,273,274],{},"onBegin"," \u002F ",[170,277,278],{},"onPause",[170,280,281],{},"onComplete"," for play state.",[203,284,285,286,288],{},"Call ",[170,287,182],{}," on the master for each card and for the closing move, staggering the offsets so the routines play in sequence and the closing move lands after the solos.",[203,290,291,292,295,296,299,300,303,304,307],{},"Wire Play, Pause, and Restart buttons to the master's ",[170,293,294],{},".play()",", ",[170,297,298],{},".pause()",", and ",[170,301,302],{},".restart()",", and a range slider to ",[170,305,306],{},".seek(value * master.duration)",".",[309,310,312],"collapsible",{"name":311},"AI build prompt",[313,314,320],"pre",{"className":315,"code":317,"language":318,"meta":319},[316],"language-text","Using the nanime Nuxt module, build a Vue 3 component with 4 card elements.\nGive each card its own useAnimeTimeline instance (autoplay: false) with a\ndistinct multi-step animation (position, rotation, scale) using arrays of\nkeyframes with an individual duration and ease per step. Use Anime.js's own\neasing names, like 'outQuad', 'outBounce', 'outElastic', 'inOutSine', and\n'linear'. Skip the 'easeOutQuad' or 'easeInOutSine' naming convention some\nother animation libraries use. An unrecognized ease string fails silently\nand falls back to linear, so get this from the module's actual easing list\nrather than guessing. Optionally split each card into a \"mover\" element for\nposition and a \"rotator\" element for scale and rotation, purely to keep\neach `.add()` call's keyframe schedule independent since they rarely share\nthe same step count or duration.\n\nAdd one more autoplay: false timeline for a closing wave that animates every\ncard at once, using stagger() on the shared box selector so the boxes ripple\nrather than moving together.\n\nCreate a master useAnimeTimeline (autoplay: false) with onUpdate reporting\nprogress from 0 to 1, and onBegin \u002F onPause \u002F onComplete toggling an\nisPlaying flag. Sync each card's timeline into the master with\n.sync(childTimeline, offsetMs), staggering the offsets so the cards animate\none after another instead of all at once, and sync the closing wave last so\nit plays after the solos finish.\n\nAdd Play, Pause, and Restart buttons calling the master's .play(),\n.pause(), and .restart(), and a range slider that calls\n.seek(value * master.duration) to scrub through the whole composition.\n","text","",[170,321,317],{"__ignoreMap":319},{"title":319,"searchDepth":323,"depth":323,"links":324},2,[325,326,327],{"id":154,"depth":323,"text":155},{"id":161,"depth":323,"text":162},{"id":197,"depth":323,"text":198},"Independent timelines synced into one composition.","md",null,{},{"icon":111},{"title":108,"description":328},"oCZKnAWx8hJAUt-OdaCaXbbIkEUQzV_qugl6QAawuVg",[336,338],{"title":11,"path":104,"stem":105,"description":337,"icon":106,"children":-1},"Full compositions built with the module.",{"title":113,"path":114,"stem":115,"description":339,"icon":116,"children":-1},"Dragging, hit testing, and a list that closes its own gap.","\n::timeline-storyboard-demo\n::\n\n\n::u-button\n---\nto: https:\u002F\u002Fgithub.com\u002Fastraldev\u002Fnanime\u002Fblob\u002Fmain\u002Fdocs\u002Fapp\u002Fcomponents\u002Fcontent\u002Fexamples\u002Fshowcase\u002Ftimeline-storyboard\u002FTimelineStoryboardDemo.vue\ntarget: _blank\nvariant: link\ncolor: neutral\nicon: i-simple-icons-github\nclass: mt-2.5 pl-0.5\n---\nView on GitHub\n::\n",{"data":342,"body":343},{},{"type":344,"children":345},"root",[346,351],{"type":347,"tag":348,"props":349,"children":350},"element","timeline-storyboard-demo",{},[],{"type":347,"tag":352,"props":353,"children":362},"u-button",{"className":354,"color":357,"icon":358,"target":359,"to":360,"variant":361},[355,356],"mt-2.5","pl-0.5","neutral","i-simple-icons-github","_blank","https:\u002F\u002Fgithub.com\u002Fastraldev\u002Fnanime\u002Fblob\u002Fmain\u002Fdocs\u002Fapp\u002Fcomponents\u002Fcontent\u002Fexamples\u002Fshowcase\u002Ftimeline-storyboard\u002FTimelineStoryboardDemo.vue","link",[363],{"type":318,"value":364},"View on GitHub",1788821081495]