[{"data":1,"prerenderedAt":359},["ShallowReactive",2],{"navigation_docs":3,"-examples-drag-to-bin":137,"-examples-drag-to-bin-surround":329,"preview-examples\u002Fshowcase\u002Fdrag-to-bin\u002FDragToBinDemo.vue-false":334,"mdc-4t3t6d-key":335},[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":113,"body":139,"description":322,"extension":323,"links":324,"meta":325,"navigation":326,"path":114,"seo":327,"stem":115,"__hash__":328},"docs\u002F5.examples\u002F2.drag-to-bin.md",{"type":140,"value":141,"toc":316},"minimark",[142,146,151,156,159,163,180,196,199,202,212,223,235,239,302],[143,144,145],"p",{},"Drag a card over the bin and it settles into place, or pull it back out and\nit springs back to its original size. Let go while it's over the bin and the\ncard fades out, its slot in the list collapses, and everything below slides\nup to close the gap.",[147,148],"render-code-block-preview",{":code":149,"src":150},"false","examples\u002Fshowcase\u002Fdrag-to-bin\u002FDragToBinDemo.vue",[152,153,155],"h2",{"id":154},"whats-happening","What's happening",[143,157,158],{},"Drag a card toward the bin and it shrinks and slides as it gets close, like\nit's being pulled in. Drop it inside and it fades out, and the\nrest of the list closes up the space it left. Pull it back out before letting go, and\nit snaps back to its normal size, like nothing happened.",[152,160,162],{"id":161},"how-its-built","How it's built",[143,164,165,171,172,175,176,179],{},[166,167,168],"a",{"href":66},[169,170,65],"code",{}," moves the card, and it also\nhandles the return trip. ",[169,173,174],{},"snap: [0]"," and\n",[169,177,178],{},"releaseEase: spring({ bounce: 0.2, duration: 500 })"," mean a card released\noutside the bin springs back to its origin on its own, with no release\nhandler involved.",[143,181,182,183,187,188,191,192,195],{},"The shrink toward the bin runs off\n",[166,184,185],{"href":51},[169,186,50],{},". Crossing into the bin is\ntreated as a state rather than a gradient: ",[169,189,190],{},"onUpdate"," tests the handle's\ncentre against the bin's box and reports a boolean, and the animatable eases\na single ",[169,193,194],{},"0 → 1"," value from it over 350ms. The card's width, height and\noffset are all interpolated from that value in a computed style, so the\n\"inside the bin\" look is one animation rather than three.",[143,197,198],{},"Everything else is CSS. The bin's highlight is a class toggled from the same\nboolean, the binned card fades on an opacity transition, and the slot it\noccupied collapses through a height and margin transition on the ghost\nelement. The rest of the list is not animated at all: it moves because the\ncollapsing ghost is in normal document flow, so the browser reflows what\nsits below it.",[143,200,201],{},"Nothing is positioned by hand. Each card sits inside a ghost element that\nholds its place in the flow, and the card itself is absolutely positioned\nwithin that ghost, so dragging never disturbs the layout around it.",[143,203,204,205,207,208,211],{},"The card is also split in two. A fixed-size handle is what ",[169,206,65],{},"\nmoves, and the visible card inside it is what changes shape. That keeps the\ndrag target's own box constant, which matters because AnimeJS watches the\ndraggable element with a ",[169,209,210],{},"ResizeObserver"," and schedules a refresh whenever\nits size changes.",[143,213,214,215,218,219,222],{},"On release the only work is bookkeeping. If the card was over the bin,\n",[169,216,217],{},"draggable.stop()"," halts it and the parent marks the item binned. Restoring\nan item resets the blend value and calls ",[169,220,221],{},"draggable.reset()"," to put the\nhandle back at its origin.",[224,225,226,227,230,231,234],"note",{},"Geometry is measured once in ",[169,228,229],{},"onGrab"," rather than on every frame. Nothing in\nthe list moves until the card is released, so a per-frame\n",[169,232,233],{},"getBoundingClientRect()"," would buy nothing and cost a layout on every tick.",[152,236,238],{"id":237},"building-it-yourself","Building it yourself",[240,241,242,246,252,265,271,279,289,292],"ol",{},[243,244,245],"li",{},"Wrap each item in a ghost element that stays in normal document flow. This is what preserves list position and lets the list reflow when a card is removed.",[243,247,248,249,251],{},"Inside the ghost, split the card into a fixed-size handle and a visible card absolutely positioned within it. ",[169,250,65],{}," moves only the handle.",[243,253,254,255,258,259,261,262,264],{},"Call ",[169,256,257],{},"useDraggable(handle, { onGrab, onUpdate, onRelease })",". In ",[169,260,229],{},", measure the ghost's rest rect and the bin's rect once with ",[169,263,233],{},", and precompute the size delta between them.",[243,266,267,268,270],{},"In ",[169,269,190],{},", test whether the handle's centre point falls inside the bin's rect, and report that boolean only when it changes.",[243,272,273,274,278],{},"Drive a ",[166,275,276],{"href":51},[169,277,50],{}," value from that boolean, from 0 to 1, and interpolate the card's width, height, and offset from it in a computed style.",[243,280,281,282,284,285,288],{},"Give the draggable ",[169,283,174],{}," and a ",[169,286,287],{},"releaseEase"," spring so a card dropped outside the bin returns on its own.",[243,290,291],{},"On release, if the boolean was true, stop the draggable and mark the item as binned. Collapse the ghost's height and margin with a CSS transition so the list closes the gap.",[243,293,294,295,298,299,301],{},"To restore an item, set the blend value back to ",[169,296,297],{},"0"," and call ",[169,300,221],{},".",[303,304,306],"collapsible",{"name":305},"AI build prompt",[307,308,314],"pre",{"className":309,"code":311,"language":312,"meta":313},[310],"language-text","Using the nanime Nuxt module, build a Vue 3 draggable-to-bin list. For each\nlist item, render a ghost wrapper that stays in the document's normal flow\nand holds a fixed-size handle element, with the visible card absolutely\npositioned inside that handle.\n\nUse useDraggable(handle, { onGrab, onUpdate, onRelease }) so only the handle\nis the drag target. In onGrab, measure the handle's ghost rect and the bin\nelement's rect once with getBoundingClientRect(), and compute the delta\nbetween the card's rest size and the bin's size.\n\nIn onUpdate, test whether the handle's centre point falls inside the bin's\nrect and, only when that boolean changes, drive a useAnimatable value from\n0 to 1 with outQuad easing over about 350ms. Bind the card's width, height,\nand translate offset in a computed style interpolated from that animatable\nvalue, so it shrinks and slides toward the bin as it's dragged over it.\n\nGive the draggable snap: [0] and releaseEase: spring({ bounce: 0.2,\nduration: 500 }) so a card dropped outside the bin springs back to its\norigin without a release handler.\n\nOn release, if the boolean was true, call draggable.stop() and mark the item\nas binned. Collapse the ghost's height and margin-bottom to 0 with a CSS\ntransition so the rest of the list reflows to close the gap. To restore an\nitem, set the animatable value back to 0 and call draggable.reset().\n","text","",[169,315,311],{"__ignoreMap":313},{"title":313,"searchDepth":317,"depth":317,"links":318},2,[319,320,321],{"id":154,"depth":317,"text":155},{"id":161,"depth":317,"text":162},{"id":237,"depth":317,"text":238},"Dragging, hit testing, and a list that closes its own gap.","md",null,{},{"icon":116},{"title":113,"description":322},"vOEZczuU_H7uDRjEO0eKI8-xh4zrD6wNIPXIomnt72k",[330,332],{"title":108,"path":109,"stem":110,"description":331,"icon":111,"children":-1},"Independent timelines synced into one composition.",{"title":118,"path":119,"stem":120,"description":333,"icon":121,"children":-1},"Idle to loading to success.","\n::drag-to-bin-demo\n::\n\n\n::u-button\n---\nto: https:\u002F\u002Fgithub.com\u002Fastraldev\u002Fnanime\u002Fblob\u002Fmain\u002Fdocs\u002Fapp\u002Fcomponents\u002Fcontent\u002Fexamples\u002Fshowcase\u002Fdrag-to-bin\u002FDragToBinDemo.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":336,"body":337},{},{"type":338,"children":339},"root",[340,345],{"type":341,"tag":342,"props":343,"children":344},"element","drag-to-bin-demo",{},[],{"type":341,"tag":346,"props":347,"children":356},"u-button",{"className":348,"color":351,"icon":352,"target":353,"to":354,"variant":355},[349,350],"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\u002Fdrag-to-bin\u002FDragToBinDemo.vue","link",[357],{"type":312,"value":358},"View on GitHub",1788821081745]