@luna-park/plugin-motion 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,11 +8,13 @@ Powered by [anime.js](https://animejs.com), and what you see in the editor previ
8
8
 
9
9
  | | |
10
10
  |---|---|
11
- | 🎬 **18 ready-made presets** | Enter, emphasis and ambient animations, one click away. |
11
+ | 🎬 **19 ready-made presets** | Enter, emphasis and ambient animations, one click away. |
12
12
  | 🔢 **Count-up** | Numbers count up from 0 (e.g. `0 → 4.9`) when they appear, or as you scroll. |
13
13
  | 🌄 **Scroll-linked & parallax** | Tie any animation to the scroll position, stopping at the center of the page or continuing past it. |
14
14
  | 🧈 **Smooth scroll** | Lenis-powered inertia scrolling for the whole app, in one switch. |
15
- | 🎛️ **Custom from/to** | Animate opacity, position, scale, rotation and blur between your own values. |
15
+ | 🔗 **Smooth anchor links** | Links to a section scroll to it smoothly, stopping below your sticky header. |
16
+ | 📰 **Marquee** | Turn a row into an endless ticker or logo strip. Items are repeated for you. |
17
+ | 🎛️ **Custom from/to** | Animate opacity, position, scale, rotation and blur between your own values, with optional keyframes in between. |
16
18
  | 🎯 **7 triggers** | On mount, when visible, synced with scroll, on hover, on press, on focus, or driven by a state. |
17
19
  | 🌊 **Stagger** | Cascade the animation over children, over sibling elements (lists!), from the first, last, center or at random. |
18
20
  | 🔤 **Split text** | Animate a text letter by letter, word by word, or line by line. |
@@ -30,8 +32,8 @@ Powered by [anime.js](https://animejs.com), and what you see in the editor previ
30
32
  |---|---|---|
31
33
  | **Enter** | `fade`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `zoom`, `blur`, `count` | Make an element appear (on mount, when scrolled into view…). |
32
34
  | **Emphasis** | `grow`, `shrink`, `lift`, `tilt` | Small feedback on interaction, best with hover, press, focus or state. |
33
- | **Ambient** | `pulse`, `float`, `spin`, `shake`, `blink`, `wiggle` | Loop forever to draw attention. |
34
- | **Custom** | `custom` | Animate from your **From** values to your **To** values (`opacity`, `x`, `y`, `scale`, `rotate`, `blur`). |
35
+ | **Ambient** | `pulse`, `float`, `spin`, `shake`, `blink`, `wiggle`, `marquee` | Loop forever to draw attention. |
36
+ | **Custom** | `custom` | Animate from your **From** values to your **To** values (`opacity`, `x`, `y`, `scale`, `scaleX`, `scaleY`, `rotate`, `blur`). |
35
37
 
36
38
  ## 🎯 Triggers
37
39
 
@@ -53,6 +55,8 @@ Powered by [anime.js](https://animejs.com), and what you see in the editor previ
53
55
  | **Easing** | `linear`, `outQuad`, `outCubic`, `outExpo`, `inOutSine`, `outBack`, `outElastic`, `outBounce`. |
54
56
  | **Loops** | Number of repetitions, `-1` for infinite. Ambient presets loop by default. |
55
57
  | **Alternate** | Play back and forth instead of restarting each loop. |
58
+ | **Keyframes** | With a **Custom** animation, steps played between **From** and **To**, evenly spaced. Use them for a squash, a wiggle or a bounce. |
59
+ | **Stepped** | Jump through that many frames instead of moving smoothly, for a retro or stop-motion feel. |
56
60
  | **Stagger** | Delay between each animated item, in milliseconds. |
57
61
  | **Stagger from** | Where the cascade starts: `first`, `center`, `last` or `random`. |
58
62
  | **Scroll anchor** / **Scroll target** / **Scroll mode** | With **Synced with scroll**, see [Scroll options](#-scroll-options). |
@@ -63,6 +67,9 @@ Powered by [anime.js](https://animejs.com), and what you see in the editor previ
63
67
  >
64
68
  > **Parallax**: pick **Synced with scroll**, **Continue past target** and a **Custom** animation with **From → Y** set to e.g. `100px`. The element is `100px` low when it enters, in place at the target, and keeps rising at the same pace afterwards, so it moves faster than the page. Use a negative value to make it lag behind, like a background. **Continue past target** uses `linear` easing unless you pick one.
65
69
 
70
+ > [!TIP]
71
+ > **Marquee**: put it on a row (`display: flex`) inside a parent with `overflow: hidden`, and list your items once. Motion repeats them so the loop is seamless, and hides the copies from screen readers. **Duration** is the time of one pass.
72
+
66
73
  > [!TIP]
67
74
  > **Stagger** adapts to what you put it on:
68
75
  > - On a **single element**, its children are animated one after the other. Children added later are animated too.
@@ -94,6 +101,8 @@ With the defaults, the animation starts when the top of the element appears and
94
101
  | **Default easing** | `outExpo` | Used by every animation without its own easing (ambient presets have their own). |
95
102
  | **Smooth scroll** | `false` | Smooth the scroll of the whole app with [Lenis](https://lenis.darkroom.engineering). |
96
103
  | **Smooth scroll intensity** | `0.1` | Lenis `lerp`, between `0.01` and `1`. Lower is smoother. |
104
+ | **Smooth anchor links** | `false` | Links to a section of the page (`#pricing`) scroll to it smoothly. |
105
+ | **Anchor offset** | `0` | Space kept above the section, in pixels, e.g. the height of a sticky header. |
97
106
  | **Reduced motion** | `reduce` | With `reduce`, visitors who prefer reduced motion get instant transitions, no delays, no looping or scroll-synced animations, and no smooth scroll. Use `ignore` to always play everything. |
98
107
 
99
108
  ## 📦 In your deployed app
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.motion-card[data-v-0dfc3339]{gap:var(--length-xxs);background:var(--color-background-dark);padding:var(--length-xs);border-radius:var(--length-radius-s);flex-direction:column;display:flex}.motion-card .header[data-v-0dfc3339]{font-size:var(--font-size-xs);color:var(--color-content-lite);align-items:center;gap:var(--length-xxs);display:flex}.motion-card .header .title[data-v-0dfc3339]{align-items:center;gap:var(--length-xxs);flex:1;display:flex}.motion-card .header .title .icon[data-v-0dfc3339]{font-size:var(--font-icon-xxs);color:var(--color-content-liter)}.motion-card .header .title .hint[data-v-0dfc3339]{color:var(--color-content-litest)}.motion-panel[data-v-7f091a1a]{flex-direction:column;display:flex}.motion-panel .cards[data-v-7f091a1a]{margin:var(--length-xs);gap:var(--length-xs);flex-direction:column;display:flex}.motion-panel .option[data-v-7f091a1a]{align-items:center;gap:var(--length-xs);display:flex}.motion-panel .option .label[data-v-7f091a1a]{width:48px;font-size:var(--font-size-xs);color:var(--color-content-liter)}.motion-panel .option .input[data-v-7f091a1a]{flex:1}.motion-panel .curve[data-v-7f091a1a]{width:16px;height:16px}.motion-panel .curve polyline[data-v-7f091a1a]{fill:none;stroke:currentColor;stroke-width:1.5px;stroke-linecap:round;stroke-linejoin:round}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
2
- import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s as ee, t as te } from "./runtime-BDFfjVth.js";
1
+ (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.motion-card[data-v-0dfc3339]{gap:var(--length-xxs);background:var(--color-background-dark);padding:var(--length-xs);border-radius:var(--length-radius-s);flex-direction:column;display:flex}.motion-card .header[data-v-0dfc3339]{font-size:var(--font-size-xs);color:var(--color-content-lite);align-items:center;gap:var(--length-xxs);display:flex}.motion-card .header .title[data-v-0dfc3339]{align-items:center;gap:var(--length-xxs);flex:1;display:flex}.motion-card .header .title .icon[data-v-0dfc3339]{font-size:var(--font-icon-xxs);color:var(--color-content-liter)}.motion-card .header .title .hint[data-v-0dfc3339]{color:var(--color-content-litest)}.motion-panel[data-v-a6164aab]{flex-direction:column;display:flex}.motion-panel .cards[data-v-a6164aab]{margin:var(--length-xs);gap:var(--length-xs);flex-direction:column;display:flex}.motion-panel .option[data-v-a6164aab]{align-items:center;gap:var(--length-xs);display:flex}.motion-panel .option .label[data-v-a6164aab]{width:48px;font-size:var(--font-size-xs);color:var(--color-content-liter)}.motion-panel .option .input[data-v-a6164aab]{flex:1}.motion-panel .curve[data-v-a6164aab]{width:16px;height:16px}.motion-panel .curve polyline[data-v-a6164aab]{fill:none;stroke:currentColor;stroke-width:1.5px;stroke-linecap:round;stroke-linejoin:round}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
2
+ import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s as ee, t as te } from "./runtime-cHamDyz2.js";
3
3
  import { Fragment as ne, computed as re, createBlock as ie, createCommentVNode as ae, createElementBlock as oe, createElementVNode as se, createSlots as ce, createTextVNode as le, createVNode as ue, defineComponent as de, markRaw as fe, openBlock as pe, ref as me, renderList as he, renderSlot as ge, toDisplayString as _e, unref as s, watch as ve, withCtx as ye } from "vue";
4
4
  import { LIcon as be, LInput as xe, LSegmented as Se } from "@luna-park/design";
5
5
  //#region \0rolldown/runtime.js
@@ -3234,7 +3234,7 @@ function Ld(e) {
3234
3234
  }
3235
3235
  //#endregion
3236
3236
  //#region src/llm.md?raw
3237
- var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plugin.motion.<field>` attributes, with `:` for numbers, booleans, objects and bindings: `<div plugin.motion.preset=\"slide-up\" plugin.motion.trigger=\"visible\" :plugin.motion.duration=\"800\" />`.\n\n## Presets\n- Enter, from a start state to the element's normal look: `fade`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `zoom`, `blur`, `count` (counts the first number in the text from `countFrom` up to its value).\n- Emphasis, from the normal look to a target: `grow`, `shrink`, `lift`, `tilt`.\n- Ambient, looping forever: `pulse`, `float`, `spin`, `shake`, `blink`, `wiggle`.\n- `custom`: animates from `from` to `to`, both objects with `x`, `y` (px), `scale`, `rotate` (degrees), `opacity` and `blur` (px). Missing keys use the normal look (`x: 0, y: 0, scale: 1, rotate: 0, opacity: 1, blur: 0`). `from`/`to` are ignored by other presets.\n\n## Triggers\n- `mount` (default): plays when the element is mounted.\n- `visible`: plays once, the first time the element enters the screen.\n- `scroll`: progress follows the scroll position. `scrollAnchor` (`top`/`center`), `scrollTarget` (screen % where it ends, default 50) and `scrollMode` (`stop`, `continue`, `hold`) tune it.\n- `hover`, `press`, `focus`: plays forward on enter and backward on leave.\n- `state`: follows the `state` boolean, e.g. `:plugin.motion.state=\"menuOpen\"`. The first value is applied instantly (`true` shows the end, `false` the start); later changes play forward (`true`) or backward (`false`).\n\n## Timing\n- `duration` and `delay` are in milliseconds. `duration` defaults to the plugin setting (600 ms), `delay` to 0.\n- `loop`: extra repetitions. `0` plays once, `-1` repeats forever. Without it, ambient presets loop forever and the others play once.\n- `alternate`: plays every other repetition backward.\n- `ease`: `linear`, `outQuad`, `outCubic`, `outExpo` (default), `inOutSine`, `outBack`, `outElastic`, `outBounce`.\n- `stagger` (ms) plays the children one after another, from `staggerFrom` (`first`, `center`, `last`, `random`). Sibling elements with the same settings are staggered together.\n- `split` (`chars`, `words`, `lines`) splits the text and staggers the pieces. It rewrites the element's text, so only use it on static text.\n\n## Notes\n- Motion sets inline `transform`, `opacity` and `filter` styles, and turns `inline` targets into `inline-block`.\n- When the visitor prefers reduced motion (plugin setting `reducedMotion: \"reduce\"`), animations finish instantly and looping or scroll animations are skipped.\n- The Motion panel's Replay button replays the selected element's animation in the editor. It does not rerun the page's logic or reset its variables; reopen the page for that.\n- To replay an animation from logic, prefer the `state` trigger and toggle its variable, instead of hiding and showing the element.\n", zd = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='utf-8'?%3e%3c!--%20Generator:%20Adobe%20Illustrator%2027.5.0,%20SVG%20Export%20Plug-In%20.%20SVG%20Version:%206.00%20Build%200)%20--%3e%3csvg%20version='1.1'%20id='Calque_1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20x='0px'%20y='0px'%20viewBox='0%200%20100%20100'%20style='enable-background:new%200%200%20100%20100;'%20xml:space='preserve'%3e%3cstyle%20type='text/css'%3e%20.st0{clip-path:url(%23SVGID_00000047022933307920725830000016124621795394122405_);fill:url(%23SVGID_00000173862278939040857730000006968173594089226137_);}%20%3c/style%3e%3cg%3e%3cdefs%3e%3cpath%20id='SVGID_1_'%20d='M90.2,51c0,1.8-0.2,3.7-0.5,5.5c-0.2,1.3-1.9,1.9-2.8,0.9L69,39.4C58.5,29,41.5,29,31.1,39.4L13.1,57.4%20c-1,1-2.6,0.4-2.8-0.9c-3.7-22,12.3-43.9,34.9-46.4C69.2,7,91,26.8,90.2,51z%20M55.7,44.4c-3.6-1.5-7.7-1.5-11.3,0%20c-0.6,0.3-1,0.9-1,1.6v42.2c0,0.8,0.6,1.6,1.5,1.7c3.5,0.5,7,0.5,10.5,0c0.8-0.1,1.5-0.8,1.5-1.7V46%20C56.7,45.3,56.3,44.7,55.7,44.4z%20M83.2,70.3c-3.2-3.2-8.2-8.2-11.9-11.9c-1.1-1.1-2.9-0.3-2.9,1.2v23.3c0,1.3,1.4,2.1,2.5,1.4%20c4.9-3,9.2-7.1,12.4-11.9C83.9,71.7,83.8,70.8,83.2,70.3z%20M28.7,58.4C25,62.1,20,67.1,16.8,70.3c-0.6,0.6-0.6,1.5-0.2,2.1%20c3.2,4.8,7.5,8.9,12.4,11.9c1.1,0.7,2.5-0.1,2.5-1.4V59.5C31.6,58,29.8,57.3,28.7,58.4z'/%3e%3c/defs%3e%3cclipPath%20id='SVGID_00000176734456353677071660000015084933141304141444_'%3e%3cuse%20xlink:href='%23SVGID_1_'%20style='overflow:visible;'/%3e%3c/clipPath%3e%3cradialGradient%20id='SVGID_00000019658959786127304010000007409785301083503023_'%20cx='-322.5985'%20cy='231.969'%20r='47.68'%20fx='-327.6757'%20fy='225.8638'%20gradientTransform='matrix(0.7606%200%200%200.7606%20295.3712%20-126.4447)'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0'%20style='stop-color:%23187BFF'/%3e%3cstop%20offset='1'%20style='stop-color:%230066F1'/%3e%3c/radialGradient%3e%3crect%20x='9.8'%20y='9.8'%20style='clip-path:url(%23SVGID_00000176734456353677071660000015084933141304141444_);fill:url(%23SVGID_00000019658959786127304010000007409785301083503023_);'%20width='80.4'%20height='80.4'/%3e%3c/g%3e%3c/svg%3e", Bd = {
3237
+ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plugin.motion.<field>` attributes, with `:` for numbers, booleans, objects and bindings: `<div plugin.motion.preset=\"slide-up\" plugin.motion.trigger=\"visible\" :plugin.motion.duration=\"800\" />`.\n\n## Presets\n- Enter, from a start state to the element's normal look: `fade`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `zoom`, `blur`, `count` (counts the first number in the text from `countFrom` up to its value).\n- Emphasis, from the normal look to a target: `grow`, `shrink`, `lift`, `tilt`.\n- Ambient, looping forever: `pulse`, `float`, `spin`, `shake`, `blink`, `wiggle`, `marquee`.\n- `custom`: animates from `from` to `to`, both objects with `x`, `y` (px), `scale`, `scaleX`, `scaleY`, `rotate` (degrees), `opacity` and `blur` (px). Missing keys use the normal look (`x: 0, y: 0, scale: 1, scaleX: 1, scaleY: 1, rotate: 0, opacity: 1, blur: 0`). `from`/`to` are ignored by other presets.\n- `keyframes` adds evenly spaced steps between `from` and `to` of a `custom` preset, as an array of the same objects. A jelly squash on hover: `plugin.motion.preset=\"custom\" plugin.motion.trigger=\"hover\" :plugin.motion.keyframes=\"[{scaleX:1.08,scaleY:0.92},{scaleX:0.94,scaleY:1.06},{scaleX:1.03,scaleY:0.97}]\" :plugin.motion.duration=\"520\"`. A wiggle that ends where it started: `:plugin.motion.keyframes=\"[{rotate:-3},{rotate:3}]\"`.\n- `marquee` scrolls the children of a row sideways forever, for tickers and logo strips. Put it on a flex row (`display:flex`) inside a parent with `overflow:hidden`, and list the items once: Motion repeats them, hides the copies from screen readers and loops seamlessly, `gap` included. `duration` is the time of one pass (default 20000 ms).\n\n## Triggers\n- `mount` (default): plays when the element is mounted.\n- `visible`: plays once, the first time the element enters the screen.\n- `scroll`: progress follows the scroll position. `scrollAnchor` (`top`/`center`), `scrollTarget` (screen % where it ends, default 50) and `scrollMode` (`stop`, `continue`, `hold`) tune it.\n- `hover`, `press`, `focus`: plays forward on enter and backward on leave.\n- `state`: follows the `state` boolean, e.g. `:plugin.motion.state=\"menuOpen\"`. The first value is applied instantly (`true` shows the end, `false` the start); later changes play forward (`true`) or backward (`false`).\n\n## Timing\n- `duration` and `delay` are in milliseconds. `duration` defaults to the plugin setting (600 ms), `delay` to 0.\n- `loop`: extra repetitions. `0` plays once, `-1` repeats forever. Without it, ambient presets loop forever and the others play once.\n- `alternate`: plays every other repetition backward.\n- `ease`: `linear`, `outQuad`, `outCubic`, `outExpo` (default), `inOutSine`, `outBack`, `outElastic`, `outBounce`.\n- `stepped`: plays in that many jumps instead of a smooth move, like CSS `steps()`. `:plugin.motion.stepped=\"2\"` with `alternate` and `loop` makes a two-frame wobble.\n- `stagger` (ms) plays the children one after another, from `staggerFrom` (`first`, `center`, `last`, `random`). Sibling elements with the same settings are staggered together.\n- `split` (`chars`, `words`, `lines`) splits the text and staggers the pieces. It rewrites the element's text, so only use it on static text.\n\n## Loops and interaction states\n- Use Motion for looping decoration instead of `@keyframes` in `.inject/style.css`. Ambient presets cover the common loops: a blinking light is `plugin.motion.preset=\"blink\"`, a bobbing mascot `float`, a breathing badge `pulse`.\n- Any other two-state loop is a `custom` preset with `loop` and `alternate`: `plugin.motion.preset=\"custom\" :plugin.motion.to=\"{scale:0.55,rotate:45}\" :plugin.motion.loop=\"-1\" :plugin.motion.alternate=\"true\" plugin.motion.ease=\"inOutSine\" :plugin.motion.duration=\"1300\"`. `duration` is one direction, so a 2.6 s CSS cycle is 1300 ms. Without `alternate` the loop restarts from the start, which suits a one-way slide with `ease=\"linear\"`.\n- Offset identical loops with `delay` so they do not move in unison.\n- Hover, press and focus feedback that moves, scales or rotates the element uses the `hover`, `press` and `focus` triggers, e.g. `plugin.motion.preset=\"shrink\" plugin.motion.trigger=\"press\"`. Feedback that changes colours, shadows or outlines uses the layout's own `style:hover`, `style:active` and `style:focus-visible` states, never a `data-*` attribute styled from global CSS.\n- Keep `@keyframes` in `.inject/style.css` only for properties Motion does not animate (colours, shadows, clip paths). Multi-step moves use `keyframes`, stepped timing uses `stepped`, tickers use `marquee`.\n\n## Plugin settings\n- `anchorScroll` makes links to a section (`href=\"#pricing\"`) scroll smoothly, and `anchorOffset` (px) keeps that much space above the section, e.g. the height of a sticky header. Turn it on instead of writing `scroll-behavior` and `scroll-margin-top` in `.inject/style.css`. It follows `reducedMotion` and works with `smoothScroll`.\n- `smoothScroll` adds inertia to the whole page scroll (`smoothScrollLerp` tunes it).\n\n## Notes\n- Motion sets inline `transform`, `opacity` and `filter` styles, and turns `inline` targets into `inline-block`.\n- When the visitor prefers reduced motion (plugin setting `reducedMotion: \"reduce\"`), animations finish instantly and looping or scroll animations are skipped.\n- The Motion panel's Replay button replays the selected element's animation in the editor. It does not rerun the page's logic or reset its variables; reopen the page for that.\n- To replay an animation from logic, prefer the `state` trigger and toggle its variable, instead of hiding and showing the element.\n", zd = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='utf-8'?%3e%3c!--%20Generator:%20Adobe%20Illustrator%2027.5.0,%20SVG%20Export%20Plug-In%20.%20SVG%20Version:%206.00%20Build%200)%20--%3e%3csvg%20version='1.1'%20id='Calque_1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20x='0px'%20y='0px'%20viewBox='0%200%20100%20100'%20style='enable-background:new%200%200%20100%20100;'%20xml:space='preserve'%3e%3cstyle%20type='text/css'%3e%20.st0{clip-path:url(%23SVGID_00000047022933307920725830000016124621795394122405_);fill:url(%23SVGID_00000173862278939040857730000006968173594089226137_);}%20%3c/style%3e%3cg%3e%3cdefs%3e%3cpath%20id='SVGID_1_'%20d='M90.2,51c0,1.8-0.2,3.7-0.5,5.5c-0.2,1.3-1.9,1.9-2.8,0.9L69,39.4C58.5,29,41.5,29,31.1,39.4L13.1,57.4%20c-1,1-2.6,0.4-2.8-0.9c-3.7-22,12.3-43.9,34.9-46.4C69.2,7,91,26.8,90.2,51z%20M55.7,44.4c-3.6-1.5-7.7-1.5-11.3,0%20c-0.6,0.3-1,0.9-1,1.6v42.2c0,0.8,0.6,1.6,1.5,1.7c3.5,0.5,7,0.5,10.5,0c0.8-0.1,1.5-0.8,1.5-1.7V46%20C56.7,45.3,56.3,44.7,55.7,44.4z%20M83.2,70.3c-3.2-3.2-8.2-8.2-11.9-11.9c-1.1-1.1-2.9-0.3-2.9,1.2v23.3c0,1.3,1.4,2.1,2.5,1.4%20c4.9-3,9.2-7.1,12.4-11.9C83.9,71.7,83.8,70.8,83.2,70.3z%20M28.7,58.4C25,62.1,20,67.1,16.8,70.3c-0.6,0.6-0.6,1.5-0.2,2.1%20c3.2,4.8,7.5,8.9,12.4,11.9c1.1,0.7,2.5-0.1,2.5-1.4V59.5C31.6,58,29.8,57.3,28.7,58.4z'/%3e%3c/defs%3e%3cclipPath%20id='SVGID_00000176734456353677071660000015084933141304141444_'%3e%3cuse%20xlink:href='%23SVGID_1_'%20style='overflow:visible;'/%3e%3c/clipPath%3e%3cradialGradient%20id='SVGID_00000019658959786127304010000007409785301083503023_'%20cx='-322.5985'%20cy='231.969'%20r='47.68'%20fx='-327.6757'%20fy='225.8638'%20gradientTransform='matrix(0.7606%200%200%200.7606%20295.3712%20-126.4447)'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20offset='0'%20style='stop-color:%23187BFF'/%3e%3cstop%20offset='1'%20style='stop-color:%230066F1'/%3e%3c/radialGradient%3e%3crect%20x='9.8'%20y='9.8'%20style='clip-path:url(%23SVGID_00000176734456353677071660000015084933141304141444_);fill:url(%23SVGID_00000019658959786127304010000007409785301083503023_);'%20width='80.4'%20height='80.4'/%3e%3c/g%3e%3c/svg%3e", Bd = {
3238
3238
  prefix: "fas",
3239
3239
  iconName: "down-left-and-up-right-to-center",
3240
3240
  icon: [
@@ -3603,6 +3603,16 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3603
3603
  "M448 96c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 320c0 17.7 14.3 32 32 32s32-14.3 32-32l0-320zM310.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L210.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l178.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z"
3604
3604
  ]
3605
3605
  }, Cf = {
3606
+ prefix: "fas",
3607
+ iconName: "angles-left",
3608
+ icon: [
3609
+ 512,
3610
+ 512,
3611
+ [171, "angle-double-left"],
3612
+ "f100",
3613
+ "M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z"
3614
+ ]
3615
+ }, wf = {
3606
3616
  prefix: "fas",
3607
3617
  iconName: "arrow-up-from-line",
3608
3618
  icon: [
@@ -3612,7 +3622,7 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3612
3622
  "f342",
3613
3623
  "M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.3l0 66.7 0 112c0 17.7 14.3 32 32 32s32-14.3 32-32l0-112 0-66.7 73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128zM32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32l320 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 416z"
3614
3624
  ]
3615
- }, wf = {
3625
+ }, Tf = {
3616
3626
  prefix: "fas",
3617
3627
  iconName: "up-right-and-down-left-from-center",
3618
3628
  icon: [
@@ -3622,10 +3632,10 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3622
3632
  "f424",
3623
3633
  "M344 0L488 0c13.3 0 24 10.7 24 24l0 144c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-87 87c-9.4 9.4-24.6 9.4-33.9 0l-32-32c-9.4-9.4-9.4-24.6 0-33.9l87-87L327 41c-6.9-6.9-8.9-17.2-5.2-26.2S334.3 0 344 0zM168 512L24 512c-13.3 0-24-10.7-24-24L0 344c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39 87-87c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8z"
3624
3634
  ]
3625
- }, Tf = { class: "motion-card" }, Ef = { class: "header" }, Df = { class: "title" }, Of = {
3635
+ }, Ef = { class: "motion-card" }, Df = { class: "header" }, Of = { class: "title" }, kf = {
3626
3636
  key: 0,
3627
3637
  class: "hint"
3628
- }, kf = /*@__PURE__*/ de({
3638
+ }, Af = /*@__PURE__*/ de({
3629
3639
  __name: "LMotionCard",
3630
3640
  props: {
3631
3641
  hint: {},
@@ -3633,23 +3643,23 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3633
3643
  title: {}
3634
3644
  },
3635
3645
  setup(e) {
3636
- return (t, n) => (pe(), oe("div", Tf, [se("div", Ef, [se("div", Df, [
3646
+ return (t, n) => (pe(), oe("div", Ef, [se("div", Df, [se("div", Of, [
3637
3647
  ue(s(be), {
3638
3648
  class: "icon",
3639
3649
  icon: e.icon
3640
3650
  }, null, 8, ["icon"]),
3641
3651
  le(" " + _e(e.title) + " ", 1),
3642
- e.hint ? (pe(), oe("span", Of, _e(e.hint), 1)) : ae("", !0)
3652
+ e.hint ? (pe(), oe("span", kf, _e(e.hint), 1)) : ae("", !0)
3643
3653
  ]), ge(t.$slots, "header", {}, void 0, !0)]), ge(t.$slots, "default", {}, void 0, !0)]));
3644
3654
  }
3645
- }), Af = (e, t) => {
3655
+ }), jf = (e, t) => {
3646
3656
  let n = e.__vccOpts || e;
3647
3657
  for (let [e, r] of t) n[e] = r;
3648
3658
  return n;
3649
- }, jf = /*#__PURE__*/ Af(kf, [["__scopeId", "data-v-0dfc3339"]]), Mf = { class: "motion-panel" }, Nf = { class: "cards" }, Pf = { class: "option" }, Ff = { class: "option" }, If = { class: "option" }, Lf = {
3659
+ }, Mf = /*#__PURE__*/ jf(Af, [["__scopeId", "data-v-0dfc3339"]]), Nf = { class: "motion-panel" }, Pf = { class: "cards" }, Ff = { class: "option" }, If = { class: "option" }, Lf = { class: "option" }, Rf = {
3650
3660
  class: "curve",
3651
3661
  viewBox: "0 0 24 24"
3652
- }, Rf = ["points"], zf = /*#__PURE__*/ Af(/* @__PURE__ */ de({
3662
+ }, zf = ["points"], Bf = /*#__PURE__*/ jf(/* @__PURE__ */ de({
3653
3663
  __name: "LMotionPanel",
3654
3664
  props: {
3655
3665
  getElements: { type: Function },
@@ -3664,8 +3674,9 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3664
3674
  count: lf,
3665
3675
  fade: bf,
3666
3676
  float: Ud,
3667
- grow: wf,
3668
- lift: Cf,
3677
+ grow: Tf,
3678
+ lift: wf,
3679
+ marquee: Cf,
3669
3680
  pulse: Zd,
3670
3681
  shake: nf,
3671
3682
  shrink: Bd,
@@ -3812,8 +3823,8 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3812
3823
  return `${3 + r * 18},${17 - n(r) * 10}`;
3813
3824
  }).join(" ");
3814
3825
  }
3815
- return (n, r) => (pe(), oe("div", Mf, [se("div", Nf, [
3816
- ue(jf, {
3826
+ return (n, r) => (pe(), oe("div", Nf, [se("div", Pf, [
3827
+ ue(Mf, {
3817
3828
  hint: le.find((e) => e.value === t.modelValue.trigger)?.title,
3818
3829
  icon: s(mf),
3819
3830
  title: "Trigger"
@@ -3825,19 +3836,19 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3825
3836
  wide: "",
3826
3837
  "onUpdate:modelValue": r[0] ||= (e) => l("trigger", e)
3827
3838
  }, null, 8, ["model-value"]), t.modelValue.trigger === "scroll" ? (pe(), oe(ne, { key: 0 }, [
3828
- se("div", Pf, [r[7] ||= se("span", { class: "label" }, "Anchor", -1), ue(s(Se), {
3839
+ se("div", Ff, [r[7] ||= se("span", { class: "label" }, "Anchor", -1), ue(s(Se), {
3829
3840
  "model-value": t.modelValue.scrollAnchor ?? "top",
3830
3841
  options: fe,
3831
3842
  small: "",
3832
3843
  "onUpdate:modelValue": r[1] ||= (e) => l("scrollAnchor", e)
3833
3844
  }, null, 8, ["model-value"])]),
3834
- se("div", Ff, [r[8] ||= se("span", { class: "label" }, "Mode", -1), ue(s(Se), {
3845
+ se("div", If, [r[8] ||= se("span", { class: "label" }, "Mode", -1), ue(s(Se), {
3835
3846
  "model-value": t.modelValue.scrollMode ?? "stop",
3836
3847
  options: ge,
3837
3848
  small: "",
3838
3849
  "onUpdate:modelValue": r[2] ||= (e) => l("scrollMode", e)
3839
3850
  }, null, 8, ["model-value"])]),
3840
- se("div", If, [r[9] ||= se("span", { class: "label" }, "Target", -1), ue(s(xe), {
3851
+ se("div", Lf, [r[9] ||= se("span", { class: "label" }, "Target", -1), ue(s(xe), {
3841
3852
  class: "input",
3842
3853
  "model-value": t.modelValue.scrollTarget ?? 50,
3843
3854
  options: {
@@ -3853,7 +3864,7 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3853
3864
  ], 64)) : ae("", !0)]),
3854
3865
  _: 1
3855
3866
  }, 8, ["hint", "icon"]),
3856
- ue(jf, {
3867
+ ue(Mf, {
3857
3868
  hint: Te(t.modelValue.preset),
3858
3869
  icon: s(qd),
3859
3870
  title: "Animation"
@@ -3874,7 +3885,7 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3874
3885
  }, null, 8, ["model-value", "options"]))]),
3875
3886
  _: 1
3876
3887
  }, 8, ["hint", "icon"]),
3877
- ue(jf, {
3888
+ ue(Mf, {
3878
3889
  hint: t.modelValue.ease ?? `${s(e).ease} (default)`,
3879
3890
  icon: s(af),
3880
3891
  title: "Easing"
@@ -3887,15 +3898,15 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3887
3898
  "onUpdate:modelValue": r[6] ||= (e) => l("ease", e)
3888
3899
  }, ce({ _: 2 }, [he(s(o), (e) => ({
3889
3900
  name: e,
3890
- fn: ye(() => [(pe(), oe("svg", Lf, [se("polyline", { points: Ee(e) }, null, 8, Rf)]))])
3901
+ fn: ye(() => [(pe(), oe("svg", Rf, [se("polyline", { points: Ee(e) }, null, 8, zf)]))])
3891
3902
  }))]), 1032, ["model-value", "options"])]),
3892
3903
  _: 1
3893
3904
  }, 8, ["hint", "icon"])
3894
3905
  ])]));
3895
3906
  }
3896
- }), [["__scopeId", "data-v-7f091a1a"]]), Bf = {
3907
+ }), [["__scopeId", "data-v-a6164aab"]]), Vf = {
3897
3908
  name: "@luna-park/plugin-motion",
3898
- version: "1.3.0",
3909
+ version: "1.4.0",
3899
3910
  private: !1,
3900
3911
  description: "Motion plugin for Luna Park.",
3901
3912
  keywords: [
@@ -3950,7 +3961,7 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3950
3961
  "@luna-park/design": "^1.6.0",
3951
3962
  vue: "^3.5.24"
3952
3963
  }
3953
- }, Vf = [
3964
+ }, Hf = [
3954
3965
  "mount",
3955
3966
  "visible",
3956
3967
  "scroll",
@@ -3958,46 +3969,57 @@ var Rd = "# Motion plugin\n\nAnimates any layout element. Set its fields as `plu
3958
3969
  "press",
3959
3970
  "focus",
3960
3971
  "state"
3961
- ];
3962
- function Hf(e) {
3963
- return l.object({
3964
- blur: l.number({
3965
- default: 0,
3966
- name: "Blur",
3967
- options: { suffix: "px" }
3968
- }),
3969
- opacity: l.number({
3970
- default: 1,
3971
- name: "Opacity"
3972
- }),
3973
- rotate: l.number({
3974
- default: 0,
3975
- name: "Rotate (deg)"
3976
- }),
3977
- scale: l.number({
3978
- default: 1,
3979
- name: "Scale"
3980
- }),
3981
- x: l.number({
3982
- default: 0,
3983
- name: "X",
3984
- options: { suffix: "px" }
3985
- }),
3986
- y: l.number({
3987
- default: 0,
3988
- name: "Y",
3989
- options: { suffix: "px" }
3990
- })
3991
- }, {
3972
+ ], Uf = {
3973
+ blur: l.number({
3974
+ default: 0,
3975
+ name: "Blur",
3976
+ options: { suffix: "px" }
3977
+ }),
3978
+ opacity: l.number({
3979
+ default: 1,
3980
+ name: "Opacity"
3981
+ }),
3982
+ rotate: l.number({
3983
+ default: 0,
3984
+ name: "Rotate (deg)"
3985
+ }),
3986
+ scale: l.number({
3987
+ default: 1,
3988
+ name: "Scale"
3989
+ }),
3990
+ scaleX: l.number({
3991
+ default: 1,
3992
+ name: "Scale X"
3993
+ }),
3994
+ scaleY: l.number({
3995
+ default: 1,
3996
+ name: "Scale Y"
3997
+ }),
3998
+ x: l.number({
3999
+ default: 0,
4000
+ name: "X",
4001
+ options: { suffix: "px" }
4002
+ }),
4003
+ y: l.number({
4004
+ default: 0,
4005
+ name: "Y",
4006
+ options: { suffix: "px" }
4007
+ })
4008
+ };
4009
+ function Wf(e) {
4010
+ return e.preset !== "custom";
4011
+ }
4012
+ function Gf(e) {
4013
+ return l.object(Uf, {
3992
4014
  name: e,
3993
- options: { hidden: (e) => e.preset !== "custom" }
4015
+ options: { hidden: Wf }
3994
4016
  });
3995
4017
  }
3996
- var Uf = {
3997
- component: fe(zf),
4018
+ var Kf = {
4019
+ component: fe(Bf),
3998
4020
  directive: {
3999
4021
  build: {
4000
- from: `${Bf.name}/runtime`,
4022
+ from: `${Vf.name}/runtime`,
4001
4023
  name: "vMotion"
4002
4024
  },
4003
4025
  value: t
@@ -4040,7 +4062,14 @@ var Uf = {
4040
4062
  optional: !0,
4041
4063
  options: { hidden: !0 }
4042
4064
  }),
4043
- from: Hf("From"),
4065
+ from: Gf("From"),
4066
+ keyframes: l.array(l.object(Uf, { name: "Step" }), {
4067
+ default: [],
4068
+ description: "Steps played between From and To, evenly spaced",
4069
+ name: "Keyframes",
4070
+ optional: !0,
4071
+ options: { hidden: Wf }
4072
+ }),
4044
4073
  loop: l.number({
4045
4074
  default: -1,
4046
4075
  description: "-1 = infinite",
@@ -4113,37 +4142,54 @@ var Uf = {
4113
4142
  name: "State",
4114
4143
  options: { hidden: (e) => e.trigger !== "state" }
4115
4144
  }),
4116
- to: Hf("To"),
4145
+ stepped: l.number({
4146
+ default: 2,
4147
+ description: "Jumps through this many frames instead of moving smoothly",
4148
+ name: "Stepped",
4149
+ optional: !0
4150
+ }),
4151
+ to: Gf("To"),
4117
4152
  trigger: l.string({
4118
4153
  default: "mount",
4119
- enum: Vf,
4154
+ enum: Hf,
4120
4155
  name: "Trigger",
4121
4156
  options: { hidden: !0 }
4122
4157
  })
4123
4158
  }
4124
- }, Wf = l.object({
4159
+ }, qf = l.object({
4160
+ anchorOffset: l.number({
4161
+ default: 0,
4162
+ description: "Space kept above a section reached from a link, e.g. the height of a sticky header.",
4163
+ name: "Anchor offset",
4164
+ options: { suffix: "px" }
4165
+ }),
4166
+ anchorScroll: l.boolean({
4167
+ default: !1,
4168
+ description: "Links to a section of the page (#pricing) scroll to it smoothly.",
4169
+ name: "Smooth anchor links"
4170
+ }),
4125
4171
  duration: l.number({
4126
- name: "Default duration (ms)",
4127
- default: 600
4172
+ default: 600,
4173
+ name: "Default duration (ms)"
4128
4174
  }),
4129
4175
  ease: l.string({
4130
- name: "Default easing",
4131
4176
  default: "outExpo",
4132
- enum: o
4177
+ enum: o,
4178
+ name: "Default easing"
4133
4179
  }),
4134
4180
  reducedMotion: l.string({
4135
- name: "Reduced motion",
4136
4181
  default: "reduce",
4137
- enum: ["reduce", "ignore"]
4182
+ enum: ["reduce", "ignore"],
4183
+ name: "Reduced motion"
4138
4184
  }),
4139
4185
  smoothScroll: l.boolean({
4140
- name: "Smooth scroll",
4141
- default: !1
4186
+ default: !1,
4187
+ name: "Smooth scroll"
4142
4188
  }),
4143
4189
  smoothScrollLerp: l.number({
4144
- name: "Smooth scroll intensity",
4145
4190
  default: .1,
4146
4191
  description: "Lower is smoother.",
4192
+ name: "Smooth scroll intensity",
4147
4193
  options: {
4148
4194
  clamp: !0,
4149
4195
  max: 1,
@@ -4151,10 +4197,10 @@ var Uf = {
4151
4197
  step: .01
4152
4198
  }
4153
4199
  })
4154
- }), Gf = n(!0);
4155
- function Kf({ config: e, mode: t }) {
4200
+ }), Jf = n(!0);
4201
+ function Yf({ config: e, mode: t }) {
4156
4202
  if (t === "editor") return {
4157
- component: Gf,
4203
+ component: Jf,
4158
4204
  name: "MotionScroll"
4159
4205
  };
4160
4206
  if (e.smoothScroll) return {
@@ -4163,38 +4209,46 @@ function Kf({ config: e, mode: t }) {
4163
4209
  name: "MotionScroll"
4164
4210
  };
4165
4211
  }
4166
- function qf({ config: e }) {
4212
+ function Xf({ config: e, mode: t }) {
4213
+ if (t === "editor" || !e.anchorScroll) return "";
4214
+ let n = `[id] { scroll-margin-top: ${e.anchorOffset}px; }`;
4215
+ if (e.smoothScroll) return n;
4216
+ let r = "html { scroll-behavior: smooth; }";
4217
+ return `${n} ${e.reducedMotion === "reduce" ? `@media (prefers-reduced-motion: no-preference) { ${r} }` : r}`;
4218
+ }
4219
+ function Zf({ config: e }) {
4167
4220
  i(e);
4168
4221
  }
4169
- var Jf = Ld({
4170
- id: "motion",
4171
- name: "Motion",
4172
- description: "Animate elements with anime.js.",
4173
- llm: Rd,
4222
+ var Qf = Ld({
4174
4223
  build: {
4175
4224
  frontImports: [{
4176
- name: Bf.name,
4177
- version: Bf.version
4225
+ name: Vf.name,
4226
+ version: Vf.version
4178
4227
  }],
4179
4228
  injections: ({ config: e }) => ({
4180
- [Jl.AppImport]: `import { MotionScroll } from "${Bf.name}/runtime";`,
4229
+ [Jl.AppImport]: `import { MotionScroll } from "${Vf.name}/runtime";`,
4181
4230
  [Jl.AppBody]: "app.component(\"MotionScroll\", MotionScroll);",
4182
4231
  [Jl.AppSetup]: `
4183
- import { configureMotion } from "${Bf.name}/runtime";
4232
+ import { configureMotion } from "${Vf.name}/runtime";
4184
4233
  configureMotion(${JSON.stringify(e)});
4185
4234
  `
4186
4235
  })
4187
4236
  },
4188
- config: Wf,
4237
+ config: qf,
4238
+ description: "Animate elements with anime.js.",
4189
4239
  editor: {
4190
- panel: { element: [Uf] },
4191
- wrapper: Kf
4240
+ panel: { element: [Kf] },
4241
+ wrapper: Yf
4192
4242
  },
4193
4243
  icon: zd,
4244
+ id: "motion",
4245
+ inject: { css: Xf },
4194
4246
  lifecycle: {
4195
- mount: qf,
4196
- update: qf
4197
- }
4247
+ mount: Zf,
4248
+ update: Zf
4249
+ },
4250
+ llm: Rd,
4251
+ name: "Motion"
4198
4252
  });
4199
4253
  //#endregion
4200
- export { Jf as default };
4254
+ export { Qf as default };