@pixodesk/svg-animator-vue 1.0.30 โ 1.0.35
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 +17 -18
- package/dist/index.cjs +29 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -49
- package/dist/index.d.ts +28 -49
- package/dist/index.js +30 -65
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +931 -557
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# animator-vue
|
|
2
2
|
|
|
3
|
+
> ๐ Full user guide: [docs/library/vue.md](../../docs/library/vue.md) ยท [all docs](../../README.md#documentation)
|
|
4
|
+
|
|
3
5
|
[](https://github.com/pixodesk/pixodesk-svg-animator/actions/workflows/ci.yml)
|
|
4
6
|
[](https://opensource.org/licenses/MIT)
|
|
5
7
|
|
|
@@ -66,12 +68,12 @@ const animator = ref<VueAnimatorApi | null>(null);
|
|
|
66
68
|
|
|
67
69
|
### Controlled time
|
|
68
70
|
|
|
69
|
-
Render a single frame
|
|
71
|
+
Render a single frame โ by time in milliseconds, or by fraction of the whole timeline:
|
|
70
72
|
|
|
71
73
|
```vue
|
|
72
74
|
<template>
|
|
73
|
-
<PixodeskSvgAnimator :doc="animationDoc" :time="
|
|
74
|
-
<PixodeskSvgAnimator :doc="animationDoc" :
|
|
75
|
+
<PixodeskSvgAnimator :doc="animationDoc" :time="500" /> <!-- 500 ms in -->
|
|
76
|
+
<PixodeskSvgAnimator :doc="animationDoc" :progress="0.5" /> <!-- halfway through -->
|
|
75
77
|
</template>
|
|
76
78
|
```
|
|
77
79
|
|
|
@@ -83,21 +85,18 @@ Render a single frame at a specific point in time:
|
|
|
83
85
|
| `autoplay` | `boolean` | Use triggers from the document |
|
|
84
86
|
| `play` | `boolean` | Start playback, ignoring document triggers |
|
|
85
87
|
| `pause` | `boolean` | Pause current playback |
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
With none of `autoplay` / `play` / `pause` / `time` / `timeMs` set, the component renders the animation statically (initial state, no playback); use the template ref for imperative control.
|
|
99
|
-
|
|
100
|
-
Note: recreating the animator (unmount or a `doc` swap) emits `cancel`, `remove`, and `stop` for the torn-down instance. Scrubbing `time` / `timeMs` does **not** recreate the animator โ it seeks the existing one.
|
|
88
|
+
| `progress` | `number` | show the frame at this position in the whole timeline (duration ร iterations): `0` is the first frame, `0.5` the middle, `1` the last |
|
|
89
|
+
| `time` | `number` | show the frame at that time, in milliseconds from the start |
|
|
90
|
+
| `config` | `object \| string` | Per-instance override of the document's `animator` block, deep-merged over it โ same shape as the file (`{ timeline: { mode, frameRate, fillMode, direction, trigger: { outAction, โฆ } } }`); `null` at a slot deletes that key. A JSON string is accepted too |
|
|
91
|
+
| `resetDocDefaults` | `boolean` | Ignore the document's playback settings and start from the player's defaults, with `config` on top |
|
|
92
|
+
| `duration` | `number` | Shortcut for `config.timeline.duration` (ms) |
|
|
93
|
+
| `delay` | `number` | Shortcut for `config.timeline.delay` (ms) |
|
|
94
|
+
| `iterations` | `number \| 'infinite'` | Shortcut for `config.timeline.iterations` |
|
|
95
|
+
| `startOn` | `'load' \| 'mouseOver' \| 'click' \| 'scrollIntoView' \| 'programmatic'` | Shortcut for `config.timeline.trigger.startOn` |
|
|
96
|
+
|
|
97
|
+
With none of `autoplay` / `play` / `pause` / `progress` / `time` set, the component renders the animation statically (initial state, no playback); use the template ref for imperative control.
|
|
98
|
+
|
|
99
|
+
Note: passing a different `doc` (or unmounting) throws the old animator away and builds a new one; the old instance emits `cancel`, `remove`, and `stop` on its way out. Changing `progress` / `time` does **not** recreate the animator โ it just jumps the existing one to the new time.
|
|
101
100
|
|
|
102
101
|
## Events
|
|
103
102
|
|
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
29
29
|
// src/PixodeskSvgAnimator.ts
|
|
30
30
|
var import_svg_animator_web = require("@pixodesk/svg-animator-web");
|
|
31
31
|
var import_vue = require("vue");
|
|
32
|
+
var VUE_PROP = { ref: "ref" };
|
|
32
33
|
function createVueAdapter(elementRefs) {
|
|
33
34
|
const warnedSelectors = /* @__PURE__ */ new Set();
|
|
34
35
|
const adapter = {
|
|
@@ -51,63 +52,32 @@ function createVueAdapter(elementRefs) {
|
|
|
51
52
|
return adapter;
|
|
52
53
|
}
|
|
53
54
|
function applyDocOverrides(doc, props, compMode) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
trigger: { ...doc.animator?.trigger, startOn: "programmatic" }
|
|
62
|
-
}
|
|
63
|
-
};
|
|
55
|
+
const { config, resetDocDefaults, duration, delay, iterations, startOn } = props;
|
|
56
|
+
const patch = (0, import_svg_animator_web.foldAnimatorConfigShortcuts)(config, { duration, delay, iterations, startOn });
|
|
57
|
+
const fullPatch = compMode !== "autoplay" /* autoplay */ ? {
|
|
58
|
+
...patch ?? {},
|
|
59
|
+
timeline: {
|
|
60
|
+
...patch?.timeline ?? {},
|
|
61
|
+
trigger: { ...patch?.timeline?.trigger ?? {}, startOn: "programmatic" }
|
|
64
62
|
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
doc =
|
|
70
|
-
...doc,
|
|
71
|
-
animator: {
|
|
72
|
-
...animator,
|
|
73
|
-
mode: mode !== void 0 ? mode : animator.mode,
|
|
74
|
-
duration: duration !== void 0 ? duration : animator.duration,
|
|
75
|
-
delay: delay !== void 0 ? delay : animator.delay,
|
|
76
|
-
iterations: iterations !== void 0 ? iterations : animator.iterations,
|
|
77
|
-
fill: fill !== void 0 ? fill : animator.fill,
|
|
78
|
-
direction: direction !== void 0 ? direction : animator.direction,
|
|
79
|
-
frameRate: frameRate !== void 0 ? frameRate : animator.frameRate
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const { startOn, outAction, scrollIntoViewThreshold } = props;
|
|
84
|
-
if (startOn !== void 0 || outAction !== void 0 || scrollIntoViewThreshold !== void 0) {
|
|
85
|
-
const trigger = doc.animator?.trigger || {};
|
|
86
|
-
doc = {
|
|
87
|
-
...doc,
|
|
88
|
-
animator: {
|
|
89
|
-
...doc.animator,
|
|
90
|
-
trigger: {
|
|
91
|
-
...trigger,
|
|
92
|
-
startOn: startOn !== void 0 ? startOn : trigger.startOn,
|
|
93
|
-
outAction: outAction !== void 0 ? outAction : trigger.outAction,
|
|
94
|
-
scrollIntoViewThreshold: scrollIntoViewThreshold !== void 0 ? scrollIntoViewThreshold : trigger.scrollIntoViewThreshold
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
63
|
+
} : patch;
|
|
64
|
+
if (fullPatch !== void 0 || resetDocDefaults) {
|
|
65
|
+
const applied = (0, import_svg_animator_web.applyAnimatorConfig)(doc, fullPatch ?? {}, { resetDefaults: !!resetDocDefaults });
|
|
66
|
+
for (const w of applied.warnings) console.warn("[PixodeskSvgAnimator] config override:", w);
|
|
67
|
+
doc = applied.doc;
|
|
98
68
|
}
|
|
99
69
|
return doc;
|
|
100
70
|
}
|
|
101
71
|
function calcSeekMs(doc, props) {
|
|
102
72
|
let seekMs;
|
|
103
|
-
const animator = doc
|
|
104
|
-
if (props.
|
|
73
|
+
const animator = (0, import_svg_animator_web.getAnimatorConfig)(doc) || {};
|
|
74
|
+
if (props.progress !== void 0) {
|
|
105
75
|
const iterationsValue = props.iterations ?? animator.iterations;
|
|
106
76
|
const iterationsCount = typeof iterationsValue === "number" && iterationsValue >= 1 ? iterationsValue : 1;
|
|
107
77
|
const singleDuration = props.duration ?? animator.duration ?? 1e3;
|
|
108
|
-
seekMs = props.
|
|
78
|
+
seekMs = props.progress * singleDuration * iterationsCount;
|
|
109
79
|
}
|
|
110
|
-
if (props.
|
|
80
|
+
if (props.time !== void 0) seekMs = props.time;
|
|
111
81
|
return seekMs;
|
|
112
82
|
}
|
|
113
83
|
var PixodeskSvgAnimator = (0, import_vue.defineComponent)({
|
|
@@ -115,26 +85,21 @@ var PixodeskSvgAnimator = (0, import_vue.defineComponent)({
|
|
|
115
85
|
props: {
|
|
116
86
|
// -- Source
|
|
117
87
|
doc: { type: Object, required: true },
|
|
118
|
-
// --
|
|
119
|
-
|
|
120
|
-
|
|
88
|
+
// -- Playback override: one object spelled exactly like `animator` in the file,
|
|
89
|
+
// plus the four shortcuts people reach for most.
|
|
90
|
+
config: { type: [Object, String] },
|
|
91
|
+
resetDocDefaults: { type: Boolean, default: void 0 },
|
|
92
|
+
duration: { type: Number },
|
|
121
93
|
delay: { type: Number },
|
|
122
|
-
fill: { type: String },
|
|
123
94
|
iterations: { type: [Number, String] },
|
|
124
|
-
duration: { type: Number },
|
|
125
|
-
direction: { type: String },
|
|
126
|
-
frameRate: { type: Number },
|
|
127
|
-
// -- Trigger overrides
|
|
128
95
|
startOn: { type: String },
|
|
129
|
-
outAction: { type: String },
|
|
130
|
-
scrollIntoViewThreshold: { type: Number },
|
|
131
96
|
// -- Declarative control
|
|
132
97
|
autoplay: { type: Boolean, default: void 0 },
|
|
133
98
|
play: { type: Boolean, default: void 0 },
|
|
134
99
|
pause: { type: Boolean, default: void 0 },
|
|
135
100
|
// -- Controlled time
|
|
136
|
-
|
|
137
|
-
|
|
101
|
+
progress: { type: Number },
|
|
102
|
+
time: { type: Number }
|
|
138
103
|
},
|
|
139
104
|
emits: ["play", "stop", "pause", "cancel", "finish", "remove"],
|
|
140
105
|
setup(props, { expose, emit }) {
|
|
@@ -142,7 +107,7 @@ var PixodeskSvgAnimator = (0, import_vue.defineComponent)({
|
|
|
142
107
|
const apiRef = (0, import_vue.shallowRef)(null);
|
|
143
108
|
const compMode = (0, import_vue.computed)(() => {
|
|
144
109
|
if (props.autoplay) return "autoplay" /* autoplay */;
|
|
145
|
-
if (props.
|
|
110
|
+
if (props.progress !== void 0 || props.time !== void 0) return "fixedTime" /* fixedTime */;
|
|
146
111
|
if (props.play !== void 0 || props.pause !== void 0) return "play" /* play */;
|
|
147
112
|
return "static" /* static */;
|
|
148
113
|
});
|
|
@@ -154,9 +119,9 @@ var PixodeskSvgAnimator = (0, import_vue.defineComponent)({
|
|
|
154
119
|
if (!node) return null;
|
|
155
120
|
const { type, animate, meta, children, ...attrs } = node;
|
|
156
121
|
const normProps = (0, import_svg_animator_web.getNormalizedProps)(attrs);
|
|
157
|
-
if (node
|
|
158
|
-
const nodeId = node
|
|
159
|
-
normProps[
|
|
122
|
+
if (node.id) {
|
|
123
|
+
const nodeId = node.id;
|
|
124
|
+
normProps[VUE_PROP.ref] = (el) => {
|
|
160
125
|
if (el) {
|
|
161
126
|
elementRefs.set(nodeId, el);
|
|
162
127
|
} else {
|
|
@@ -223,7 +188,7 @@ var PixodeskSvgAnimator = (0, import_vue.defineComponent)({
|
|
|
223
188
|
(0, import_vue.onMounted)(() => createApi());
|
|
224
189
|
(0, import_vue.watch)(resolvedDoc, () => createApi(), { flush: "post" });
|
|
225
190
|
(0, import_vue.watch)([compMode, () => props.play, () => props.pause], () => syncPlayState());
|
|
226
|
-
(0, import_vue.watch)([compMode, () => props.
|
|
191
|
+
(0, import_vue.watch)([compMode, () => props.progress, () => props.time], () => applySeek());
|
|
227
192
|
(0, import_vue.onUnmounted)(() => {
|
|
228
193
|
destroyApi();
|
|
229
194
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/PixodeskSvgAnimator.ts","../src/PixodeskSvgCssAnimator.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport PixodeskSvgAnimator from './PixodeskSvgAnimator';\nexport { PixodeskSvgAnimator };\nexport type { VueAnimatorApi } from './PixodeskSvgAnimator';\n\nimport PixodeskSvgCssAnimator from './PixodeskSvgCssAnimator';\nexport { PixodeskSvgCssAnimator };","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxAnimatedSvgDocument, PxAnimatorAPI, PxNode, PxPlatformAdapter, PxTrigger } from '@pixodesk/svg-animator-web';\nimport { camelCaseToKebabWordIfNeeded, createAnimator, FillMode, generateNewIds, getNormalizedProps, STYLE_ATTR_NAMES } from '@pixodesk/svg-animator-web';\nimport {\n computed, defineComponent, h, onMounted, onUnmounted, ref, shallowRef, type PropType, type VNode,\n watch,\n} from 'vue';\n\n\n// -- Public types -----------------------------------------------------------\n\nexport interface VueAnimatorApi {\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n}\n\n\n// -- Internal types ---------------------------------------------------------\n\nenum CompMode {\n static = 'static',\n autoplay = 'autoplay',\n play = 'play',\n fixedTime = 'fixedTime'\n}\n\n\n// -- Vue โ Animator bridge --------------------------------------------------\n\n/**\n * Creates a platform adapter that routes animator attribute updates\n * to the corresponding Vue-managed DOM element refs.\n */\nfunction createVueAdapter(elementRefs: Map<string, Element>) {\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => true,\n setAttribute: (id, attrName, value) => {\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const element = elementRefs.get(id);\n\n if (!element && !warnedSelectors.has(id)) {\n warnedSelectors.add(id);\n console.warn('setAttribute: No elements found for id \"' + id + '\"');\n }\n\n if (element) {\n element.setAttribute(attrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}\n\n// FIXME: add model validation (e.g. isElementFileJson check)\n\n\n// -- Helper: apply doc overrides --------------------------------------------\n\ninterface DocOverrideProps {\n mode?: 'waapi' | 'frames' | 'auto';\n delay?: number;\n fill?: FillMode;\n iterations?: number | 'infinite';\n duration?: number;\n direction?: PlaybackDirection;\n frameRate?: number;\n startOn?: 'load' | 'mouseOver' | 'click' | 'scrollIntoView' | 'programmatic';\n outAction?: 'continue' | 'pause' | 'reset' | 'reverse';\n scrollIntoViewThreshold?: number;\n time?: number;\n timeMs?: number;\n}\n\nfunction applyDocOverrides(\n doc: PxAnimatedSvgDocument,\n props: DocOverrideProps,\n compMode: CompMode,\n): PxAnimatedSvgDocument {\n\n // In non-autoplay modes, override the document trigger to 'programmatic'\n // so the component can manage playback itself.\n if (compMode !== CompMode.autoplay) {\n const docStartOn = doc.animator?.trigger?.startOn;\n if (docStartOn && docStartOn !== 'programmatic') { // FIXME: use enum\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: { ...doc.animator?.trigger, startOn: 'programmatic' }\n }\n };\n }\n }\n\n // Apply timing overrides from props onto the document config.\n const { mode, duration, delay, iterations, fill, direction, frameRate } = props;\n if (\n mode !== undefined || duration !== undefined || delay !== undefined ||\n iterations !== undefined || fill !== undefined || direction !== undefined ||\n frameRate !== undefined\n ) {\n const animator = doc.animator || {};\n doc = {\n ...doc,\n animator: {\n ...animator,\n mode: mode !== undefined ? mode : animator.mode,\n duration: duration !== undefined ? duration : animator.duration,\n delay: delay !== undefined ? delay : animator.delay,\n iterations: iterations !== undefined ? iterations : animator.iterations,\n fill: fill !== undefined ? fill : animator.fill,\n direction: direction !== undefined ? direction : animator.direction,\n frameRate: frameRate !== undefined ? frameRate : animator.frameRate,\n }\n };\n }\n\n // Apply trigger overrides from props.\n const { startOn, outAction, scrollIntoViewThreshold } = props;\n if (startOn !== undefined || outAction !== undefined || scrollIntoViewThreshold !== undefined) {\n const trigger: PxTrigger = doc.animator?.trigger || {};\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: {\n ...trigger,\n startOn: startOn !== undefined ? startOn : trigger.startOn,\n outAction: outAction !== undefined ? outAction : trigger.outAction,\n scrollIntoViewThreshold: scrollIntoViewThreshold !== undefined ? scrollIntoViewThreshold : trigger.scrollIntoViewThreshold,\n }\n }\n };\n }\n\n return doc;\n}\n\n/**\n * Controlled-time mode: absolute seek target in ms. `time` is a fraction\n * (0โ1) of the WHOLE timeline (duration ร iterations); `timeMs` is absolute.\n * Applied through the animator API (setCurrentTime) so scrubbing does NOT\n * recreate the animator.\n */\nfunction calcSeekMs(doc: PxAnimatedSvgDocument, props: DocOverrideProps): number | undefined {\n let seekMs: number | undefined;\n const animator = doc.animator || {};\n if (props.time !== undefined) {\n const iterationsValue = props.iterations ?? animator.iterations;\n const iterationsCount = typeof iterationsValue === 'number' && iterationsValue >= 1 ? iterationsValue : 1;\n const singleDuration = props.duration ?? animator.duration ?? 1000; // engine default duration\n seekMs = props.time * singleDuration * iterationsCount;\n }\n if (props.timeMs !== undefined) seekMs = props.timeMs;\n return seekMs;\n}\n\n\n// -- Main public component --------------------------------------------------\n\n/**\n * Vue component for rendering and controlling Pixodesk SVG animations.\n *\n * Supports four mutually-exclusive control modes:\n *\n * 1. **Autoplay** โ uses triggers from the animation document.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" autoplay />\n * ```\n *\n * 2. **Declarative play/pause** โ controlled via boolean props.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" play :pause=\"false\" />\n * ```\n *\n * 3. **Imperative** โ exposes a ref-based API for full programmatic control.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" ref=\"animator\" />\n * <button @click=\"$refs.animator.play()\">Play</button>\n * ```\n *\n * 4. **Controlled time** โ renders a single frame at a given time.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" :time=\"0.5\" />\n * <PixodeskSvgAnimator :doc=\"animation\" :timeMs=\"500\" />\n * ```\n */\nconst PixodeskSvgAnimator = defineComponent({\n name: 'PixodeskSvgAnimator',\n\n props: {\n // -- Source\n doc: { type: Object as PropType<PxAnimatedSvgDocument>, required: true },\n\n // -- Rendering mode\n mode: { type: String as PropType<'waapi' | 'frames' | 'auto'> },\n\n // -- Timing overrides\n delay: { type: Number },\n fill: { type: String as PropType<FillMode> },\n iterations: { type: [Number, String] as PropType<number | 'infinite'> },\n duration: { type: Number },\n direction: { type: String as PropType<PlaybackDirection> },\n frameRate: { type: Number },\n\n // -- Trigger overrides\n startOn: { type: String as PropType<'load' | 'mouseOver' | 'click' | 'scrollIntoView' | 'programmatic'> },\n outAction: { type: String as PropType<'continue' | 'pause' | 'reset' | 'reverse'> },\n scrollIntoViewThreshold: { type: Number },\n\n // -- Declarative control\n autoplay: { type: Boolean, default: undefined },\n play: { type: Boolean, default: undefined },\n pause: { type: Boolean, default: undefined },\n\n // -- Controlled time\n time: { type: Number },\n timeMs: { type: Number },\n },\n\n emits: ['play', 'stop', 'pause', 'cancel', 'finish', 'remove'],\n\n setup(props, { expose, emit }) {\n const elementRefs = new Map<string, Element>();\n const apiRef = shallowRef<PxAnimatorAPI | null>(null);\n\n // -- Determine control mode ---------------------------------------------\n\n const compMode = computed<CompMode>(() => {\n if (props.autoplay) return CompMode.autoplay;\n if (props.time !== undefined || props.timeMs !== undefined) return CompMode.fixedTime;\n if (props.play !== undefined || props.pause !== undefined) return CompMode.play;\n return CompMode.static;\n });\n\n // -- Prepare the document with overrides --------------------------------\n\n const resolvedDoc = computed(() => {\n let doc = generateNewIds(props.doc);\n return applyDocOverrides(doc, props, compMode.value);\n });\n\n // -- Render the SVG node tree -------------------------------------------\n\n function renderNode(node: PxNode | undefined): VNode | null {\n if (!node) return null;\n\n const { type, animate, meta, children, ...attrs } = node;\n const normProps = getNormalizedProps(attrs);\n\n // Capture a ref to each element with an id.\n if (node['id']) {\n const nodeId = node['id'];\n normProps['ref'] = (el: Element | null) => {\n if (el) {\n elementRefs.set(nodeId, el);\n } else {\n elementRefs.delete(nodeId);\n }\n };\n }\n\n const childVNodes = children?.map(child => renderNode(child)).filter(Boolean) as VNode[] | undefined;\n return h(type, normProps, childVNodes);\n }\n\n // -- Animator lifecycle -------------------------------------------------\n\n function createApi() {\n destroyApi();\n const doc = resolvedDoc.value;\n if (!doc) return;\n\n // Route animator lifecycle events to Vue component events.\n // `stop` fires alongside any event that halts playback.\n const callbacks = {\n onPlay: () => emit('play'),\n onPause: () => { emit('pause'); emit('stop'); },\n onCancel: () => { emit('cancel'); emit('stop'); },\n onFinish: () => { emit('finish'); emit('stop'); },\n onRemove: () => { emit('remove'); emit('stop'); },\n };\n\n apiRef.value = createAnimator({ data: doc, adapter: createVueAdapter(elementRefs), callbacks });\n\n // (Re)apply the declarative control state to the fresh animator โ\n // covers both the initial mount (e.g. `:play=\"true\"` from the\n // start) and doc swaps.\n syncPlayState();\n applySeek();\n }\n\n function destroyApi() {\n apiRef.value?.destroy();\n apiRef.value = null;\n }\n\n /** Declarative play/pause โ animator calls. */\n function syncPlayState() {\n if (compMode.value !== CompMode.play) return;\n if (props.play && !props.pause) {\n apiRef.value?.play();\n } else if (props.pause) {\n apiRef.value?.pause();\n } else if (props.play === false) {\n // explicit play=false โ jump to the end state\n apiRef.value?.finish();\n } else {\n // pause-only usage: pause switched off โ resume\n apiRef.value?.play();\n }\n }\n\n /** Controlled-time mode: seek through the animator API (no recreate). */\n function applySeek() {\n if (compMode.value !== CompMode.fixedTime) return;\n const doc = resolvedDoc.value;\n if (!doc) return;\n const seekMs = calcSeekMs(doc, props);\n if (seekMs !== undefined) {\n apiRef.value?.setCurrentTime(seekMs);\n apiRef.value?.pause();\n }\n }\n\n // Create the animator once DOM refs are available.\n onMounted(() => createApi());\n\n // Recreate the animator when the resolved doc changes.\n // `flush: 'post'` โ the animator must be created AFTER the DOM is\n // patched, otherwise the new root element isn't in the document yet\n // and trigger setup fails (autoplay would never resume after a doc swap).\n watch(resolvedDoc, () => createApi(), { flush: 'post' });\n\n // Sync declarative play/pause props with the animator.\n watch([compMode, () => props.play, () => props.pause], () => syncPlayState());\n\n // Scrubbing time/timeMs only seeks โ the animator is NOT recreated.\n watch([compMode, () => props.time, () => props.timeMs], () => applySeek());\n\n onUnmounted(() => {\n destroyApi();\n });\n\n // -- Expose imperative API ----------------------------------------------\n\n const publicApi: VueAnimatorApi = {\n isPlaying: () => apiRef.value?.isPlaying() || false,\n play: () => apiRef.value?.play(),\n pause: () => apiRef.value?.pause(),\n cancel: () => apiRef.value?.cancel(),\n finish: () => apiRef.value?.finish(),\n setPlaybackRate: (rate: number) => apiRef.value?.setPlaybackRate(rate),\n getCurrentTime: () => apiRef.value?.getCurrentTime() ?? null,\n setCurrentTime: (time: number) => apiRef.value?.setCurrentTime(time),\n };\n\n expose(publicApi);\n\n // -- Render -------------------------------------------------------------\n\n return () => {\n const doc = resolvedDoc.value;\n return doc ? renderNode(doc) : null;\n };\n },\n});\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { OutAction, StartOn } from \"@pixodesk/svg-animator-web\";\nimport { computed, defineComponent, h, onMounted, onUnmounted, ref, useAttrs, type PropType } from 'vue';\n\n\ntype AnimState = 'idle' | 'paused' | 'playing';\n\n\n/**\n * Controls playback of a SVG+CSS animated file by toggling class names on a wrapper div.\n *\n * Intended for use with SVG files exported from the Pixodesk editor using the\n * **CSS Keyframes** flavor (no `<script>` tag). Import the SVG as a Vue component\n * via `vite-svg-loader` and pass it as the default slot:\n *\n * ```vue\n * <script setup>\n * import AnimationSvg from './animation.svg'; // vite-svg-loader\n * </script>\n *\n * <template>\n * <PixodeskSvgCssAnimator startOn=\"mouseOver\" outAction=\"pause\">\n * <AnimationSvg />\n * </PixodeskSvgCssAnimator>\n * </template>\n * ```\n *\n * The wrapper div carries one of three animation states via CSS class names:\n * - *(no class)* โ idle, animation not started\n * - `px-anim-enabled` โ started but paused\n * - `px-anim-enabled px-anim-playing` โ actively playing\n *\n * @prop startOn - What triggers the animation to start:\n * - `'load'` โ plays immediately on mount (default)\n * - `'mouseOver'` โ plays on hover\n * - `'click'` โ plays on click, toggles on second click\n * - `'scrollIntoView'` โ plays when the element enters the viewport\n * @prop outAction - What happens when the trigger ends (hover/scroll out, second click):\n * - `'continue'` โ keeps playing (default)\n * - `'pause'` โ pauses at the current frame\n * - `'reset'` โ resets to the beginning\n */\nconst PixodeskSvgCssAnimator = defineComponent({\n name: 'PixodeskSvgCssAnimator',\n\n inheritAttrs: false,\n\n props: {\n startOn: { type: String as PropType<StartOn>, default: 'load' },\n outAction: { type: String as PropType<OutAction>, default: 'continue' },\n },\n\n setup(props, { slots }) {\n const attrs = useAttrs();\n const state = ref<AnimState>(props.startOn === 'load' ? 'playing' : 'idle');\n const divRef = ref<HTMLDivElement | null>(null);\n\n const goOut = () => {\n state.value =\n props.outAction === 'reset' ? 'idle' :\n props.outAction === 'pause' ? 'paused' : 'playing';\n };\n\n let observerCleanup: (() => void) | undefined;\n\n onMounted(() => {\n if (props.startOn !== 'scrollIntoView') return;\n const el = divRef.value;\n if (!el) return;\n const outState: AnimState =\n props.outAction === 'reset' ? 'idle' :\n props.outAction === 'pause' ? 'paused' : 'playing';\n const observer = new IntersectionObserver(\n ([entry]) => { state.value = entry.isIntersecting ? 'playing' : outState; },\n { threshold: 0.1 }\n );\n observer.observe(el);\n observerCleanup = () => observer.disconnect();\n });\n\n onUnmounted(() => observerCleanup?.());\n\n const animClass = computed(() =>\n state.value === 'playing' ? 'px-anim-enabled px-anim-playing' :\n state.value === 'paused' ? 'px-anim-enabled' : ''\n );\n\n const handlers = computed(() =>\n props.startOn === 'mouseOver' ? {\n onMouseenter: () => { state.value = 'playing'; },\n onMouseleave: goOut,\n } :\n props.startOn === 'click' ? {\n onClick: () => state.value === 'playing' ? goOut() : (state.value = 'playing'),\n } : {}\n );\n\n return () => h('div', {\n ref: divRef,\n ...attrs,\n class: [attrs.class, animClass.value],\n ...handlers.value,\n }, slots.default?.());\n },\n});\n\nexport default PixodeskSvgCssAnimator;\n"],"mappings":"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","names":["import_vue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/PixodeskSvgAnimator.ts","../src/PixodeskSvgCssAnimator.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport PixodeskSvgAnimator from './PixodeskSvgAnimator';\nexport { PixodeskSvgAnimator };\nexport type { VueAnimatorApi } from './PixodeskSvgAnimator';\n\nimport PixodeskSvgCssAnimator from './PixodeskSvgCssAnimator';\nexport { PixodeskSvgCssAnimator };","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxAnimatedSvgDocument, PxAnimatorAPI, PxAnimatorConfigPatch, PxNode, PxPlatformAdapter, PxTimelineEngineExtra, PxTrigger } from '@pixodesk/svg-animator-web';\nimport { camelCaseToKebabWordIfNeeded, createAnimator, FillMode, generateNewIds, getNormalizedProps, STYLE_ATTR_NAMES, applyAnimatorConfig, foldAnimatorConfigShortcuts, getAnimatorConfig } from '@pixodesk/svg-animator-web';\nimport {\n computed, defineComponent, h, onMounted, onUnmounted, ref, shallowRef, type PropType, type VNode,\n watch,\n} from 'vue';\n\n\n// -- Public types -----------------------------------------------------------\n\n/** Vue's own prop names on the vnode โ not wire keys. See the React twin. */\nconst VUE_PROP = { ref: 'ref' } as const;\n\nexport interface VueAnimatorApi {\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n}\n\n\n// -- Internal types ---------------------------------------------------------\n\nenum CompMode {\n static = 'static',\n autoplay = 'autoplay',\n play = 'play',\n fixedTime = 'fixedTime'\n}\n\n\n// -- Vue โ Animator bridge --------------------------------------------------\n\n/**\n * Creates a platform adapter that routes animator attribute updates\n * to the corresponding Vue-managed DOM element refs.\n */\nfunction createVueAdapter(elementRefs: Map<string, Element>) {\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => true,\n setAttribute: (id, attrName, value) => {\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const element = elementRefs.get(id);\n\n if (!element && !warnedSelectors.has(id)) {\n warnedSelectors.add(id);\n console.warn('setAttribute: No elements found for id \"' + id + '\"');\n }\n\n if (element) {\n element.setAttribute(attrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}\n\n// FIXME: add model validation (e.g. isElementFileJson check)\n\n\n// -- Helper: apply doc overrides --------------------------------------------\n\ninterface DocOverrideProps {\n /** Per-instance override of the document's `animator` config โ the same shape as\n * `animator` in SCHEMA.md, deep-merged; `null` at a slot deletes it. Also accepts a\n * JSON string. Replaces the former flat mode/fill/direction/frameRate/outAction props. */\n config?: PxAnimatorConfigPatch | string;\n /** Start from the player's defaults instead of the document's playback settings. */\n resetDocDefaults?: boolean;\n duration?: number;\n delay?: number;\n iterations?: number | 'infinite';\n startOn?: 'load' | 'mouseOver' | 'click' | 'scrollIntoView' | 'programmatic';\n progress?: number;\n time?: number;\n}\n\nfunction applyDocOverrides(\n doc: PxAnimatedSvgDocument,\n props: DocOverrideProps,\n compMode: CompMode,\n): PxAnimatedSvgDocument {\n\n // ONE patch, applied ONCE: the props, plus the component's own need to take the trigger\n // over in the non-autoplay control modes.\n //\n // This replaces three hand-rolled spread blocks that wrote the FLAT runtime keys. On a\n // wire-format document โ which is what every writer emits โ `flattenAnimatorTimeline`\n // overwrote them from `timeline` immediately afterwards, so the overrides were silently\n // discarded. See PLAYBACK-OVERRIDE-PLAN.md ยง1.1.\n const { config, resetDocDefaults, duration, delay, iterations, startOn } = props;\n const patch = foldAnimatorConfigShortcuts(config, { duration, delay, iterations, startOn });\n const fullPatch: any = compMode !== CompMode.autoplay\n ? {\n ...(patch ?? {}),\n timeline: {\n ...((patch as any)?.timeline ?? {}),\n trigger: { ...((patch as any)?.timeline?.trigger ?? {}), startOn: 'programmatic' },\n },\n }\n : patch;\n\n if (fullPatch !== undefined || resetDocDefaults) {\n const applied = applyAnimatorConfig(doc, fullPatch ?? {}, { resetDefaults: !!resetDocDefaults });\n for (const w of applied.warnings) console.warn('[PixodeskSvgAnimator] config override:', w);\n doc = applied.doc;\n }\n\n return doc;\n}\n\n/**\n * Controlled-time mode: absolute seek target in ms. `progress` is a fraction\n * (0โ1) of the WHOLE timeline (duration ร iterations); `time` is absolute.\n * Applied through the animator API (setCurrentTime) so scrubbing does NOT\n * recreate the animator.\n */\nfunction calcSeekMs(doc: PxAnimatedSvgDocument, props: DocOverrideProps): number | undefined {\n let seekMs: number | undefined;\n // The FLAT runtime view, so this works on a wire-format document too โ reading\n // `doc.animator.duration` directly finds nothing there.\n const animator = getAnimatorConfig(doc) || {};\n if (props.progress !== undefined) {\n const iterationsValue = props.iterations ?? animator.iterations;\n const iterationsCount = typeof iterationsValue === 'number' && iterationsValue >= 1 ? iterationsValue : 1;\n const singleDuration = props.duration ?? animator.duration ?? 1000; // engine default duration\n seekMs = props.progress * singleDuration * iterationsCount;\n }\n if (props.time !== undefined) seekMs = props.time;\n return seekMs;\n}\n\n\n// -- Main public component --------------------------------------------------\n\n/**\n * Vue component for rendering and controlling Pixodesk SVG animations.\n *\n * Supports four mutually-exclusive control modes:\n *\n * 1. **Autoplay** โ uses triggers from the animation document.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" autoplay />\n * ```\n *\n * 2. **Declarative play/pause** โ controlled via boolean props.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" play :pause=\"false\" />\n * ```\n *\n * 3. **Imperative** โ exposes a ref-based API for full programmatic control.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" ref=\"animator\" />\n * <button @click=\"$refs.animator.play()\">Play</button>\n * ```\n *\n * 4. **Controlled time** โ renders a single frame at a given time.\n * ```vue\n * <PixodeskSvgAnimator :doc=\"animation\" :progress=\"0.5\" />\n * <PixodeskSvgAnimator :doc=\"animation\" :time=\"500\" />\n * ```\n */\nconst PixodeskSvgAnimator = defineComponent({\n name: 'PixodeskSvgAnimator',\n\n props: {\n // -- Source\n doc: { type: Object as PropType<PxAnimatedSvgDocument>, required: true },\n\n // -- Playback override: one object spelled exactly like `animator` in the file,\n // plus the four shortcuts people reach for most.\n config: { type: [Object, String] as PropType<PxAnimatorConfigPatch | string> },\n resetDocDefaults: { type: Boolean, default: undefined },\n duration: { type: Number },\n delay: { type: Number },\n iterations: { type: [Number, String] as PropType<number | 'infinite'> },\n startOn: { type: String as PropType<'load' | 'mouseOver' | 'click' | 'scrollIntoView' | 'programmatic'> },\n\n // -- Declarative control\n autoplay: { type: Boolean, default: undefined },\n play: { type: Boolean, default: undefined },\n pause: { type: Boolean, default: undefined },\n\n // -- Controlled time\n progress: { type: Number },\n time: { type: Number },\n },\n\n emits: ['play', 'stop', 'pause', 'cancel', 'finish', 'remove'],\n\n setup(props, { expose, emit }) {\n const elementRefs = new Map<string, Element>();\n const apiRef = shallowRef<PxAnimatorAPI | null>(null);\n\n // -- Determine control mode ---------------------------------------------\n\n const compMode = computed<CompMode>(() => {\n if (props.autoplay) return CompMode.autoplay;\n if (props.progress !== undefined || props.time !== undefined) return CompMode.fixedTime;\n if (props.play !== undefined || props.pause !== undefined) return CompMode.play;\n return CompMode.static;\n });\n\n // -- Prepare the document with overrides --------------------------------\n\n const resolvedDoc = computed(() => {\n let doc = generateNewIds(props.doc);\n return applyDocOverrides(doc, props, compMode.value);\n });\n\n // -- Render the SVG node tree -------------------------------------------\n\n function renderNode(node: PxNode | undefined): VNode | null {\n if (!node) return null;\n\n const { type, animate, meta, children, ...attrs } = node;\n const normProps = getNormalizedProps(attrs);\n\n // Capture a ref to each element with an id.\n if (node.id) {\n const nodeId = node.id;\n normProps[VUE_PROP.ref] = (el: Element | null) => {\n if (el) {\n elementRefs.set(nodeId, el);\n } else {\n elementRefs.delete(nodeId);\n }\n };\n }\n\n const childVNodes = children?.map(child => renderNode(child)).filter(Boolean) as VNode[] | undefined;\n return h(type, normProps, childVNodes);\n }\n\n // -- Animator lifecycle -------------------------------------------------\n\n function createApi() {\n destroyApi();\n const doc = resolvedDoc.value;\n if (!doc) return;\n\n // Route animator lifecycle events to Vue component events.\n // `stop` fires alongside any event that halts playback.\n const callbacks = {\n onPlay: () => emit('play'),\n onPause: () => { emit('pause'); emit('stop'); },\n onCancel: () => { emit('cancel'); emit('stop'); },\n onFinish: () => { emit('finish'); emit('stop'); },\n onRemove: () => { emit('remove'); emit('stop'); },\n };\n\n apiRef.value = createAnimator({ data: doc, adapter: createVueAdapter(elementRefs), callbacks });\n\n // (Re)apply the declarative control state to the fresh animator โ\n // covers both the initial mount (e.g. `:play=\"true\"` from the\n // start) and doc swaps.\n syncPlayState();\n applySeek();\n }\n\n function destroyApi() {\n apiRef.value?.destroy();\n apiRef.value = null;\n }\n\n /** Declarative play/pause โ animator calls. */\n function syncPlayState() {\n if (compMode.value !== CompMode.play) return;\n if (props.play && !props.pause) {\n apiRef.value?.play();\n } else if (props.pause) {\n apiRef.value?.pause();\n } else if (props.play === false) {\n // explicit play=false โ jump to the end state\n apiRef.value?.finish();\n } else {\n // pause-only usage: pause switched off โ resume\n apiRef.value?.play();\n }\n }\n\n /** Controlled-time mode: seek through the animator API (no recreate). */\n function applySeek() {\n if (compMode.value !== CompMode.fixedTime) return;\n const doc = resolvedDoc.value;\n if (!doc) return;\n const seekMs = calcSeekMs(doc, props);\n if (seekMs !== undefined) {\n apiRef.value?.setCurrentTime(seekMs);\n apiRef.value?.pause();\n }\n }\n\n // Create the animator once DOM refs are available.\n onMounted(() => createApi());\n\n // Recreate the animator when the resolved doc changes.\n // `flush: 'post'` โ the animator must be created AFTER the DOM is\n // patched, otherwise the new root element isn't in the document yet\n // and trigger setup fails (autoplay would never resume after a doc swap).\n watch(resolvedDoc, () => createApi(), { flush: 'post' });\n\n // Sync declarative play/pause props with the animator.\n watch([compMode, () => props.play, () => props.pause], () => syncPlayState());\n\n // Scrubbing progress/time only seeks โ the animator is NOT recreated.\n watch([compMode, () => props.progress, () => props.time], () => applySeek());\n\n onUnmounted(() => {\n destroyApi();\n });\n\n // -- Expose imperative API ----------------------------------------------\n\n const publicApi: VueAnimatorApi = {\n isPlaying: () => apiRef.value?.isPlaying() || false,\n play: () => apiRef.value?.play(),\n pause: () => apiRef.value?.pause(),\n cancel: () => apiRef.value?.cancel(),\n finish: () => apiRef.value?.finish(),\n setPlaybackRate: (rate: number) => apiRef.value?.setPlaybackRate(rate),\n getCurrentTime: () => apiRef.value?.getCurrentTime() ?? null,\n setCurrentTime: (time: number) => apiRef.value?.setCurrentTime(time),\n };\n\n expose(publicApi);\n\n // -- Render -------------------------------------------------------------\n\n return () => {\n const doc = resolvedDoc.value;\n return doc ? renderNode(doc) : null;\n };\n },\n});\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { OutAction, StartOn } from \"@pixodesk/svg-animator-web\";\nimport { computed, defineComponent, h, onMounted, onUnmounted, ref, useAttrs, type PropType } from 'vue';\n\n\ntype AnimState = 'idle' | 'paused' | 'playing';\n\n\n/**\n * Controls playback of a SVG+CSS animated file by toggling class names on a wrapper div.\n *\n * Intended for use with SVG files exported from the Pixodesk editor using the\n * **CSS Keyframes** flavor (no `<script>` tag). Import the SVG as a Vue component\n * via `vite-svg-loader` and pass it as the default slot:\n *\n * ```vue\n * <script setup>\n * import AnimationSvg from './animation.svg'; // vite-svg-loader\n * </script>\n *\n * <template>\n * <PixodeskSvgCssAnimator startOn=\"mouseOver\" outAction=\"pause\">\n * <AnimationSvg />\n * </PixodeskSvgCssAnimator>\n * </template>\n * ```\n *\n * The wrapper div carries one of three animation states via CSS class names:\n * - *(no class)* โ idle, animation not started\n * - `px-anim-enabled` โ started but paused\n * - `px-anim-enabled px-anim-playing` โ actively playing\n *\n * @prop startOn - What triggers the animation to start:\n * - `'load'` โ plays immediately on mount (default)\n * - `'mouseOver'` โ plays on hover\n * - `'click'` โ plays on click, toggles on second click\n * - `'scrollIntoView'` โ plays when the element enters the viewport\n * @prop outAction - What happens when the trigger ends (hover/scroll out, second click):\n * - `'continue'` โ keeps playing (default)\n * - `'pause'` โ pauses at the current frame\n * - `'reset'` โ resets to the beginning\n */\nconst PixodeskSvgCssAnimator = defineComponent({\n name: 'PixodeskSvgCssAnimator',\n\n inheritAttrs: false,\n\n props: {\n startOn: { type: String as PropType<StartOn>, default: 'load' },\n outAction: { type: String as PropType<OutAction>, default: 'continue' },\n },\n\n setup(props, { slots }) {\n const attrs = useAttrs();\n const state = ref<AnimState>(props.startOn === 'load' ? 'playing' : 'idle');\n const divRef = ref<HTMLDivElement | null>(null);\n\n const goOut = () => {\n state.value =\n props.outAction === 'reset' ? 'idle' :\n props.outAction === 'pause' ? 'paused' : 'playing';\n };\n\n let observerCleanup: (() => void) | undefined;\n\n onMounted(() => {\n if (props.startOn !== 'scrollIntoView') return;\n const el = divRef.value;\n if (!el) return;\n const outState: AnimState =\n props.outAction === 'reset' ? 'idle' :\n props.outAction === 'pause' ? 'paused' : 'playing';\n const observer = new IntersectionObserver(\n ([entry]) => { state.value = entry.isIntersecting ? 'playing' : outState; },\n { threshold: 0.1 }\n );\n observer.observe(el);\n observerCleanup = () => observer.disconnect();\n });\n\n onUnmounted(() => observerCleanup?.());\n\n const animClass = computed(() =>\n state.value === 'playing' ? 'px-anim-enabled px-anim-playing' :\n state.value === 'paused' ? 'px-anim-enabled' : ''\n );\n\n const handlers = computed(() =>\n props.startOn === 'mouseOver' ? {\n onMouseenter: () => { state.value = 'playing'; },\n onMouseleave: goOut,\n } :\n props.startOn === 'click' ? {\n onClick: () => state.value === 'playing' ? goOut() : (state.value = 'playing'),\n } : {}\n );\n\n return () => h('div', {\n ref: divRef,\n ...attrs,\n class: [attrs.class, animClass.value],\n ...handlers.value,\n }, slots.default?.());\n },\n});\n\nexport default PixodeskSvgCssAnimator;\n"],"mappings":"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","names":["import_vue"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
2
|
import { PropType, VNode } from 'vue';
|
|
3
|
-
import { PxAnimatedSvgDocument,
|
|
3
|
+
import { PxAnimatedSvgDocument, PxAnimatorConfigPatch, StartOn, OutAction } from '@pixodesk/svg-animator-web';
|
|
4
4
|
|
|
5
5
|
interface VueAnimatorApi {
|
|
6
6
|
/** Returns true if the animation is currently running. */
|
|
@@ -43,8 +43,8 @@ interface VueAnimatorApi {
|
|
|
43
43
|
*
|
|
44
44
|
* 4. **Controlled time** โ renders a single frame at a given time.
|
|
45
45
|
* ```vue
|
|
46
|
-
* <PixodeskSvgAnimator :doc="animation" :
|
|
47
|
-
* <PixodeskSvgAnimator :doc="animation" :
|
|
46
|
+
* <PixodeskSvgAnimator :doc="animation" :progress="0.5" />
|
|
47
|
+
* <PixodeskSvgAnimator :doc="animation" :time="500" />
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
50
|
declare const PixodeskSvgAnimator: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
@@ -52,36 +52,25 @@ declare const PixodeskSvgAnimator: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
52
52
|
type: PropType<PxAnimatedSvgDocument>;
|
|
53
53
|
required: true;
|
|
54
54
|
};
|
|
55
|
-
|
|
56
|
-
type: PropType<
|
|
55
|
+
config: {
|
|
56
|
+
type: PropType<PxAnimatorConfigPatch | string>;
|
|
57
57
|
};
|
|
58
|
-
|
|
59
|
-
type:
|
|
60
|
-
|
|
61
|
-
fill: {
|
|
62
|
-
type: PropType<FillMode>;
|
|
63
|
-
};
|
|
64
|
-
iterations: {
|
|
65
|
-
type: PropType<number | "infinite">;
|
|
58
|
+
resetDocDefaults: {
|
|
59
|
+
type: BooleanConstructor;
|
|
60
|
+
default: undefined;
|
|
66
61
|
};
|
|
67
62
|
duration: {
|
|
68
63
|
type: NumberConstructor;
|
|
69
64
|
};
|
|
70
|
-
|
|
71
|
-
type: PropType<PlaybackDirection>;
|
|
72
|
-
};
|
|
73
|
-
frameRate: {
|
|
65
|
+
delay: {
|
|
74
66
|
type: NumberConstructor;
|
|
75
67
|
};
|
|
68
|
+
iterations: {
|
|
69
|
+
type: PropType<number | "infinite">;
|
|
70
|
+
};
|
|
76
71
|
startOn: {
|
|
77
72
|
type: PropType<"load" | "mouseOver" | "click" | "scrollIntoView" | "programmatic">;
|
|
78
73
|
};
|
|
79
|
-
outAction: {
|
|
80
|
-
type: PropType<"continue" | "pause" | "reset" | "reverse">;
|
|
81
|
-
};
|
|
82
|
-
scrollIntoViewThreshold: {
|
|
83
|
-
type: NumberConstructor;
|
|
84
|
-
};
|
|
85
74
|
autoplay: {
|
|
86
75
|
type: BooleanConstructor;
|
|
87
76
|
default: undefined;
|
|
@@ -94,49 +83,38 @@ declare const PixodeskSvgAnimator: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
94
83
|
type: BooleanConstructor;
|
|
95
84
|
default: undefined;
|
|
96
85
|
};
|
|
97
|
-
|
|
86
|
+
progress: {
|
|
98
87
|
type: NumberConstructor;
|
|
99
88
|
};
|
|
100
|
-
|
|
89
|
+
time: {
|
|
101
90
|
type: NumberConstructor;
|
|
102
91
|
};
|
|
103
92
|
}>, () => VNode<vue.RendererNode, vue.RendererElement, {
|
|
104
93
|
[key: string]: any;
|
|
105
|
-
}> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("play" | "
|
|
94
|
+
}> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("play" | "stop" | "pause" | "cancel" | "finish" | "remove")[], "play" | "stop" | "pause" | "cancel" | "finish" | "remove", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
106
95
|
doc: {
|
|
107
96
|
type: PropType<PxAnimatedSvgDocument>;
|
|
108
97
|
required: true;
|
|
109
98
|
};
|
|
110
|
-
|
|
111
|
-
type: PropType<
|
|
112
|
-
};
|
|
113
|
-
delay: {
|
|
114
|
-
type: NumberConstructor;
|
|
115
|
-
};
|
|
116
|
-
fill: {
|
|
117
|
-
type: PropType<FillMode>;
|
|
99
|
+
config: {
|
|
100
|
+
type: PropType<PxAnimatorConfigPatch | string>;
|
|
118
101
|
};
|
|
119
|
-
|
|
120
|
-
type:
|
|
102
|
+
resetDocDefaults: {
|
|
103
|
+
type: BooleanConstructor;
|
|
104
|
+
default: undefined;
|
|
121
105
|
};
|
|
122
106
|
duration: {
|
|
123
107
|
type: NumberConstructor;
|
|
124
108
|
};
|
|
125
|
-
|
|
126
|
-
type: PropType<PlaybackDirection>;
|
|
127
|
-
};
|
|
128
|
-
frameRate: {
|
|
109
|
+
delay: {
|
|
129
110
|
type: NumberConstructor;
|
|
130
111
|
};
|
|
112
|
+
iterations: {
|
|
113
|
+
type: PropType<number | "infinite">;
|
|
114
|
+
};
|
|
131
115
|
startOn: {
|
|
132
116
|
type: PropType<"load" | "mouseOver" | "click" | "scrollIntoView" | "programmatic">;
|
|
133
117
|
};
|
|
134
|
-
outAction: {
|
|
135
|
-
type: PropType<"continue" | "pause" | "reset" | "reverse">;
|
|
136
|
-
};
|
|
137
|
-
scrollIntoViewThreshold: {
|
|
138
|
-
type: NumberConstructor;
|
|
139
|
-
};
|
|
140
118
|
autoplay: {
|
|
141
119
|
type: BooleanConstructor;
|
|
142
120
|
default: undefined;
|
|
@@ -149,22 +127,23 @@ declare const PixodeskSvgAnimator: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
149
127
|
type: BooleanConstructor;
|
|
150
128
|
default: undefined;
|
|
151
129
|
};
|
|
152
|
-
|
|
130
|
+
progress: {
|
|
153
131
|
type: NumberConstructor;
|
|
154
132
|
};
|
|
155
|
-
|
|
133
|
+
time: {
|
|
156
134
|
type: NumberConstructor;
|
|
157
135
|
};
|
|
158
136
|
}>> & Readonly<{
|
|
159
137
|
onPlay?: ((...args: any[]) => any) | undefined;
|
|
160
|
-
onPause?: ((...args: any[]) => any) | undefined;
|
|
161
138
|
onStop?: ((...args: any[]) => any) | undefined;
|
|
139
|
+
onPause?: ((...args: any[]) => any) | undefined;
|
|
162
140
|
onCancel?: ((...args: any[]) => any) | undefined;
|
|
163
141
|
onFinish?: ((...args: any[]) => any) | undefined;
|
|
164
142
|
onRemove?: ((...args: any[]) => any) | undefined;
|
|
165
143
|
}>, {
|
|
166
144
|
autoplay: boolean;
|
|
167
145
|
play: boolean;
|
|
146
|
+
resetDocDefaults: boolean;
|
|
168
147
|
pause: boolean;
|
|
169
148
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
170
149
|
|