nanime 0.0.8 → 0.0.11

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/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.13.5 <5.0.0"
6
6
  },
7
- "version": "0.0.8",
7
+ "version": "0.0.11",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -30,6 +30,7 @@ const module$1 = defineNuxtModule({
30
30
  "animejs/layout",
31
31
  "animejs/text",
32
32
  "animejs/draggable",
33
+ "animejs/timeline",
33
34
  "tailwind-merge",
34
35
  "@vueuse/core",
35
36
  "lodash-es"
@@ -51,6 +52,7 @@ const module$1 = defineNuxtModule({
51
52
  _nuxt.options.alias[`#${__configKey}/types`] = resolver.resolve("./runtime/app/utils/types");
52
53
  _nuxt.options.alias[`#${__configKey}/easings`] = resolver.resolve("./runtime/app/utils/easings");
53
54
  _nuxt.options.alias[`#${__configKey}/utils`] = resolver.resolve("./runtime/app/utils/index");
55
+ _nuxt.options.alias[`#${__configKey}/proxies/text`] = resolver.resolve("./runtime/app/utils/proxies/text");
54
56
  }
55
57
  });
56
58
 
@@ -3,6 +3,7 @@ import { toReactive, tryOnScopeDispose, useMounted } from "@vueuse/core";
3
3
  import { shallowRef, toValue, watchEffect, nextTick } from "vue";
4
4
  import { normalizeAnimeTarget } from "../utils/normalize-targets.js";
5
5
  import { AnimationComponentFlags, getAnimationComponentFlag } from "../utils/normalizers/instance-management.js";
6
+ import { markNanimeInstance } from "../utils/create-proxy.js";
6
7
  export function useAnimatable(target, options) {
7
8
  const flag = getAnimationComponentFlag();
8
9
  const animatable = shallowRef(createAnimatable({}, {}));
@@ -28,5 +29,7 @@ export function useAnimatable(target, options) {
28
29
  animatable.value = newAnimatable;
29
30
  });
30
31
  }
31
- return toReactive(animatable);
32
+ const result = toReactive(animatable);
33
+ markNanimeInstance(result, animatable);
34
+ return result;
32
35
  }
@@ -3,6 +3,7 @@ import { shallowRef, toValue, watchEffect, nextTick } from "vue";
3
3
  import { normalizeAnimeTarget } from "../utils/normalize-targets.js";
4
4
  import { animate } from "animejs/animation";
5
5
  import { AnimationComponentFlags, getAnimationComponentFlag } from "../utils/normalizers/instance-management.js";
6
+ import { markNanimeInstance } from "../utils/create-proxy.js";
6
7
  export function useAnimate(target, parameters) {
7
8
  const flag = getAnimationComponentFlag();
8
9
  const animation = shallowRef(animate({}, {}));
@@ -29,5 +30,7 @@ export function useAnimate(target, parameters) {
29
30
  animation.value = newAnimation;
30
31
  });
31
32
  }
32
- return toReactive(animation);
33
+ const result = toReactive(animation);
34
+ markNanimeInstance(result, animation);
35
+ return result;
33
36
  }
