canvasengine 2.0.0-beta.6 → 2.0.0-beta.8
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/index.d.ts +37 -9
- package/dist/index.js +106 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DisplayObject.ts +3 -3
- package/src/components/Text.ts +2 -2
- package/src/engine/animation.ts +41 -5
- package/src/engine/reactive.ts +99 -23
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _signe_reactive from '@signe/reactive';
|
|
2
|
-
import { WritableSignal, Signal, WritableArraySignal } from '@signe/reactive';
|
|
2
|
+
import { WritableSignal, Signal, WritableArraySignal, WritableObjectSignal } from '@signe/reactive';
|
|
3
3
|
export * from '@signe/reactive';
|
|
4
4
|
import { Subscription, Subject, Observable } from 'rxjs';
|
|
5
5
|
export { isObservable } from 'rxjs';
|
|
@@ -13,6 +13,7 @@ interface AnimateOptions<T> {
|
|
|
13
13
|
duration?: number;
|
|
14
14
|
ease?: (t: number) => number;
|
|
15
15
|
onUpdate?: (value: T) => void;
|
|
16
|
+
onComplete?: () => void;
|
|
16
17
|
}
|
|
17
18
|
interface AnimatedState<T> {
|
|
18
19
|
current: T;
|
|
@@ -21,7 +22,7 @@ interface AnimatedState<T> {
|
|
|
21
22
|
}
|
|
22
23
|
interface AnimatedSignal<T> extends Omit<WritableSignal<T>, 'set'> {
|
|
23
24
|
(): T;
|
|
24
|
-
set: (newValue: T) => void
|
|
25
|
+
set: (newValue: T, options?: AnimateOptions<T>) => Promise<void>;
|
|
25
26
|
animatedState: WritableSignal<AnimatedState<T>>;
|
|
26
27
|
update: (updater: (value: T) => T) => void;
|
|
27
28
|
}
|
|
@@ -45,6 +46,25 @@ declare function isAnimatedSignal(signal: WritableSignal<any>): boolean;
|
|
|
45
46
|
* animatedValue.animatedState() // { current: 10, start: 10, end: 11 }
|
|
46
47
|
*/
|
|
47
48
|
declare function animatedSignal<T>(initialValue: T, options?: AnimateOptions<T>): AnimatedSignal<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Executes a sequence of animations. If an array is provided as an element in the sequence,
|
|
51
|
+
* those animations will be executed in parallel.
|
|
52
|
+
*
|
|
53
|
+
* @param sequence Array of animation functions or arrays of animation functions for parallel execution
|
|
54
|
+
* @returns Promise that resolves when all animations are complete
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* await animatedSequence([
|
|
58
|
+
* () => value1.set(10),
|
|
59
|
+
* [
|
|
60
|
+
* () => value2.set(20),
|
|
61
|
+
* () => value3.set(30)
|
|
62
|
+
* ],
|
|
63
|
+
* () => value1.set(0)
|
|
64
|
+
* ])
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function animatedSequence(sequence: ((() => Promise<void>) | (() => Promise<void>)[])[]): Promise<void>;
|
|
48
68
|
|
|
49
69
|
type SignalOrPrimitive<T> = T | Signal<T> | AnimatedSignal<T>;
|
|
50
70
|
|
|
@@ -157,7 +177,7 @@ declare function DisplayObject(extendClass: any): {
|
|
|
157
177
|
onInit(props: any): void;
|
|
158
178
|
onMount({ parent, props }: Element</*elided*/ any>, index?: number): void;
|
|
159
179
|
effectSize(width: Size, height: Size): void;
|
|
160
|
-
|
|
180
|
+
applyFlexLayout(): void;
|
|
161
181
|
"__#1@#flexRender"(props: any): void;
|
|
162
182
|
onUpdate(props: any): void;
|
|
163
183
|
onDestroy(): void;
|
|
@@ -204,6 +224,12 @@ type ArrayChange<T> = {
|
|
|
204
224
|
index?: number;
|
|
205
225
|
items: T[];
|
|
206
226
|
};
|
|
227
|
+
type ObjectChange<T> = {
|
|
228
|
+
type: "add" | "remove" | "update" | "init" | "reset";
|
|
229
|
+
key?: string;
|
|
230
|
+
value?: T;
|
|
231
|
+
items: T[];
|
|
232
|
+
};
|
|
207
233
|
type NestedSignalObjects = {
|
|
208
234
|
[Key in string]: NestedSignalObjects | Signal<any>;
|
|
209
235
|
};
|
|
@@ -226,10 +252,12 @@ interface Element<T = ComponentInstance> {
|
|
|
226
252
|
destroy: () => void;
|
|
227
253
|
allElements: Subject<void>;
|
|
228
254
|
}
|
|
229
|
-
type
|
|
255
|
+
type FlowResult = {
|
|
230
256
|
elements: Element[];
|
|
231
257
|
prev?: Element;
|
|
232
|
-
|
|
258
|
+
fullElements?: Element[];
|
|
259
|
+
};
|
|
260
|
+
type FlowObservable = Observable<FlowResult>;
|
|
233
261
|
declare const isElement: (value: any) => value is Element;
|
|
234
262
|
declare const isPrimitive: (value: any) => boolean;
|
|
235
263
|
declare function registerComponent(name: any, component: any): void;
|
|
@@ -245,13 +273,13 @@ declare function registerComponent(name: any, component: any): void;
|
|
|
245
273
|
*/
|
|
246
274
|
declare function createComponent(tag: string, props?: Props): Element;
|
|
247
275
|
/**
|
|
248
|
-
* Observes a BehaviorSubject containing an array of items and dynamically creates child elements for each item.
|
|
276
|
+
* Observes a BehaviorSubject containing an array or object of items and dynamically creates child elements for each item.
|
|
249
277
|
*
|
|
250
|
-
* @param {
|
|
278
|
+
* @param {WritableArraySignal<T> | WritableObjectSignal<T>} itemsSubject - A signal that emits an array or object of items.
|
|
251
279
|
* @param {Function} createElementFn - A function that takes an item and returns an element representation.
|
|
252
280
|
* @returns {Observable} An observable that emits the list of created child elements.
|
|
253
281
|
*/
|
|
254
|
-
declare function loop<T
|
|
282
|
+
declare function loop<T>(itemsSubject: WritableArraySignal<T[]> | WritableObjectSignal<T>, createElementFn: (item: T, index: number | string) => Element | null): FlowObservable;
|
|
255
283
|
/**
|
|
256
284
|
* Conditionally creates and destroys elements based on a condition signal.
|
|
257
285
|
*
|
|
@@ -1106,4 +1134,4 @@ declare namespace utils {
|
|
|
1106
1134
|
export { utils_arrayEquals as arrayEquals, utils_calculateDistance as calculateDistance, utils_error as error, utils_fps2ms as fps2ms, utils_get as get, utils_isBrowser as isBrowser, utils_isFunction as isFunction, utils_isObject as isObject, utils_isPromise as isPromise, utils_log as log, utils_preciseNow as preciseNow, utils_set as set, utils_setObservablePoint as setObservablePoint };
|
|
1107
1135
|
}
|
|
1108
1136
|
|
|
1109
|
-
export { type AnimatedSignal, type AnimatedState, type ArrayChange, Canvas, Circle, type ComponentFunction, type ComponentInstance, Container, DisplayObject, EVENTS, Easing, type Element, Ellipse, Graphics, NineSliceSprite, ParticlesEmitter, type Props, RadialGradient, Rect, Scene, Sprite, Text, TilingSprite, Triangle, utils as Utils, Video, Viewport, animatedSignal, bootstrapCanvas, cond, createComponent, currentSubscriptionsTracker, h, isAnimatedSignal, isElement, isPrimitive, isTrigger, loop, mount, mountTracker, on, registerComponent, Svg as svg, tick, trigger, useDefineProps, useProps };
|
|
1137
|
+
export { type AnimateOptions, type AnimatedSignal, type AnimatedState, type ArrayChange, Canvas, Circle, type ComponentFunction, type ComponentInstance, Container, DisplayObject, EVENTS, Easing, type Element, Ellipse, Graphics, NineSliceSprite, type ObjectChange, ParticlesEmitter, type Props, RadialGradient, Rect, Scene, Sprite, Text, TilingSprite, Triangle, utils as Utils, Video, Viewport, animatedSequence, animatedSignal, bootstrapCanvas, cond, createComponent, currentSubscriptionsTracker, h, isAnimatedSignal, isElement, isPrimitive, isTrigger, loop, mount, mountTracker, on, registerComponent, Svg as svg, tick, trigger, useDefineProps, useProps };
|
package/dist/index.js
CHANGED
|
@@ -1307,19 +1307,42 @@ function createComponent(tag, props) {
|
|
|
1307
1307
|
}
|
|
1308
1308
|
function loop(itemsSubject, createElementFn) {
|
|
1309
1309
|
let elements = [];
|
|
1310
|
-
const
|
|
1310
|
+
const isArraySignal = "_subject" in itemsSubject && "items" in itemsSubject._subject;
|
|
1311
|
+
const addAt = (items, insertIndex, keys) => {
|
|
1311
1312
|
return items.map((item, index) => {
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1313
|
+
const key = keys ? keys[index] : typeof insertIndex === "number" ? insertIndex + index : insertIndex;
|
|
1314
|
+
const element = createElementFn(item, key);
|
|
1315
|
+
if (typeof insertIndex === "number") {
|
|
1316
|
+
elements.splice(insertIndex + index, 0, element);
|
|
1317
|
+
} else {
|
|
1318
|
+
elements.push(element);
|
|
1319
|
+
}
|
|
1314
1320
|
return element;
|
|
1315
1321
|
});
|
|
1316
1322
|
};
|
|
1323
|
+
const getInitialItems = () => {
|
|
1324
|
+
if (isArraySignal) {
|
|
1325
|
+
return {
|
|
1326
|
+
items: itemsSubject._subject.items,
|
|
1327
|
+
keys: void 0
|
|
1328
|
+
};
|
|
1329
|
+
} else {
|
|
1330
|
+
const entries = Object.entries(itemsSubject._subject.value.value);
|
|
1331
|
+
return {
|
|
1332
|
+
items: entries.map(([_, value]) => value),
|
|
1333
|
+
keys: entries.map(([key]) => key)
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1317
1337
|
return defer(() => {
|
|
1318
|
-
|
|
1338
|
+
const { items, keys } = getInitialItems();
|
|
1339
|
+
let initialItems = [...items];
|
|
1340
|
+
let initialKeys = keys ? [...keys] : void 0;
|
|
1319
1341
|
let init = true;
|
|
1320
1342
|
return itemsSubject.observable.pipe(
|
|
1321
1343
|
map((event) => {
|
|
1322
|
-
const { type, items
|
|
1344
|
+
const { type, items: items2 } = event;
|
|
1345
|
+
const index = "index" in event ? event.index : event.key;
|
|
1323
1346
|
if (init) {
|
|
1324
1347
|
if (elements.length > 0) {
|
|
1325
1348
|
return {
|
|
@@ -1327,8 +1350,9 @@ function loop(itemsSubject, createElementFn) {
|
|
|
1327
1350
|
fullElements: elements
|
|
1328
1351
|
};
|
|
1329
1352
|
}
|
|
1330
|
-
const newElements = addAt(initialItems, 0);
|
|
1353
|
+
const newElements = addAt(initialItems, 0, initialKeys);
|
|
1331
1354
|
initialItems = [];
|
|
1355
|
+
initialKeys = void 0;
|
|
1332
1356
|
init = false;
|
|
1333
1357
|
return {
|
|
1334
1358
|
elements: newElements,
|
|
@@ -1341,25 +1365,60 @@ function loop(itemsSubject, createElementFn) {
|
|
|
1341
1365
|
});
|
|
1342
1366
|
elements = [];
|
|
1343
1367
|
}
|
|
1344
|
-
|
|
1368
|
+
if (!isArraySignal) {
|
|
1369
|
+
const entries = Object.entries(itemsSubject._subject.value.value);
|
|
1370
|
+
const newElements2 = addAt(
|
|
1371
|
+
entries.map(([_, value]) => value),
|
|
1372
|
+
0,
|
|
1373
|
+
entries.map(([key]) => key)
|
|
1374
|
+
);
|
|
1375
|
+
return {
|
|
1376
|
+
elements: newElements2,
|
|
1377
|
+
fullElements: elements
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
const newElements = addAt(items2, 0);
|
|
1345
1381
|
return {
|
|
1346
1382
|
elements: newElements,
|
|
1347
1383
|
fullElements: elements
|
|
1348
1384
|
};
|
|
1349
1385
|
} else if (type == "add" && index != void 0) {
|
|
1350
|
-
const lastElement = elements[index - 1];
|
|
1351
|
-
|
|
1386
|
+
const lastElement = typeof index === "number" ? elements[index - 1] : elements[elements.length - 1];
|
|
1387
|
+
let newElements;
|
|
1388
|
+
if (!isArraySignal && typeof index === "string") {
|
|
1389
|
+
const value = event.value;
|
|
1390
|
+
if (value !== void 0) {
|
|
1391
|
+
newElements = [createElementFn(value, index)];
|
|
1392
|
+
elements.push(newElements[0]);
|
|
1393
|
+
} else {
|
|
1394
|
+
newElements = [];
|
|
1395
|
+
}
|
|
1396
|
+
} else {
|
|
1397
|
+
newElements = addAt(items2, index);
|
|
1398
|
+
}
|
|
1352
1399
|
return {
|
|
1353
1400
|
prev: lastElement,
|
|
1354
1401
|
elements: newElements,
|
|
1355
1402
|
fullElements: elements
|
|
1356
1403
|
};
|
|
1357
|
-
} else if (
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1404
|
+
} else if (type == "remove") {
|
|
1405
|
+
if (!isArraySignal && typeof index === "string") {
|
|
1406
|
+
const elementIndex = elements.findIndex((el) => {
|
|
1407
|
+
return el.props.text === index || el.props.key === index;
|
|
1408
|
+
});
|
|
1409
|
+
if (elementIndex !== -1) {
|
|
1410
|
+
const currentElement = elements[elementIndex];
|
|
1411
|
+
destroyElement(currentElement);
|
|
1412
|
+
elements.splice(elementIndex, 1);
|
|
1413
|
+
}
|
|
1414
|
+
} else if (typeof index === "number") {
|
|
1415
|
+
const currentElement = elements[index];
|
|
1416
|
+
destroyElement(currentElement);
|
|
1417
|
+
elements.splice(index, 1);
|
|
1418
|
+
}
|
|
1361
1419
|
return {
|
|
1362
|
-
elements: []
|
|
1420
|
+
elements: [],
|
|
1421
|
+
fullElements: elements
|
|
1363
1422
|
};
|
|
1364
1423
|
}
|
|
1365
1424
|
return {
|
|
@@ -1579,7 +1638,7 @@ var EVENTS2 = [
|
|
|
1579
1638
|
"wheelcapture"
|
|
1580
1639
|
];
|
|
1581
1640
|
function DisplayObject(extendClass) {
|
|
1582
|
-
var _canvasContext, _DisplayObject_instances,
|
|
1641
|
+
var _canvasContext, _DisplayObject_instances, flexRender_fn, setAlign_fn, setEdgeSize_fn, _a;
|
|
1583
1642
|
return _a = class extends extendClass {
|
|
1584
1643
|
constructor() {
|
|
1585
1644
|
super(...arguments);
|
|
@@ -1648,7 +1707,7 @@ function DisplayObject(extendClass) {
|
|
|
1648
1707
|
effect3(() => {
|
|
1649
1708
|
setter(parentSize() * (parseInt(size) / 100));
|
|
1650
1709
|
if (this.isFlex) {
|
|
1651
|
-
|
|
1710
|
+
this.applyFlexLayout();
|
|
1652
1711
|
}
|
|
1653
1712
|
});
|
|
1654
1713
|
} else {
|
|
@@ -1664,6 +1723,14 @@ function DisplayObject(extendClass) {
|
|
|
1664
1723
|
this.parent.displayHeight
|
|
1665
1724
|
);
|
|
1666
1725
|
}
|
|
1726
|
+
applyFlexLayout() {
|
|
1727
|
+
this.calculateLayout();
|
|
1728
|
+
for (let child of this.children) {
|
|
1729
|
+
const { left, top } = child.node.getComputedLayout();
|
|
1730
|
+
child.x = left;
|
|
1731
|
+
child.y = top;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1667
1734
|
onUpdate(props) {
|
|
1668
1735
|
this.fullProps = {
|
|
1669
1736
|
...this.fullProps,
|
|
@@ -1841,18 +1908,11 @@ function DisplayObject(extendClass) {
|
|
|
1841
1908
|
getHeight() {
|
|
1842
1909
|
return this.displayHeight();
|
|
1843
1910
|
}
|
|
1844
|
-
}, _canvasContext = new WeakMap(), _DisplayObject_instances = new WeakSet(),
|
|
1845
|
-
this.calculateLayout();
|
|
1846
|
-
for (let child of this.children) {
|
|
1847
|
-
const { left, top } = child.node.getComputedLayout();
|
|
1848
|
-
child.x = left;
|
|
1849
|
-
child.y = top;
|
|
1850
|
-
}
|
|
1851
|
-
}, flexRender_fn = function(props) {
|
|
1911
|
+
}, _canvasContext = new WeakMap(), _DisplayObject_instances = new WeakSet(), flexRender_fn = function(props) {
|
|
1852
1912
|
if (!this.parent) return;
|
|
1853
1913
|
if (props.flexDirection || props.justifyContent) {
|
|
1854
1914
|
this.isFlex = true;
|
|
1855
|
-
|
|
1915
|
+
this.applyFlexLayout();
|
|
1856
1916
|
}
|
|
1857
1917
|
}, setAlign_fn = function(methodName, align) {
|
|
1858
1918
|
const mapping = {
|
|
@@ -2218,7 +2278,7 @@ function animatedSignal(initialValue, options = {}) {
|
|
|
2218
2278
|
const currentState = privateSignal();
|
|
2219
2279
|
publicSignal.set(currentState.current);
|
|
2220
2280
|
});
|
|
2221
|
-
function animatedSignal2(newValue) {
|
|
2281
|
+
function animatedSignal2(newValue, animationConfig = {}) {
|
|
2222
2282
|
if (newValue === void 0) {
|
|
2223
2283
|
return privateSignal();
|
|
2224
2284
|
}
|
|
@@ -2236,6 +2296,7 @@ function animatedSignal(initialValue, options = {}) {
|
|
|
2236
2296
|
// TODO
|
|
2237
2297
|
duration: 20,
|
|
2238
2298
|
...options,
|
|
2299
|
+
...animationConfig,
|
|
2239
2300
|
from: prevState.current,
|
|
2240
2301
|
to: newValue,
|
|
2241
2302
|
onUpdate: (value) => {
|
|
@@ -2256,11 +2317,25 @@ function animatedSignal(initialValue, options = {}) {
|
|
|
2256
2317
|
fn.update = (updater) => {
|
|
2257
2318
|
animatedSignal2(updater(privateSignal().current));
|
|
2258
2319
|
};
|
|
2259
|
-
fn.set = (newValue) => {
|
|
2260
|
-
|
|
2320
|
+
fn.set = async (newValue, animationConfig = {}) => {
|
|
2321
|
+
return new Promise((resolve) => {
|
|
2322
|
+
animatedSignal2(newValue, {
|
|
2323
|
+
...animationConfig,
|
|
2324
|
+
onComplete: resolve
|
|
2325
|
+
});
|
|
2326
|
+
});
|
|
2261
2327
|
};
|
|
2262
2328
|
return fn;
|
|
2263
2329
|
}
|
|
2330
|
+
async function animatedSequence(sequence) {
|
|
2331
|
+
for (const item of sequence) {
|
|
2332
|
+
if (Array.isArray(item)) {
|
|
2333
|
+
await Promise.all(item.map((fn) => fn()));
|
|
2334
|
+
} else {
|
|
2335
|
+
await item();
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2264
2339
|
|
|
2265
2340
|
// src/components/Sprite.ts
|
|
2266
2341
|
var log2 = console.log;
|
|
@@ -2762,8 +2837,8 @@ var CanvasText = class extends DisplayObject(PixiText) {
|
|
|
2762
2837
|
this.typewriterOptions = props.typewriter;
|
|
2763
2838
|
}
|
|
2764
2839
|
}
|
|
2765
|
-
if (props.text) {
|
|
2766
|
-
this.text = props.text;
|
|
2840
|
+
if (props.text !== void 0) {
|
|
2841
|
+
this.text = "" + props.text;
|
|
2767
2842
|
}
|
|
2768
2843
|
if (props.text !== void 0 && props.text !== this.fullText && this.fullProps.typewriter) {
|
|
2769
2844
|
this.text = "";
|
|
@@ -3159,6 +3234,7 @@ export {
|
|
|
3159
3234
|
utils_exports as Utils,
|
|
3160
3235
|
Video,
|
|
3161
3236
|
Viewport,
|
|
3237
|
+
animatedSequence,
|
|
3162
3238
|
animatedSignal,
|
|
3163
3239
|
bootstrapCanvas,
|
|
3164
3240
|
cond,
|