@thednp/tween 0.0.1 → 0.0.2
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 +112 -109
- package/dist/preact/preact.d.mts +62 -0
- package/dist/preact/preact.d.mts.map +1 -0
- package/dist/preact/preact.mjs +181 -0
- package/dist/preact/preact.mjs.map +1 -0
- package/dist/react/react.d.mts +62 -0
- package/dist/react/react.d.mts.map +1 -0
- package/dist/react/react.mjs +183 -0
- package/dist/react/react.mjs.map +1 -0
- package/dist/solid/solid.d.mts +60 -0
- package/dist/solid/solid.d.mts.map +1 -0
- package/dist/solid/solid.mjs +157 -0
- package/dist/solid/solid.mjs.map +1 -0
- package/dist/svelte/svelte.d.mts.map +1 -0
- package/dist/svelte/svelte.mjs.map +1 -0
- package/dist/svelte/tween.svelte.d.ts +58 -0
- package/dist/svelte/tween.svelte.js +156 -0
- package/dist/tween/index.d.mts +939 -0
- package/dist/tween/index.d.mts.map +1 -0
- package/dist/tween/index.mjs +1929 -0
- package/dist/tween/index.mjs.map +1 -0
- package/dist/tween.min.js +8 -0
- package/dist/tween.min.js.map +1 -0
- package/dist/vue/vue.d.mts +61 -0
- package/dist/vue/vue.d.mts.map +1 -0
- package/dist/vue/vue.mjs +157 -0
- package/dist/vue/vue.mjs.map +1 -0
- package/package.json +56 -40
- package/dist/index.cjs +0 -621
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -184
- package/dist/index.d.mts +0 -184
- package/dist/index.mjs +0 -610
- package/dist/index.mjs.map +0 -1
- package/dist/react.cjs +0 -61
- package/dist/react.cjs.map +0 -1
- package/dist/react.d.cts +0 -9
- package/dist/react.d.mts +0 -9
- package/dist/react.mjs +0 -55
- package/dist/react.mjs.map +0 -1
- package/dist/solid.cjs +0 -81
- package/dist/solid.cjs.map +0 -1
- package/dist/solid.d.cts +0 -9
- package/dist/solid.d.mts +0 -9
- package/dist/solid.mjs +0 -75
- package/dist/solid.mjs.map +0 -1
- package/dist/tween.iife.js +0 -2
- package/dist/tween.iife.js.map +0 -1
- package/wiki/Easing.md +0 -58
- package/wiki/React.md +0 -255
- package/wiki/Solid.md +0 -149
- package/wiki/Timeline.md +0 -207
- package/wiki/Tween.md +0 -230
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @thednp/tween hooks for React v0.0.2 (https://github.com/thednp/tween)
|
|
3
|
+
* Copyright 2026 © thednp
|
|
4
|
+
* Licensed under MIT (https://github.com/thednp/tween/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
import { Timeline, Tween, TweenProps } from "@thednp/tween";
|
|
9
|
+
|
|
10
|
+
//#region src/react/miniStore.d.ts
|
|
11
|
+
declare function useMiniStore<T extends TweenProps>(initialValue: T): T;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/react/index.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Hook for updating values with Tween.
|
|
16
|
+
*
|
|
17
|
+
* **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.
|
|
18
|
+
* This has two important aspects: never configure or start update loop in SSR
|
|
19
|
+
* and only configure or start the loop when component is mounted in the client.
|
|
20
|
+
*
|
|
21
|
+
* @param initialValues - Initial tween values
|
|
22
|
+
* @returns [store, tween] Tuple of reactive store and Tween instance
|
|
23
|
+
* @example
|
|
24
|
+
* const App = () => {
|
|
25
|
+
* const [state, tween] = useTween({ x: 0, y: 0 })
|
|
26
|
+
*
|
|
27
|
+
* useEffect(() => {
|
|
28
|
+
* tween.to({ x: 100, y: 100 }).start()
|
|
29
|
+
* }, [])
|
|
30
|
+
*
|
|
31
|
+
* return (
|
|
32
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
*/
|
|
36
|
+
declare const useTween: <T extends TweenProps>(initialValues: T) => readonly [T, Tween<T>];
|
|
37
|
+
/**
|
|
38
|
+
* Hook for sequencing values update with Timeline.
|
|
39
|
+
*
|
|
40
|
+
* **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.
|
|
41
|
+
* This has two important aspects: never configure or start update loop in SSR
|
|
42
|
+
* and only configure or start the loop when component is mounted in the client.
|
|
43
|
+
*
|
|
44
|
+
* @param initialValues - Initial tween values
|
|
45
|
+
* @returns [store, timeline] Tuple of reactive store and Timeline instance
|
|
46
|
+
* @example
|
|
47
|
+
* const App = () => {
|
|
48
|
+
* const [state, timeline] = useTimeline({ x: 0, y: 0 })
|
|
49
|
+
*
|
|
50
|
+
* useEffect(() => {
|
|
51
|
+
* timeline.to({ x: 100, y: 100 }).start()
|
|
52
|
+
* }, [])
|
|
53
|
+
*
|
|
54
|
+
* return (
|
|
55
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
56
|
+
* );
|
|
57
|
+
* }
|
|
58
|
+
*/
|
|
59
|
+
declare function useTimeline<T extends TweenProps>(initialValues: T): readonly [T, Timeline<T>];
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Timeline, Tween, useMiniStore, useTimeline, useTween };
|
|
62
|
+
//# sourceMappingURL=react.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.mts","names":[],"sources":["../../src/react/miniStore.ts","../../src/react/index.ts"],"mappings":";;;;;;;;;;iBA0JgB,YAAA,WAAuB,UAAA,CAAA,CAAY,YAAA,EAAc,CAAA,GAAC,CAAA;;;AAAlE;;;;;;;;;;;;;;;;;;ACxHA;;;;ADwHA,cCxHa,QAAA,aAAsB,UAAA,EAAY,aAAA,EAAe,CAAA,eAAC,CAAA,EAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;AA4C/D;;;;;;;;iBAAgB,WAAA,WAAsB,UAAA,CAAA,CAAY,aAAA,EAAe,CAAA,aAAC,CAAA,EAAA,QAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @thednp/tween hooks for React v0.0.2 (https://github.com/thednp/tween)
|
|
3
|
+
* Copyright 2026 © thednp
|
|
4
|
+
* Licensed under MIT (https://github.com/thednp/tween/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
import { useEffect, useRef, useState } from "react";
|
|
9
|
+
import { Timeline, Tween, dummyInstance, isArray, isPlainObject, isServer, objectHasProp } from "@thednp/tween";
|
|
10
|
+
|
|
11
|
+
//#region src/react/miniStore.ts
|
|
12
|
+
const STATE_PROXY = "_proxy";
|
|
13
|
+
const proxyProps = {
|
|
14
|
+
value: 1,
|
|
15
|
+
enumerable: false,
|
|
16
|
+
configurable: false,
|
|
17
|
+
writable: false
|
|
18
|
+
};
|
|
19
|
+
function defineArrayProxy(index, value, target, sourceLen, notifyListeners) {
|
|
20
|
+
const itemIsLast = index === sourceLen - 1;
|
|
21
|
+
if (isArray(value)) {
|
|
22
|
+
const subArray = [];
|
|
23
|
+
const valueLen = value.length;
|
|
24
|
+
value.forEach((itm, idx) => {
|
|
25
|
+
const subItemIsLast = itemIsLast && idx === valueLen - 1;
|
|
26
|
+
let currentItem = itm;
|
|
27
|
+
Object.defineProperty(subArray, idx, {
|
|
28
|
+
get: () => currentItem,
|
|
29
|
+
set: (newValue) => {
|
|
30
|
+
currentItem = newValue;
|
|
31
|
+
if (subItemIsLast) notifyListeners();
|
|
32
|
+
},
|
|
33
|
+
enumerable: true
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
target[index] = subArray;
|
|
37
|
+
} else {
|
|
38
|
+
let currentValue = value;
|
|
39
|
+
const getter = () => currentValue;
|
|
40
|
+
const setter = (newVal) => {
|
|
41
|
+
currentValue = newVal;
|
|
42
|
+
if (itemIsLast) notifyListeners();
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperties(target, { [index]: {
|
|
45
|
+
get: getter,
|
|
46
|
+
set: setter,
|
|
47
|
+
enumerable: true
|
|
48
|
+
} });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function defineStateProxy(key, value, target, notifyListeners) {
|
|
52
|
+
const valueIsArray = isArray(value);
|
|
53
|
+
let currentValue = value;
|
|
54
|
+
const getter = () => currentValue;
|
|
55
|
+
let setter;
|
|
56
|
+
if (valueIsArray) {
|
|
57
|
+
const arrayProxy = [];
|
|
58
|
+
const valLength = value.length;
|
|
59
|
+
for (let i = 0; i < valLength; i++) defineArrayProxy(i, value[i], arrayProxy, valLength, notifyListeners);
|
|
60
|
+
currentValue = arrayProxy;
|
|
61
|
+
} else setter = (newValue) => {
|
|
62
|
+
if (currentValue !== newValue) {
|
|
63
|
+
currentValue = newValue;
|
|
64
|
+
notifyListeners();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
Object.defineProperties(target, {
|
|
68
|
+
[STATE_PROXY]: proxyProps,
|
|
69
|
+
[key]: {
|
|
70
|
+
get: getter,
|
|
71
|
+
set: setter,
|
|
72
|
+
enumerable: true
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function createMiniState(obj, parentReceiver, notifyListeners) {
|
|
77
|
+
if (objectHasProp(obj, STATE_PROXY)) return obj;
|
|
78
|
+
for (const [key, value] of Object.entries(obj)) if (isPlainObject(value)) parentReceiver[key] = createMiniState(value, {}, notifyListeners);
|
|
79
|
+
else defineStateProxy(key, value, parentReceiver, notifyListeners);
|
|
80
|
+
return parentReceiver;
|
|
81
|
+
}
|
|
82
|
+
function miniStore(init) {
|
|
83
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
84
|
+
const notifyListeners = () => {
|
|
85
|
+
listeners.forEach((listener) => listener(store));
|
|
86
|
+
};
|
|
87
|
+
const store = createMiniState(init, {}, notifyListeners);
|
|
88
|
+
return {
|
|
89
|
+
get state() {
|
|
90
|
+
return store;
|
|
91
|
+
},
|
|
92
|
+
subscribe: (listener) => {
|
|
93
|
+
listeners.add(listener);
|
|
94
|
+
return () => {
|
|
95
|
+
listeners.delete(listener);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function useMiniStore(initialValue) {
|
|
101
|
+
const storeRef = useRef(null);
|
|
102
|
+
const [, setVersion] = useState(0);
|
|
103
|
+
if (!storeRef.current) storeRef.current = miniStore(initialValue);
|
|
104
|
+
useEffect(() => storeRef.current.subscribe(() => setVersion((v) => v === 2 ? 0 : v + 1)), []);
|
|
105
|
+
return storeRef.current.state;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/react/index.ts
|
|
110
|
+
/**
|
|
111
|
+
* Hook for updating values with Tween.
|
|
112
|
+
*
|
|
113
|
+
* **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.
|
|
114
|
+
* This has two important aspects: never configure or start update loop in SSR
|
|
115
|
+
* and only configure or start the loop when component is mounted in the client.
|
|
116
|
+
*
|
|
117
|
+
* @param initialValues - Initial tween values
|
|
118
|
+
* @returns [store, tween] Tuple of reactive store and Tween instance
|
|
119
|
+
* @example
|
|
120
|
+
* const App = () => {
|
|
121
|
+
* const [state, tween] = useTween({ x: 0, y: 0 })
|
|
122
|
+
*
|
|
123
|
+
* useEffect(() => {
|
|
124
|
+
* tween.to({ x: 100, y: 100 }).start()
|
|
125
|
+
* }, [])
|
|
126
|
+
*
|
|
127
|
+
* return (
|
|
128
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
129
|
+
* );
|
|
130
|
+
* }
|
|
131
|
+
*/
|
|
132
|
+
const useTween = (initialValues) => {
|
|
133
|
+
if (isServer) return [initialValues, dummyInstance];
|
|
134
|
+
const tweenRef = useRef(null);
|
|
135
|
+
const state = useMiniStore(initialValues);
|
|
136
|
+
if (!tweenRef.current) tweenRef.current = new Tween(state);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
return () => {
|
|
139
|
+
tweenRef.current?.stop();
|
|
140
|
+
tweenRef.current?.clear();
|
|
141
|
+
};
|
|
142
|
+
}, []);
|
|
143
|
+
return [state, tweenRef.current];
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Hook for sequencing values update with Timeline.
|
|
147
|
+
*
|
|
148
|
+
* **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.
|
|
149
|
+
* This has two important aspects: never configure or start update loop in SSR
|
|
150
|
+
* and only configure or start the loop when component is mounted in the client.
|
|
151
|
+
*
|
|
152
|
+
* @param initialValues - Initial tween values
|
|
153
|
+
* @returns [store, timeline] Tuple of reactive store and Timeline instance
|
|
154
|
+
* @example
|
|
155
|
+
* const App = () => {
|
|
156
|
+
* const [state, timeline] = useTimeline({ x: 0, y: 0 })
|
|
157
|
+
*
|
|
158
|
+
* useEffect(() => {
|
|
159
|
+
* timeline.to({ x: 100, y: 100 }).start()
|
|
160
|
+
* }, [])
|
|
161
|
+
*
|
|
162
|
+
* return (
|
|
163
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
164
|
+
* );
|
|
165
|
+
* }
|
|
166
|
+
*/
|
|
167
|
+
function useTimeline(initialValues) {
|
|
168
|
+
if (isServer) return [initialValues, dummyInstance];
|
|
169
|
+
const timelineRef = useRef(null);
|
|
170
|
+
const state = useMiniStore(initialValues);
|
|
171
|
+
if (!timelineRef.current) timelineRef.current = new Timeline(state);
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
return () => {
|
|
174
|
+
timelineRef.current?.clear();
|
|
175
|
+
timelineRef.current?.stop();
|
|
176
|
+
};
|
|
177
|
+
}, []);
|
|
178
|
+
return [state, timelineRef.current];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
//#endregion
|
|
182
|
+
export { Timeline, Tween, useMiniStore, useTimeline, useTween };
|
|
183
|
+
//# sourceMappingURL=react.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.mjs","names":[],"sources":["../../src/react/miniStore.ts","../../src/react/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n type ArrayVal,\n isArray,\n isPlainObject,\n objectHasProp,\n type TweenProps,\n} from \"@thednp/tween\";\n\nconst STATE_PROXY = \"_proxy\";\nconst proxyProps = {\n value: 1,\n enumerable: false,\n configurable: false,\n writable: false,\n};\n\ntype Listener<T> = (state: T) => void;\n\nfunction defineArrayProxy<T extends ArrayVal>(\n index: number,\n value: T[number] | ArrayVal,\n target: T | ArrayVal | ArrayVal[],\n sourceLen: number,\n notifyListeners: () => void,\n) {\n const itemIsLast = index === sourceLen - 1;\n\n if (isArray(value)) {\n const subArray: typeof value = [];\n const valueLen = value.length;\n\n value.forEach((itm, idx) => {\n const subItemIsLast = itemIsLast && idx === valueLen - 1;\n\n let currentItem = itm;\n Object.defineProperty(subArray, idx, {\n get: () => currentItem,\n set: (newValue: typeof itm) => {\n currentItem = newValue;\n\n // Only notify on last element to batch updates\n if (subItemIsLast) {\n notifyListeners();\n }\n },\n enumerable: true,\n });\n });\n target[index] = subArray;\n } else {\n let currentValue = value;\n const getter = () => currentValue;\n const setter = (newVal: typeof value) => {\n currentValue = newVal;\n if (itemIsLast) {\n notifyListeners();\n }\n };\n Object.defineProperties(target, {\n [index]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n }\n}\n\nfunction defineStateProxy<T extends Omit<TweenProps, \"_proxy\">>(\n key: number | keyof T,\n value: T[keyof T],\n target: T | ArrayVal,\n notifyListeners: () => void,\n) {\n const valueIsArray = isArray(value);\n let currentValue = value as ArrayVal | ArrayVal[];\n\n const getter = () => currentValue;\n let setter;\n\n if (valueIsArray) {\n // Build array proxy structure\n const arrayProxy: ArrayVal | ArrayVal[] = [];\n const valLength = value.length;\n\n for (let i = 0; i < valLength; i++) {\n defineArrayProxy(\n i,\n (value as ArrayVal)[i],\n arrayProxy as ArrayVal,\n valLength,\n notifyListeners,\n );\n }\n currentValue = arrayProxy;\n } else {\n setter = (newValue: typeof currentValue) => {\n if (currentValue !== newValue) {\n currentValue = newValue;\n notifyListeners();\n }\n };\n }\n\n Object.defineProperties(target, {\n [STATE_PROXY]: proxyProps,\n [key]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n}\n\nfunction createMiniState<T extends TweenProps>(\n obj: T,\n parentReceiver: TweenProps,\n notifyListeners: () => void,\n) {\n if (objectHasProp(obj, STATE_PROXY)) return obj;\n\n for (const [key, value] of Object.entries(obj)) {\n if (isPlainObject(value)) {\n parentReceiver[key] = createMiniState(value, {}, notifyListeners);\n } else {\n defineStateProxy(key, value, parentReceiver, notifyListeners);\n }\n }\n\n return parentReceiver as T;\n}\n\nexport function miniStore<T extends TweenProps>(init: T) {\n const listeners = new Set<Listener<T>>();\n const notifyListeners = () => {\n listeners.forEach((listener) => listener(store));\n };\n\n const store = createMiniState(init, {}, notifyListeners) as T;\n\n return {\n get state() {\n return store;\n },\n subscribe: (listener: Listener<T>) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\nexport function useMiniStore<T extends TweenProps>(initialValue: T) {\n const storeRef = useRef<ReturnType<typeof miniStore<T>>>(null);\n const [, setVersion] = useState(0);\n\n // istanbul ignore else @preserve\n if (!storeRef.current) {\n storeRef.current = miniStore(initialValue);\n }\n\n useEffect(\n () =>\n storeRef.current!.subscribe(() =>\n setVersion((v) => v === 2 ? /* istanbul ignore next */ 0 : v + 1)\n ),\n [],\n );\n\n return storeRef.current!.state;\n}\n","import { useEffect, useRef } from \"react\";\nimport {\n dummyInstance,\n isServer,\n Timeline,\n Tween,\n type TweenProps,\n} from \"@thednp/tween\";\nimport { useMiniStore } from \"./miniStore.ts\";\n\nexport { Timeline, Tween, useMiniStore };\n\n/**\n * Hook for updating values with Tween.\n *\n * **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.\n * This has two important aspects: never configure or start update loop in SSR\n * and only configure or start the loop when component is mounted in the client.\n *\n * @param initialValues - Initial tween values\n * @returns [store, tween] Tuple of reactive store and Tween instance\n * @example\n * const App = () => {\n * const [state, tween] = useTween({ x: 0, y: 0 })\n *\n * useEffect(() => {\n * tween.to({ x: 100, y: 100 }).start()\n * }, [])\n *\n * return (\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n * );\n * }\n */\nexport const useTween = <T extends TweenProps>(initialValues: T) => {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Tween<T>] as const;\n }\n const tweenRef = useRef<Tween<T> | null>(null);\n const state = useMiniStore(initialValues);\n\n // istanbul ignore else @preserve\n if (!tweenRef.current) {\n tweenRef.current = new Tween(state);\n }\n\n useEffect(() => {\n return () => {\n tweenRef.current?.stop();\n tweenRef.current?.clear();\n };\n }, []);\n\n return [state, tweenRef.current] as [T, Tween<T>];\n};\n\n/**\n * Hook for sequencing values update with Timeline.\n *\n * **NOTE**: - configuration must be wrapped in `useEffect` or `eventListener`.\n * This has two important aspects: never configure or start update loop in SSR\n * and only configure or start the loop when component is mounted in the client.\n *\n * @param initialValues - Initial tween values\n * @returns [store, timeline] Tuple of reactive store and Timeline instance\n * @example\n * const App = () => {\n * const [state, timeline] = useTimeline({ x: 0, y: 0 })\n *\n * useEffect(() => {\n * timeline.to({ x: 100, y: 100 }).start()\n * }, [])\n *\n * return (\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n * );\n * }\n */\nexport function useTimeline<T extends TweenProps>(initialValues: T) {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Timeline<T>] as const;\n }\n const timelineRef = useRef<Timeline<T> | null>(null);\n const state = useMiniStore(initialValues);\n\n // istanbul ignore else @preserve\n if (!timelineRef.current) {\n timelineRef.current = new Timeline(state);\n }\n\n useEffect(() => {\n return () => {\n timelineRef.current?.clear();\n timelineRef.current?.stop();\n };\n }, []);\n\n return [state, timelineRef.current] as [T, Timeline<T>];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @thednp/tween primitives for SolidJS v0.0.2 (https://github.com/thednp/tween)
|
|
3
|
+
* Copyright 2026 © thednp
|
|
4
|
+
* Licensed under MIT (https://github.com/thednp/tween/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
import { Timeline, Tween, TweenProps } from "@thednp/tween";
|
|
9
|
+
|
|
10
|
+
//#region src/solid/miniStore.d.ts
|
|
11
|
+
declare function miniStore<T extends TweenProps>(init: T): T;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/solid/index.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* SolidJS primitive for updating values with Tween.
|
|
16
|
+
*
|
|
17
|
+
* @param initialValues - Initial tween values
|
|
18
|
+
* @returns [store, tween] Tuple of reactive store and Tween instance
|
|
19
|
+
* @example
|
|
20
|
+
* const App = () => {
|
|
21
|
+
* const [state, tween] = createTween({ x: 0, y: 0 })
|
|
22
|
+
*
|
|
23
|
+
* // configuration is free-form, no re-render ever happens
|
|
24
|
+
* tween.to({ x: 100, y: 100 })
|
|
25
|
+
*
|
|
26
|
+
* onMount(() => {
|
|
27
|
+
* tween.start()
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* return (
|
|
31
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
32
|
+
* );
|
|
33
|
+
* }
|
|
34
|
+
*/
|
|
35
|
+
declare function createTween<T extends TweenProps>(initialValues: T): readonly [T, Tween<T>];
|
|
36
|
+
/**
|
|
37
|
+
* SolidJS primitive for sequencing values update with Timeline.
|
|
38
|
+
*
|
|
39
|
+
* @param initialValues - Initial tween values
|
|
40
|
+
* @returns [store, timeline] Tuple of reactive store and Timeline instance
|
|
41
|
+
* @example
|
|
42
|
+
* const App = () => {
|
|
43
|
+
* const [state, timeline] = createTimeline({ x: 0, y: 0 })
|
|
44
|
+
*
|
|
45
|
+
* // configuration is free-form
|
|
46
|
+
* timeline.to({ x: 100, y: 100 })
|
|
47
|
+
*
|
|
48
|
+
* onMount(() => {
|
|
49
|
+
* timeline.start()
|
|
50
|
+
* })
|
|
51
|
+
*
|
|
52
|
+
* return (
|
|
53
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
54
|
+
* );
|
|
55
|
+
* }
|
|
56
|
+
*/
|
|
57
|
+
declare function createTimeline<T extends TweenProps>(initialValues: T): readonly [T, Timeline<T>];
|
|
58
|
+
//#endregion
|
|
59
|
+
export { Timeline, Tween, createTimeline, createTween, miniStore };
|
|
60
|
+
//# sourceMappingURL=solid.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solid.d.mts","names":[],"sources":["../../src/solid/miniStore.ts","../../src/solid/index.ts"],"mappings":";;;;;;;;;;iBA2HgB,SAAA,WAAoB,UAAA,CAAA,CAAY,IAAA,EAAM,CAAA,GAChB,CAAA;;;AADtC;;;;;;;;;;;;;;;;;;AC1FA;;;AD0FA,iBC1FgB,WAAA,WAAsB,UAAA,CAAA,CAAY,aAAA,EAAe,CAAA,aAAC,CAAA,EAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;AAoClE;;;;;;iBAAgB,cAAA,WAAyB,UAAA,CAAA,CAAY,aAAA,EAAe,CAAA,aAAC,CAAA,EAAA,QAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @thednp/tween primitives for SolidJS v0.0.2 (https://github.com/thednp/tween)
|
|
3
|
+
* Copyright 2026 © thednp
|
|
4
|
+
* Licensed under MIT (https://github.com/thednp/tween/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
import { Timeline, Tween, dummyInstance, isArray, isPlainObject, isServer, objectHasProp } from "@thednp/tween";
|
|
9
|
+
import { createSignal, onCleanup } from "solid-js";
|
|
10
|
+
|
|
11
|
+
//#region src/solid/miniStore.ts
|
|
12
|
+
const STATE_PROXY = "_proxy";
|
|
13
|
+
const proxyProps = {
|
|
14
|
+
value: 1,
|
|
15
|
+
enumerable: false,
|
|
16
|
+
configurable: false,
|
|
17
|
+
writable: false
|
|
18
|
+
};
|
|
19
|
+
function defineArrayProxy(index, value, target, sourceLen, notifyListeners) {
|
|
20
|
+
const itemIsLast = index === sourceLen - 1;
|
|
21
|
+
if (isArray(value)) {
|
|
22
|
+
const subArray = [];
|
|
23
|
+
const valueLen = value.length;
|
|
24
|
+
value.forEach((itm, idx) => {
|
|
25
|
+
const subItemIsLast = itemIsLast && idx === valueLen - 1;
|
|
26
|
+
let currentItem = itm;
|
|
27
|
+
Object.defineProperty(subArray, idx, {
|
|
28
|
+
get: () => currentItem,
|
|
29
|
+
set: (newValue) => {
|
|
30
|
+
currentItem = newValue;
|
|
31
|
+
if (subItemIsLast) notifyListeners();
|
|
32
|
+
},
|
|
33
|
+
enumerable: true
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
target[index] = subArray;
|
|
37
|
+
} else {
|
|
38
|
+
let currentValue = value;
|
|
39
|
+
const getter = () => currentValue;
|
|
40
|
+
const setter = (newVal) => {
|
|
41
|
+
currentValue = newVal;
|
|
42
|
+
if (itemIsLast) notifyListeners();
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperties(target, { [index]: {
|
|
45
|
+
get: getter,
|
|
46
|
+
set: setter,
|
|
47
|
+
enumerable: true
|
|
48
|
+
} });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function defineStateProxy(key, value, target) {
|
|
52
|
+
const [get, set] = createSignal(value);
|
|
53
|
+
let getter = get;
|
|
54
|
+
let setter;
|
|
55
|
+
if (isArray(value)) {
|
|
56
|
+
const arrayProxy = [];
|
|
57
|
+
const valLength = value.length;
|
|
58
|
+
const [version, setVersion] = createSignal(0);
|
|
59
|
+
for (let i = 0; i < valLength; i++) defineArrayProxy(i, value[i], arrayProxy, valLength, () => {
|
|
60
|
+
setVersion((v) => 1 - v);
|
|
61
|
+
});
|
|
62
|
+
getter = () => {
|
|
63
|
+
version();
|
|
64
|
+
return get();
|
|
65
|
+
};
|
|
66
|
+
set(arrayProxy);
|
|
67
|
+
} else {
|
|
68
|
+
setter = set;
|
|
69
|
+
set(value);
|
|
70
|
+
}
|
|
71
|
+
Object.defineProperties(target, {
|
|
72
|
+
[STATE_PROXY]: proxyProps,
|
|
73
|
+
[key]: {
|
|
74
|
+
get: getter,
|
|
75
|
+
set: setter,
|
|
76
|
+
enumerable: true
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function createMiniState(obj, parentReceiver) {
|
|
81
|
+
if (objectHasProp(obj, STATE_PROXY)) return obj;
|
|
82
|
+
for (const [key, value] of Object.entries(obj)) if (isPlainObject(value)) parentReceiver[key] = createMiniState(value, {});
|
|
83
|
+
else defineStateProxy(key, value, parentReceiver);
|
|
84
|
+
return parentReceiver;
|
|
85
|
+
}
|
|
86
|
+
function miniStore(init) {
|
|
87
|
+
return createMiniState(init, {});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/solid/index.ts
|
|
92
|
+
/**
|
|
93
|
+
* SolidJS primitive for updating values with Tween.
|
|
94
|
+
*
|
|
95
|
+
* @param initialValues - Initial tween values
|
|
96
|
+
* @returns [store, tween] Tuple of reactive store and Tween instance
|
|
97
|
+
* @example
|
|
98
|
+
* const App = () => {
|
|
99
|
+
* const [state, tween] = createTween({ x: 0, y: 0 })
|
|
100
|
+
*
|
|
101
|
+
* // configuration is free-form, no re-render ever happens
|
|
102
|
+
* tween.to({ x: 100, y: 100 })
|
|
103
|
+
*
|
|
104
|
+
* onMount(() => {
|
|
105
|
+
* tween.start()
|
|
106
|
+
* })
|
|
107
|
+
*
|
|
108
|
+
* return (
|
|
109
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
110
|
+
* );
|
|
111
|
+
* }
|
|
112
|
+
*/
|
|
113
|
+
function createTween(initialValues) {
|
|
114
|
+
if (isServer) return [initialValues, dummyInstance];
|
|
115
|
+
const store = miniStore(initialValues);
|
|
116
|
+
const tween = new Tween(store);
|
|
117
|
+
onCleanup(() => {
|
|
118
|
+
tween.stop();
|
|
119
|
+
tween.clear();
|
|
120
|
+
});
|
|
121
|
+
return [store, tween];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* SolidJS primitive for sequencing values update with Timeline.
|
|
125
|
+
*
|
|
126
|
+
* @param initialValues - Initial tween values
|
|
127
|
+
* @returns [store, timeline] Tuple of reactive store and Timeline instance
|
|
128
|
+
* @example
|
|
129
|
+
* const App = () => {
|
|
130
|
+
* const [state, timeline] = createTimeline({ x: 0, y: 0 })
|
|
131
|
+
*
|
|
132
|
+
* // configuration is free-form
|
|
133
|
+
* timeline.to({ x: 100, y: 100 })
|
|
134
|
+
*
|
|
135
|
+
* onMount(() => {
|
|
136
|
+
* timeline.start()
|
|
137
|
+
* })
|
|
138
|
+
*
|
|
139
|
+
* return (
|
|
140
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
141
|
+
* );
|
|
142
|
+
* }
|
|
143
|
+
*/
|
|
144
|
+
function createTimeline(initialValues) {
|
|
145
|
+
if (isServer) return [initialValues, dummyInstance];
|
|
146
|
+
const store = miniStore(initialValues);
|
|
147
|
+
const timeline = new Timeline(store);
|
|
148
|
+
onCleanup(() => {
|
|
149
|
+
timeline.stop();
|
|
150
|
+
timeline.clear();
|
|
151
|
+
});
|
|
152
|
+
return [store, timeline];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
export { Timeline, Tween, createTimeline, createTween, miniStore };
|
|
157
|
+
//# sourceMappingURL=solid.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solid.mjs","names":[],"sources":["../../src/solid/miniStore.ts","../../src/solid/index.ts"],"sourcesContent":["import { createSignal } from \"solid-js\";\nimport {\n type ArrayVal,\n isArray,\n isPlainObject,\n objectHasProp,\n type TweenProps,\n} from \"@thednp/tween\";\n\nconst STATE_PROXY = \"_proxy\";\nconst proxyProps = {\n value: 1,\n enumerable: false,\n configurable: false,\n writable: false,\n};\n\nfunction defineArrayProxy<T extends ArrayVal>(\n index: number,\n value: T[number] | ArrayVal,\n target: T | ArrayVal | ArrayVal[],\n sourceLen: number,\n notifyListeners: () => void,\n) {\n const itemIsLast = index === sourceLen - 1;\n\n if (isArray(value)) {\n const subArray: typeof value = [];\n const valueLen = value.length;\n\n value.forEach((itm, idx) => {\n const subItemIsLast = itemIsLast && idx === valueLen - 1;\n\n let currentItem = itm;\n Object.defineProperty(subArray, idx, {\n get: () => currentItem,\n set: (newValue: typeof itm) => {\n currentItem = newValue;\n\n // Only notify on last element to batch updates\n if (subItemIsLast) {\n notifyListeners();\n }\n },\n enumerable: true,\n });\n });\n target[index] = subArray;\n } else {\n let currentValue = value;\n const getter = () => currentValue;\n const setter = (newVal: typeof value) => {\n currentValue = newVal;\n if (itemIsLast) {\n notifyListeners();\n }\n };\n Object.defineProperties(target, {\n [index]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n }\n}\n\nfunction defineStateProxy<T extends Omit<TweenProps, \"_proxy\">>(\n key: number | keyof T,\n value: T[keyof T] | ArrayVal,\n target: T | ArrayVal,\n) {\n const [get, set] = createSignal(value);\n let getter = get;\n let setter;\n\n if (isArray(value)) {\n const arrayProxy: typeof value = [];\n const valLength = value.length;\n const [version, setVersion] = createSignal(0);\n for (let i = 0; i < valLength; i++) {\n defineArrayProxy(i, (value as ArrayVal)[i], arrayProxy, valLength, () => {\n setVersion((v) => 1 - v);\n });\n }\n getter = () => {\n version();\n return get();\n };\n\n set(arrayProxy);\n } else {\n setter = set;\n set(value as never);\n }\n\n Object.defineProperties(target, {\n [STATE_PROXY]: proxyProps,\n [key]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n}\n\nfunction createMiniState<T extends TweenProps>(\n obj: T,\n parentReceiver: TweenProps | number[] | [string, ...number[]][],\n) {\n if (objectHasProp(obj, STATE_PROXY)) return obj;\n\n for (const [key, value] of Object.entries(obj)) {\n if (isPlainObject(value)) {\n (parentReceiver as TweenProps)[key] = createMiniState(value, {});\n } else {\n defineStateProxy(key, value, parentReceiver);\n }\n }\n\n return parentReceiver as T;\n}\n\nexport function miniStore<T extends TweenProps>(init: T) {\n return createMiniState(init, {}) as T;\n}\n","import {\n dummyInstance,\n isServer,\n Timeline,\n Tween,\n type TweenProps,\n} from \"@thednp/tween\";\nimport { onCleanup } from \"solid-js\";\nimport { miniStore } from \"./miniStore.ts\";\n\nexport { miniStore, Timeline, Tween };\n\n/**\n * SolidJS primitive for updating values with Tween.\n *\n * @param initialValues - Initial tween values\n * @returns [store, tween] Tuple of reactive store and Tween instance\n * @example\n * const App = () => {\n * const [state, tween] = createTween({ x: 0, y: 0 })\n *\n * // configuration is free-form, no re-render ever happens\n * tween.to({ x: 100, y: 100 })\n *\n * onMount(() => {\n * tween.start()\n * })\n *\n * return (\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n * );\n * }\n */\nexport function createTween<T extends TweenProps>(initialValues: T) {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Tween<T>] as const;\n }\n const store = miniStore(initialValues);\n const tween = new Tween(store);\n\n onCleanup(() => {\n tween.stop();\n tween.clear();\n });\n\n return [store, tween] as [T, Tween<T>];\n}\n\n/**\n * SolidJS primitive for sequencing values update with Timeline.\n *\n * @param initialValues - Initial tween values\n * @returns [store, timeline] Tuple of reactive store and Timeline instance\n * @example\n * const App = () => {\n * const [state, timeline] = createTimeline({ x: 0, y: 0 })\n *\n * // configuration is free-form\n * timeline.to({ x: 100, y: 100 })\n *\n * onMount(() => {\n * timeline.start()\n * })\n *\n * return (\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n * );\n * }\n */\nexport function createTimeline<T extends TweenProps>(initialValues: T) {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Timeline<T>] as const;\n }\n const store = miniStore(initialValues);\n const timeline = new Timeline(store);\n\n onCleanup(() => {\n timeline.stop();\n timeline.clear();\n });\n\n return [store, timeline] as [T, Timeline<T>];\n}\n"],"mappings":";;;;;;;;;;;AASA,MAAM,cAAc;AACpB,MAAM,aAAa;CACjB,OAAO;CACP,YAAY;CACZ,cAAc;CACd,UAAU;CACX;AAED,SAAS,iBACP,OACA,OACA,QACA,WACA,iBACA;CACA,MAAM,aAAa,UAAU,YAAY;AAEzC,KAAI,QAAQ,MAAM,EAAE;EAClB,MAAM,WAAyB,EAAE;EACjC,MAAM,WAAW,MAAM;AAEvB,QAAM,SAAS,KAAK,QAAQ;GAC1B,MAAM,gBAAgB,cAAc,QAAQ,WAAW;GAEvD,IAAI,cAAc;AAClB,UAAO,eAAe,UAAU,KAAK;IACnC,WAAW;IACX,MAAM,aAAyB;AAC7B,mBAAc;AAGd,SAAI,cACF,kBAAiB;;IAGrB,YAAY;IACb,CAAC;IACF;AACF,SAAO,SAAS;QACX;EACL,IAAI,eAAe;EACnB,MAAM,eAAe;EACrB,MAAM,UAAU,WAAyB;AACvC,kBAAe;AACf,OAAI,WACF,kBAAiB;;AAGrB,SAAO,iBAAiB,QAAQ,GAC7B,QAAQ;GACP,KAAK;GACL,KAAK;GACL,YAAY;GACb,EACF,CAAC;;;AAIN,SAAS,iBACP,KACA,OACA,QACA;CACA,MAAM,CAAC,KAAK,OAAO,aAAa,MAAM;CACtC,IAAI,SAAS;CACb,IAAI;AAEJ,KAAI,QAAQ,MAAM,EAAE;EAClB,MAAM,aAA2B,EAAE;EACnC,MAAM,YAAY,MAAM;EACxB,MAAM,CAAC,SAAS,cAAc,aAAa,EAAE;AAC7C,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,IAC7B,kBAAiB,GAAI,MAAmB,IAAI,YAAY,iBAAiB;AACvE,eAAY,MAAM,IAAI,EAAE;IACxB;AAEJ,iBAAe;AACb,YAAS;AACT,UAAO,KAAK;;AAGd,MAAI,WAAW;QACV;AACL,WAAS;AACT,MAAI,MAAe;;AAGrB,QAAO,iBAAiB,QAAQ;GAC7B,cAAc;GACd,MAAM;GACL,KAAK;GACL,KAAK;GACL,YAAY;GACb;EACF,CAAC;;AAGJ,SAAS,gBACP,KACA,gBACA;AACA,KAAI,cAAc,KAAK,YAAY,CAAE,QAAO;AAE5C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,CAC5C,KAAI,cAAc,MAAM,CACtB,CAAC,eAA8B,OAAO,gBAAgB,OAAO,EAAE,CAAC;KAEhE,kBAAiB,KAAK,OAAO,eAAe;AAIhD,QAAO;;AAGT,SAAgB,UAAgC,MAAS;AACvD,QAAO,gBAAgB,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AC3FlC,SAAgB,YAAkC,eAAkB;AAClE,KAAI,SACF,QAAO,CAAC,eAAe,cAAqC;CAE9D,MAAM,QAAQ,UAAU,cAAc;CACtC,MAAM,QAAQ,IAAI,MAAM,MAAM;AAE9B,iBAAgB;AACd,QAAM,MAAM;AACZ,QAAM,OAAO;GACb;AAEF,QAAO,CAAC,OAAO,MAAM;;;;;;;;;;;;;;;;;;;;;;;AAwBvB,SAAgB,eAAqC,eAAkB;AACrE,KAAI,SACF,QAAO,CAAC,eAAe,cAAwC;CAEjE,MAAM,QAAQ,UAAU,cAAc;CACtC,MAAM,WAAW,IAAI,SAAS,MAAM;AAEpC,iBAAgB;AACd,WAAS,MAAM;AACf,WAAS,OAAO;GAChB;AAEF,QAAO,CAAC,OAAO,SAAS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.d.mts","names":[],"sources":["../../src/svelte/miniStore.svelte.ts","../../src/svelte/index.svelte.ts"],"mappings":";;;;;;;;;;iBA2HgB,SAAA,WAAoB,UAAA,CAAA,CAAY,IAAA,EAAM,CAAA,GAChB,CAAA;;;AADtC;;;;;;;;;;;;;;;;;;AC3FA;;AD2FA,iBC3FgB,WAAA,WAAsB,UAAA,CAAA,CAAY,aAAA,EAAe,CAAA,aAAC,CAAA,EAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;AAmClE;;;;iBAAgB,cAAA,WAAyB,UAAA,CAAA,CAAY,aAAA,EAAe,CAAA,aAAC,CAAA,EAAA,QAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.mjs","names":[],"sources":["../../src/svelte/miniStore.svelte.ts","../../src/svelte/index.svelte.ts"],"sourcesContent":["import {\n type ArrayVal,\n isArray,\n isPlainObject,\n objectHasProp,\n type TweenProps,\n} from \"@thednp/tween\";\n\nconst STATE_PROXY = \"_proxy\";\nconst proxyProps = {\n value: 1,\n enumerable: false,\n configurable: false,\n writable: false,\n};\n\nfunction defineArrayProxy<T extends ArrayVal>(\n index: number,\n value: T[number] | ArrayVal,\n target: T | ArrayVal | ArrayVal[],\n sourceLen: number,\n notifyListeners: () => void,\n) {\n const itemIsLast = index === sourceLen - 1;\n\n if (isArray(value)) {\n const subArray: typeof value = [];\n const valueLen = value.length;\n\n value.forEach((itm, idx) => {\n const subItemIsLast = itemIsLast && idx === valueLen - 1;\n let currentItem = itm;\n\n Object.defineProperty(subArray, idx, {\n get: () => currentItem,\n set: (newValue: typeof itm) => {\n currentItem = newValue;\n\n // Only notify on last element to batch updates\n if (subItemIsLast) {\n notifyListeners();\n }\n },\n enumerable: true,\n });\n });\n target[index] = subArray;\n } else {\n let currentValue = value;\n const getter = () => currentValue;\n const setter = (newVal: typeof value) => {\n currentValue = newVal;\n if (itemIsLast) {\n notifyListeners();\n }\n };\n Object.defineProperties(target, {\n [index]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n }\n}\n\nfunction defineStateProxy<T extends Omit<TweenProps, \"_proxy\">>(\n key: number | keyof T,\n value: T[keyof T] | ArrayVal,\n target: T | ArrayVal,\n) {\n let state = $state.raw(value);\n let getter = () => state;\n let setter;\n\n if (isArray(value)) {\n const arrayProxy: typeof value = [];\n const valLength = value.length;\n let version = $state.raw(0);\n const getVersion = () => version;\n for (let i = 0; i < valLength; i++) {\n defineArrayProxy(i, (value as ArrayVal)[i], arrayProxy, valLength, () => {\n version = 1 - version;\n });\n }\n getter = () => {\n getVersion();\n return state;\n };\n\n state = arrayProxy;\n } else {\n setter = (newVal: typeof value) => state = newVal;\n state = value;\n }\n\n Object.defineProperties(target, {\n [STATE_PROXY]: proxyProps,\n [key]: {\n get: getter,\n set: setter,\n enumerable: true,\n },\n });\n}\n\nfunction createMiniState<T extends TweenProps>(\n obj: T,\n parentReceiver: TweenProps | number[] | [string, ...number[]][],\n) {\n if (objectHasProp(obj, STATE_PROXY)) return obj;\n\n for (const [key, value] of Object.entries(obj)) {\n if (isPlainObject(value)) {\n (parentReceiver as TweenProps)[key] = createMiniState(value, {});\n } else {\n defineStateProxy(key, value, parentReceiver);\n }\n }\n\n return parentReceiver as T;\n}\n\nexport function miniStore<T extends TweenProps>(init: T) {\n return createMiniState(init, {}) as T;\n}\n","import {\n dummyInstance,\n isServer,\n Timeline,\n Tween,\n type TweenProps,\n} from \"@thednp/tween\";\nimport { onDestroy } from \"svelte\";\nimport { miniStore } from \"./miniStore.svelte.ts\";\n\nexport { miniStore, Timeline, Tween };\n\n/**\n * Svelte hook for updating values with Tween.\n *\n * @param initialValues - Initial tween values\n * @returns [store, tween] Tuple of reactive store and Tween instance\n *\n * @example\n * <script lang=\"ts\">\n * const [state, tween] = createTween({ x: 0, y: 0 })\n *\n * // configuration is free-form, no re-render ever happens\n * tween.to({ x: 100, y: 100 })\n *\n * onMount(() => {\n * tween.start()\n * })\n * </script>\n *\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n */\nexport function createTween<T extends TweenProps>(initialValues: T) {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Tween<T>] as const;\n }\n const store = miniStore(initialValues);\n const tween = new Tween(store);\n\n onDestroy(() => {\n tween.stop();\n tween.clear();\n });\n\n return [store, tween] as [T, Tween<T>];\n}\n\n/**\n * Svelte hook for sequencing values update with Timeline.\n *\n * @param initialValues - Initial tween values\n * @returns [store, timeline] Tuple of reactive store and Timeline instance\n *\n * @example\n * <script lang=\"ts\">\n * const [state, timeline] = createTimeline({ x: 0, y: 0 })\n *\n * // configuration is free-form\n * timeline.to({ x: 100, y: 100 })\n *\n * onMount(() => {\n * timeline.start()\n * })\n * </script>\n *\n * <div style={{ translate: `${state.x}px ${state.y}px` }} />\n */\nexport function createTimeline<T extends TweenProps>(initialValues: T) {\n if (isServer) {\n return [initialValues, dummyInstance as unknown as Timeline<T>] as const;\n }\n const store = miniStore(initialValues);\n const timeline = new Timeline(store);\n\n onDestroy(() => {\n timeline.stop();\n timeline.clear();\n });\n\n return [store, timeline] as [T, Timeline<T>];\n}\n"],"mappings":";;;;;;;;;;;AAQA,MAAM,cAAc;AACpB,MAAM,aAAa;CACjB,OAAO;CACP,YAAY;CACZ,cAAc;CACd,UAAU;CACX;AAED,SAAS,iBACP,OACA,OACA,QACA,WACA,iBACA;CACA,MAAM,aAAa,UAAU,YAAY;AAEzC,KAAI,QAAQ,MAAM,EAAE;EAClB,MAAM,WAAyB,EAAE;EACjC,MAAM,WAAW,MAAM;AAEvB,QAAM,SAAS,KAAK,QAAQ;GAC1B,MAAM,gBAAgB,cAAc,QAAQ,WAAW;GACvD,IAAI,cAAc;AAElB,UAAO,eAAe,UAAU,KAAK;IACnC,WAAW;IACX,MAAM,aAAyB;AAC7B,mBAAc;AAGd,SAAI,cACF,kBAAiB;;IAGrB,YAAY;IACb,CAAC;IACF;AACF,SAAO,SAAS;QACX;EACL,IAAI,eAAe;EACnB,MAAM,eAAe;EACrB,MAAM,UAAU,WAAyB;AACvC,kBAAe;AACf,OAAI,WACF,kBAAiB;;AAGrB,SAAO,iBAAiB,QAAQ,GAC7B,QAAQ;GACP,KAAK;GACL,KAAK;GACL,YAAY;GACb,EACF,CAAC;;;AAIN,SAAS,iBACP,KACA,OACA,QACA;CACA,IAAI,QAAQ,OAAO,IAAI,MAAM;CAC7B,IAAI,eAAe;CACnB,IAAI;AAEJ,KAAI,QAAQ,MAAM,EAAE;EAClB,MAAM,aAA2B,EAAE;EACnC,MAAM,YAAY,MAAM;EACxB,IAAI,UAAU,OAAO,IAAI,EAAE;EAC3B,MAAM,mBAAmB;AACzB,OAAK,IAAI,IAAI,GAAG,IAAI,WAAW,IAC7B,kBAAiB,GAAI,MAAmB,IAAI,YAAY,iBAAiB;AACvE,aAAU,IAAI;IACd;AAEJ,iBAAe;AACb,eAAY;AACZ,UAAO;;AAGT,UAAQ;QACH;AACL,YAAU,WAAyB,QAAQ;AAC3C,UAAQ;;AAGV,QAAO,iBAAiB,QAAQ;GAC7B,cAAc;GACd,MAAM;GACL,KAAK;GACL,KAAK;GACL,YAAY;GACb;EACF,CAAC;;AAGJ,SAAS,gBACP,KACA,gBACA;AACA,KAAI,cAAc,KAAK,YAAY,CAAE,QAAO;AAE5C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,CAC5C,KAAI,cAAc,MAAM,CACtB,CAAC,eAA8B,OAAO,gBAAgB,OAAO,EAAE,CAAC;KAEhE,kBAAiB,KAAK,OAAO,eAAe;AAIhD,QAAO;;AAGT,SAAgB,UAAgC,MAAS;AACvD,QAAO,gBAAgB,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AC5FlC,SAAgB,YAAkC,eAAkB;AAClE,KAAI,SACF,QAAO,CAAC,eAAe,cAAqC;CAE9D,MAAM,QAAQ,UAAU,cAAc;CACtC,MAAM,QAAQ,IAAI,MAAM,MAAM;AAE9B,iBAAgB;AACd,QAAM,MAAM;AACZ,QAAM,OAAO;GACb;AAEF,QAAO,CAAC,OAAO,MAAM;;;;;;;;;;;;;;;;;;;;;;AAuBvB,SAAgB,eAAqC,eAAkB;AACrE,KAAI,SACF,QAAO,CAAC,eAAe,cAAwC;CAEjE,MAAM,QAAQ,UAAU,cAAc;CACtC,MAAM,WAAW,IAAI,SAAS,MAAM;AAEpC,iBAAgB;AACd,WAAS,MAAM;AACf,WAAS,OAAO;GAChB;AAEF,QAAO,CAAC,OAAO,SAAS"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @thednp/tween utils for Svelte v0.0.2 (https://github.com/thednp/tween)
|
|
3
|
+
* Copyright 2026 © thednp
|
|
4
|
+
* Licensed under MIT (https://github.com/thednp/tween/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
import { Timeline, Tween, TweenProps } from "@thednp/tween";
|
|
9
|
+
|
|
10
|
+
//#region src/svelte/miniStore.svelte.d.ts
|
|
11
|
+
declare function miniStore<T extends TweenProps>(init: T): T;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/svelte/index.svelte.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Svelte hook for updating values with Tween.
|
|
16
|
+
*
|
|
17
|
+
* @param initialValues - Initial tween values
|
|
18
|
+
* @returns [store, tween] Tuple of reactive store and Tween instance
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* <script lang="ts">
|
|
22
|
+
* const [state, tween] = createTween({ x: 0, y: 0 })
|
|
23
|
+
*
|
|
24
|
+
* // configuration is free-form, no re-render ever happens
|
|
25
|
+
* tween.to({ x: 100, y: 100 })
|
|
26
|
+
*
|
|
27
|
+
* onMount(() => {
|
|
28
|
+
* tween.start()
|
|
29
|
+
* })
|
|
30
|
+
* </script>
|
|
31
|
+
*
|
|
32
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
33
|
+
*/
|
|
34
|
+
declare function createTween<T extends TweenProps>(initialValues: T): readonly [T, Tween<T>];
|
|
35
|
+
/**
|
|
36
|
+
* Svelte hook for sequencing values update with Timeline.
|
|
37
|
+
*
|
|
38
|
+
* @param initialValues - Initial tween values
|
|
39
|
+
* @returns [store, timeline] Tuple of reactive store and Timeline instance
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* <script lang="ts">
|
|
43
|
+
* const [state, timeline] = createTimeline({ x: 0, y: 0 })
|
|
44
|
+
*
|
|
45
|
+
* // configuration is free-form
|
|
46
|
+
* timeline.to({ x: 100, y: 100 })
|
|
47
|
+
*
|
|
48
|
+
* onMount(() => {
|
|
49
|
+
* timeline.start()
|
|
50
|
+
* })
|
|
51
|
+
* </script>
|
|
52
|
+
*
|
|
53
|
+
* <div style={{ translate: `${state.x}px ${state.y}px` }} />
|
|
54
|
+
*/
|
|
55
|
+
declare function createTimeline<T extends TweenProps>(initialValues: T): readonly [T, Timeline<T>];
|
|
56
|
+
//#endregion
|
|
57
|
+
export { Timeline, Tween, createTimeline, createTween, miniStore };
|
|
58
|
+
//# sourceMappingURL=svelte.d.mts.map
|