@@ -0,0 +1,12 @@
1
+ import { type MaybeRefOrGetter } from 'vue';
2
+ import type { TimelineParams } from 'animejs';
3
+ import { type Timeline } from 'animejs/timeline';
4
+ import { type ProxyReturns } from '../utils/create-proxy.js';
5
+ /**
6
+ * Reactive timeline composable. Returns a proxied `Timeline` whose
7
+ * `.add()`, `.set()` and `.remove()` methods accept Vue template refs,
8
+ * component refs and `MaybeRefOrGetter` targets alongside raw selectors.
9
+ *
10
+ * Calls made before mount are buffered and replayed once the DOM is ready.
11
+ */
12
+ export declare function useAnimeTimeline(parameters?: MaybeRefOrGetter<TimelineParams>): ProxyReturns<Timeline>;
@@ -0,0 +1,51 @@
1
+ import { tryOnScopeDispose, useMounted } from "@vueuse/core";
2
+ import { shallowRef, toValue, watch, nextTick } from "vue";
3
+ import { createTimeline } from "animejs/timeline";
4
+ import { normalizeAnimeTarget } from "../utils/normalize-targets.js";
5
+ import { createBufferedProxy, resolveNanimeInstance } from "../utils/create-proxy.js";
6
+ import { AnimationComponentFlags, getAnimationComponentFlag } from "../utils/normalizers/instance-management.js";
7
+ const CHAINABLE_METHODS = /* @__PURE__ */ new Set(["add", "set", "remove", "call", "label", "sync"]);
8
+ const TARGET_METHODS = /* @__PURE__ */ new Set(["set", "remove"]);
9
+ function isPlainObject(value) {
10
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11
+ }
12
+ export function useAnimeTimeline(parameters) {
13
+ const flag = getAnimationComponentFlag();
14
+ const mounted = useMounted();
15
+ const timeline = shallowRef(null);
16
+ const { proxy, flushBuffer } = createBufferedProxy(timeline, {
17
+ chainableMethods: CHAINABLE_METHODS,
18
+ transformArgs: (method, args) => {
19
+ if (method === "add" && args.length >= 2 && isPlainObject(args[1])) {
20
+ return [normalizeAnimeTarget(args[0]), ...args.slice(1)];
21
+ }
22
+ if (TARGET_METHODS.has(method)) {
23
+ return [normalizeAnimeTarget(args[0]), ...args.slice(1)];
24
+ }
25
+ if (method === "sync" && args.length >= 1) {
26
+ return [resolveNanimeInstance(args[0]), ...args.slice(1)];
27
+ }
28
+ return args;
29
+ }
30
+ });
31
+ if (flag === AnimationComponentFlags.Watchable) {
32
+ watch(
33
+ [mounted, () => toValue(parameters)],
34
+ () => {
35
+ if (!mounted.value) return;
36
+ if (timeline.value) timeline.value.revert();
37
+ timeline.value = createTimeline(toValue(parameters) || {});
38
+ flushBuffer();
39
+ }
40
+ );
41
+ } else {
42
+ nextTick(() => {
43
+ timeline.value = createTimeline(toValue(parameters) || {});
44
+ flushBuffer();
45
+ });
46
+ }
47
+ tryOnScopeDispose(() => {
48
+ timeline.value?.revert();
49
+ });
50
+ return proxy;
51
+ }
@@ -0,0 +1,5 @@
1
+ import { type MaybeRefOrGetter } from 'vue';
2
+ import { normalizeAnimeTarget } from '../utils/normalize-targets.js';
3
+ import type { AnimationParams, ScrambleTextParams } from 'animejs';
4
+ import { type JSAnimation } from 'animejs/animation';
5
+ export declare function useScrambleText(target: Parameters<typeof normalizeAnimeTarget>[0], animationOptions?: MaybeRefOrGetter<AnimationParams>, scrambleOptions?: MaybeRefOrGetter<ScrambleTextParams>): JSAnimation;
@@ -0,0 +1,41 @@
1
+ import { toReactive, tryOnScopeDispose, useMounted } from "@vueuse/core";
2
+ import { shallowRef, toValue, watchEffect, nextTick } from "vue";
3
+ import { normalizeAnimeTarget } from "../utils/normalize-targets.js";
4
+ import { animate } from "animejs/animation";
5
+ import { scrambleText } from "animejs/text";
6
+ import { AnimationComponentFlags, getAnimationComponentFlag } from "../utils/normalizers/instance-management.js";
7
+ import { markNanimeInstance } from "../utils/create-proxy.js";
8
+ export function useScrambleText(target, animationOptions, scrambleOptions) {
9
+ const flag = getAnimationComponentFlag();
10
+ const animation = shallowRef(animate({}, {}));
11
+ const mounted = useMounted();
12
+ function buildParams() {
13
+ const anim = toValue(animationOptions) || {};
14
+ const scramble = toValue(scrambleOptions) || {};
15
+ return {
16
+ ...anim,
17
+ innerHTML: scrambleText(scramble)
18
+ };
19
+ }
20
+ if (flag === AnimationComponentFlags.Watchable) {
21
+ watchEffect(() => {
22
+ if (!mounted.value) return;
23
+ const targets = normalizeAnimeTarget(target);
24
+ if (!targets) return;
25
+ if (animation.value) animation.value.revert();
26
+ animation.value = animate(targets, buildParams());
27
+ });
28
+ tryOnScopeDispose(() => {
29
+ animation.value?.revert();
30
+ });
31
+ } else {
32
+ nextTick(() => {
33
+ const targets = normalizeAnimeTarget(target);
34
+ if (!targets) return;
35
+ animation.value = animate(targets, buildParams());
36
+ });
37
+ }
38
+ const result = toReactive(animation);
39
+ markNanimeInstance(result, animation);
40
+ return result;
41
+ }
@@ -3,6 +3,7 @@ import { shallowRef, toValue, watchEffect, nextTick } from "vue";
3
3
  import { normalizeWaapiAnimeTarget } from "../utils/normalize-targets.js";
4
4
  import { waapi } from "animejs/waapi";
5
5
  import { AnimationComponentFlags, getAnimationComponentFlag } from "../utils/normalizers/instance-management.js";
6
+ import { markNanimeInstance } from "../utils/create-proxy.js";
6
7
  export function useWaapiAnimate(target, parameters) {
7
8
  const flag = getAnimationComponentFlag();
8
9
  const animation = shallowRef(waapi.animate([], {}));
@@ -27,5 +28,7 @@ export function useWaapiAnimate(target, parameters) {
27
28
  animation.value = newAnimation;
28
29
  });
29
30
  }
30
- return toReactive(animation);
31
+ const result = toReactive(animation);
32
+ markNanimeInstance(result, animation);
33
+ return result;
31
34
  }
@@ -1,4 +1,23 @@
1
1
  import type { Ref, UnwrapNestedRefs } from 'vue';
2
+ /**
3
+ * Symbol used to identify nanime proxy objects and retrieve
4
+ * the underlying raw anime.js instance ref.
5
+ * Accessible via proxy[NANIME_INSTANCE] on createProxy / createBufferedProxy returns.
6
+ */
7
+ export declare const NANIME_INSTANCE: unique symbol;
8
+ /**
9
+ * Registers a toReactive-based return value so that
10
+ * `resolveNanimeInstance` can extract the raw anime.js instance.
11
+ */
12
+ export declare function markNanimeInstance<T>(proxy: object, instanceRef: Ref<T>): void;
13
+ /**
14
+ * Extracts the raw anime.js instance from a nanime proxy,
15
+ * or returns the value unchanged if it isn't a proxy.
16
+ *
17
+ * Checks the NANIME_INSTANCE symbol first (createProxy / createBufferedProxy),
18
+ * then falls back to the WeakMap registry (toReactive-based composables).
19
+ */
20
+ export declare function resolveNanimeInstance<T>(value: unknown): T;
2
21
  export type SafeFunctions<T> = {
3
22
  [K in keyof T]: T[K] extends (...args: any[]) => any ? ((...args: Parameters<T[K]>) => ReturnType<T[K]>) | undefined : T[K];
4
23
  };
@@ -7,3 +26,19 @@ export type ProxyReturns<T> = SafeFunctions<Exclude<UnwrapNestedRefs<T>, null |
7
26
  * Converts the object to a reactive version, and stubs null / undefined values
8
27
  */
9
28
  export declare function createProxy<T = object | null>(objectRef: Ref<T>): ProxyReturns<T>;
29
+ export interface BufferedProxyOptions {
30
+ /** Methods that support chaining and should be buffered when instance is null */
31
+ chainableMethods: Set<string>;
32
+ /** Transform args before passing to the real method (e.g. normalize targets) */
33
+ transformArgs?: (method: string, args: any[]) => any[];
34
+ }
35
+ /**
36
+ * Like `createProxy`, but with two additions:
37
+ * 1. Chainable methods are buffered when the ref is null and replayed on flush.
38
+ * 2. An optional `transformArgs` hook rewrites arguments before each call
39
+ * (used to normalize Vue ref targets into DOM targets).
40
+ */
41
+ export declare function createBufferedProxy<T>(objectRef: Ref<T | null>, options: BufferedProxyOptions): {
42
+ proxy: ProxyReturns<T>;
43
+ flushBuffer: () => void;
44
+ };
@@ -1,7 +1,23 @@
1
1
  import { unref, isRef, reactive } from "vue";
2
+ export const NANIME_INSTANCE = Symbol.for("nanime-instance");
3
+ const nanimeRegistry = /* @__PURE__ */ new WeakMap();
4
+ export function markNanimeInstance(proxy, instanceRef) {
5
+ nanimeRegistry.set(proxy, instanceRef);
6
+ }
7
+ export function resolveNanimeInstance(value) {
8
+ if (value && typeof value === "object") {
9
+ if (NANIME_INSTANCE in value) {
10
+ return value[NANIME_INSTANCE].value;
11
+ }
12
+ const ref = nanimeRegistry.get(value);
13
+ if (ref) return ref.value;
14
+ }
15
+ return value;
16
+ }
2
17
  export function createProxy(objectRef) {
3
18
  const proxy = new Proxy({}, {
4
19
  get(_, p, receiver) {
20
+ if (p === NANIME_INSTANCE) return objectRef;
5
21
  if (!objectRef.value) return void 0;
6
22
  return unref(Reflect.get(objectRef.value, p, receiver));
7
23
  },
@@ -18,6 +34,7 @@ export function createProxy(objectRef) {
18
34
  return Reflect.deleteProperty(objectRef.value, p);
19
35
  },
20
36
  has(_, p) {
37
+ if (p === NANIME_INSTANCE) return true;
21
38
  if (!objectRef.value) return true;
22
39
  return Reflect.has(objectRef.value, p);
23
40
  },
@@ -35,3 +52,73 @@ export function createProxy(objectRef) {
35
52
  });
36
53
  return reactive(proxy);
37
54
  }
55
+ export function createBufferedProxy(objectRef, options) {
56
+ const { chainableMethods, transformArgs } = options;
57
+ const buffer = [];
58
+ function applyMethod(instance, method, args) {
59
+ const transformed = transformArgs ? transformArgs(method, args) : args;
60
+ const fn = instance[method];
61
+ if (typeof fn === "function") {
62
+ fn.apply(instance, transformed);
63
+ }
64
+ }
65
+ function flushBuffer() {
66
+ if (!objectRef.value) return;
67
+ for (const entry of buffer) {
68
+ applyMethod(objectRef.value, entry.method, entry.args);
69
+ }
70
+ buffer.length = 0;
71
+ }
72
+ const proxy = new Proxy({}, {
73
+ get(_, p, receiver) {
74
+ if (p === NANIME_INSTANCE) return objectRef;
75
+ if (typeof p === "symbol") {
76
+ if (!objectRef.value) return void 0;
77
+ return Reflect.get(objectRef.value, p);
78
+ }
79
+ if (chainableMethods.has(p)) {
80
+ return (...args) => {
81
+ if (!objectRef.value) {
82
+ buffer.push({ method: p, args });
83
+ } else {
84
+ applyMethod(objectRef.value, p, args);
85
+ }
86
+ return receiver;
87
+ };
88
+ }
89
+ if (!objectRef.value) return void 0;
90
+ const val = Reflect.get(objectRef.value, p);
91
+ if (typeof val === "function") return val.bind(objectRef.value);
92
+ return unref(val);
93
+ },
94
+ set(_, p, value) {
95
+ if (!objectRef.value) return true;
96
+ if (isRef(objectRef.value[p]) && !isRef(value))
97
+ objectRef.value[p].value = value;
98
+ else
99
+ objectRef.value[p] = value;
100
+ return true;
101
+ },
102
+ deleteProperty(_, p) {
103
+ if (!objectRef.value) return true;
104
+ return Reflect.deleteProperty(objectRef.value, p);
105
+ },
106
+ has(_, p) {
107
+ if (p === NANIME_INSTANCE) return true;
108
+ if (!objectRef.value) return false;
109
+ return Reflect.has(objectRef.value, p);
110
+ },
111
+ ownKeys() {
112
+ if (!objectRef.value) return [];
113
+ return Object.keys(objectRef.value);
114
+ },
115
+ getOwnPropertyDescriptor() {
116
+ if (!objectRef.value) return void 0;
117
+ return {
118
+ enumerable: true,
119
+ configurable: true
120
+ };
121
+ }
122
+ });
123
+ return { proxy: reactive(proxy), flushBuffer };
124
+ }
@@ -0,0 +1,2 @@
1
+ export { scrambleText } from 'animejs/text';
2
+ export type { ScrambleTextParams } from 'animejs';
@@ -0,0 +1 @@
1
+ export { scrambleText } from "animejs/text";
@@ -1 +1 @@
1
- export type { AnimationParams, TargetsParam, AutoLayoutParams, EasingParam, LayoutAnimationParams, WAAPIEasingParam, Draggable, DraggableAxisParam, DraggableParams, WAAPIAnimationParams, DOMTargetsParam, DOMTargetSelector, AnimatableObject, AnimatableParams, } from 'animejs';
1
+ export type { AnimationParams, TargetsParam, EasingParam, WAAPIEasingParam, Draggable, DraggableAxisParam, DraggableParams, WAAPIAnimationParams, DOMTargetsParam, DOMTargetSelector, AnimatableObject, AnimatableParams, ScrambleTextParams, TimelineParams, } from 'animejs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanime",
3
- "version": "0.0.8",
3
+ "version": "0.0.11",
4
4
  "description": "Nuxt module for animejs integration and transitions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,46 +32,52 @@
32
32
  "playground",
33
33
  "docs"
34
34
  ],
35
+ "scripts": {
36
+ "prepack": "nuxt-module-build build",
37
+ "dev": "npm run dev:prepare && nuxi dev playground",
38
+ "dev:build": "nuxi build playground",
39
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
40
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
41
+ "build": "pnpm prepare && npm run prepack",
42
+ "prepare": "nuxt-module-build prepare",
43
+ "docs:build": "pnpm -C docs build",
44
+ "docs:prepare": "pnpm -C docs prepare",
45
+ "lint": "eslint .",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest watch",
48
+ "test:types": "nuxt typecheck",
49
+ "clean": "rm -rf playground/.nuxt docs/.nuxt playground/.output docs/.output .nuxt"
50
+ },
35
51
  "dependencies": {
36
- "@vueuse/core": "^14.1.0",
37
- "animejs": "^4.3.5",
38
- "defu": "^6.1.4",
39
- "vue": "^3.5.27"
52
+ "@vueuse/core": "^14.3.0",
53
+ "animejs": "^4.4.1",
54
+ "defu": "^6.1.7",
55
+ "vue": "^3.5.34"
40
56
  },
41
57
  "peerDependencies": {
42
- "@vueuse/core": "^13.0.0",
43
- "animejs": "^4.3.5",
58
+ "@vueuse/core": ">=13.0.0",
59
+ "animejs": "^4.4.0",
44
60
  "defu": "^6.1.4",
45
61
  "vue": "^3.5.0"
46
62
  },
47
63
  "devDependencies": {
48
- "@nuxt/devtools": "^3.1.1",
49
- "@nuxt/eslint-config": "^1.13.0",
50
- "@nuxt/kit": "^4.3.0",
64
+ "@nuxt/devtools": "^3.2.4",
65
+ "@nuxt/eslint-config": "^1.15.2",
66
+ "@nuxt/kit": "^4.4.6",
51
67
  "@nuxt/module-builder": "^1.0.2",
52
- "@nuxt/schema": "^4.3.0",
68
+ "@nuxt/schema": "^4.4.6",
53
69
  "@nuxt/test-utils": "^3.23.0",
54
70
  "@types/node": "latest",
55
- "@vue/test-utils": "^2.4.6",
71
+ "@vue/test-utils": "^2.4.10",
56
72
  "@vueuse/nuxt": "14.1.0",
57
73
  "changelogen": "^0.6.2",
58
- "eslint": "^9.39.2",
59
- "happy-dom": "^20.4.0",
60
- "lefthook": "^2.0.16",
61
- "nuxt": "^4.3.0",
74
+ "eslint": "^9.39.4",
75
+ "happy-dom": "^20.9.0",
76
+ "lefthook": "^2.1.8",
77
+ "nuxt": "^4.4.6",
62
78
  "typescript": "~5.9.3",
63
- "vitest": "^4.0.18",
64
- "vue-tsc": "^3.2.4"
79
+ "vitest": "^3.2.4",
80
+ "vue-tsc": "^3.3.1"
65
81
  },
66
- "scripts": {
67
- "dev": "npm run dev:prepare && nuxt dev playground",
68
- "dev:build": "nuxt build playground",
69
- "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
70
- "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
71
- "lint": "eslint .",
72
- "test": "vitest run",
73
- "test:watch": "vitest watch",
74
- "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
75
- "clean": "rm -rf playground/.nuxt docs/.nuxt playground/.output docs/.output .nuxt"
76
- }
77
- }
82
+ "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b"
83
+ }