canvasengine 2.0.0-beta.13 → 2.0.0-beta.14
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 +32 -26
- package/dist/index.js +181 -153
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Graphic.ts +15 -13
- package/src/components/types/DisplayObject.ts +7 -0
- package/src/directives/Drag.ts +26 -6
- package/src/directives/ViewportFollow.ts +26 -4
- package/src/engine/reactive.ts +11 -22
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvasengine",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@barvynkoa/particle-emitter": "^0.0.1",
|
|
9
|
-
"@signe/reactive": "^
|
|
9
|
+
"@signe/reactive": "^2.3.3",
|
|
10
10
|
"howler": "^2.2.4",
|
|
11
11
|
"pixi-filters": "^6.0.5",
|
|
12
12
|
"pixi-viewport": "^6.0.3",
|
|
@@ -1,35 +1,31 @@
|
|
|
1
|
-
import { effect, Signal } from "@signe/reactive";
|
|
1
|
+
import { Effect, effect, Signal } from "@signe/reactive";
|
|
2
2
|
import { Graphics as PixiGraphics } from "pixi.js";
|
|
3
3
|
import { createComponent, registerComponent } from "../engine/reactive";
|
|
4
4
|
import { DisplayObject } from "./DisplayObject";
|
|
5
5
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
6
6
|
import { useProps } from "../hooks/useProps";
|
|
7
|
+
import { SignalOrPrimitive } from "./types";
|
|
7
8
|
|
|
8
9
|
interface GraphicsProps extends DisplayObjectProps {
|
|
9
10
|
draw?: (graphics: PixiGraphics) => void;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
interface RectProps extends DisplayObjectProps {
|
|
13
|
-
|
|
14
|
-
height: number;
|
|
15
|
-
color: string;
|
|
14
|
+
color: SignalOrPrimitive<string>;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
interface CircleProps extends DisplayObjectProps {
|
|
19
|
-
radius: number
|
|
20
|
-
color: string
|
|
18
|
+
radius: SignalOrPrimitive<number>;
|
|
19
|
+
color: SignalOrPrimitive<string>;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
interface EllipseProps extends DisplayObjectProps {
|
|
24
|
-
|
|
25
|
-
height: number;
|
|
26
|
-
color: string;
|
|
23
|
+
color: SignalOrPrimitive<string>;
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
interface TriangleProps extends DisplayObjectProps {
|
|
30
|
-
base: number
|
|
31
|
-
|
|
32
|
-
color: string;
|
|
27
|
+
base: SignalOrPrimitive<number>;
|
|
28
|
+
color: SignalOrPrimitive<string>;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
interface SvgProps extends DisplayObjectProps {
|
|
@@ -37,15 +33,21 @@ interface SvgProps extends DisplayObjectProps {
|
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
class CanvasGraphics extends DisplayObject(PixiGraphics) {
|
|
36
|
+
clearEffect: Effect;
|
|
40
37
|
onInit(props) {
|
|
41
38
|
super.onInit(props);
|
|
42
39
|
if (props.draw) {
|
|
43
|
-
effect(() => {
|
|
40
|
+
this.clearEffect = effect(() => {
|
|
44
41
|
this.clear();
|
|
45
42
|
props.draw?.(this);
|
|
46
43
|
});
|
|
47
44
|
}
|
|
48
45
|
}
|
|
46
|
+
|
|
47
|
+
onDestroy() {
|
|
48
|
+
this.clearEffect.subscription.unsubscribe();
|
|
49
|
+
super.onDestroy();
|
|
50
|
+
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
interface CanvasGraphics extends PixiGraphics {}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as PIXI from "pixi.js";
|
|
2
2
|
import { SignalOrPrimitive } from ".";
|
|
3
|
+
import { DragProps } from "../../directives/Drag";
|
|
4
|
+
import { ViewportFollowProps } from "../../directives/ViewportFollow";
|
|
3
5
|
|
|
4
6
|
export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
5
7
|
export type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';
|
|
@@ -37,6 +39,11 @@ export interface DisplayObjectProps {
|
|
|
37
39
|
blendMode?: SignalOrPrimitive<PIXI.BLEND_MODES>;
|
|
38
40
|
blur?: SignalOrPrimitive<number>;
|
|
39
41
|
|
|
42
|
+
// Directives
|
|
43
|
+
drag?: DragProps;
|
|
44
|
+
viewportFollow?: ViewportFollowProps;
|
|
45
|
+
|
|
46
|
+
// Events
|
|
40
47
|
click?: PIXI.FederatedEventHandler;
|
|
41
48
|
mousedown?: PIXI.FederatedEventHandler;
|
|
42
49
|
mouseenter?: PIXI.FederatedEventHandler;
|
package/src/directives/Drag.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { effect, isSignal, signal } from '@signe/reactive';
|
|
1
|
+
import { effect, isComputed, isSignal, signal } from '@signe/reactive';
|
|
2
2
|
import { Container, Rectangle, Point, FederatedPointerEvent } from 'pixi.js';
|
|
3
3
|
import { Directive, registerDirective } from '../engine/directive';
|
|
4
4
|
import { Element } from '../engine/reactive';
|
|
@@ -6,6 +6,19 @@ import { snap } from 'popmotion';
|
|
|
6
6
|
import { addContext } from '../hooks/addContext';
|
|
7
7
|
import { Subscription } from 'rxjs';
|
|
8
8
|
import { useProps } from '../hooks/useProps';
|
|
9
|
+
import { SignalOrPrimitive } from '../components/types';
|
|
10
|
+
|
|
11
|
+
export type DragProps = {
|
|
12
|
+
move?: (event: FederatedPointerEvent) => void;
|
|
13
|
+
start?: () => void;
|
|
14
|
+
end?: () => void;
|
|
15
|
+
snap?: SignalOrPrimitive<number>;
|
|
16
|
+
direction?: SignalOrPrimitive<'x' | 'y' | 'all'>;
|
|
17
|
+
viewport?: {
|
|
18
|
+
edgeThreshold?: SignalOrPrimitive<number>;
|
|
19
|
+
maxSpeed?: SignalOrPrimitive<number>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
9
22
|
|
|
10
23
|
export class Drop extends Directive {
|
|
11
24
|
private elementRef: Element<Container> | null = null;
|
|
@@ -147,12 +160,19 @@ export class Drag extends Directive {
|
|
|
147
160
|
this.lastPointerPosition.copyFrom(event.global);
|
|
148
161
|
|
|
149
162
|
const { x: xProp, y: yProp } = propObservables as any;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
|
|
164
|
+
const updatePosition = (prop: any, value: number) => {
|
|
165
|
+
if (isComputed(prop)) {
|
|
166
|
+
prop.dependencies.forEach(dependency => {
|
|
167
|
+
dependency.set(value)
|
|
168
|
+
})
|
|
169
|
+
} else if (isSignal(prop)) {
|
|
170
|
+
prop.set(value)
|
|
171
|
+
}
|
|
155
172
|
}
|
|
173
|
+
|
|
174
|
+
if (xProp !== undefined) updatePosition(xProp, instance.position.x)
|
|
175
|
+
if (yProp !== undefined) updatePosition(yProp, instance.position.y)
|
|
156
176
|
}
|
|
157
177
|
|
|
158
178
|
/**
|
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
import { ComponentInstance } from '../components/DisplayObject';
|
|
2
|
+
import { SignalOrPrimitive } from '../components/types';
|
|
2
3
|
import { Directive, registerDirective } from '../engine/directive';
|
|
3
4
|
import { Element } from '../engine/reactive';
|
|
4
5
|
import { error } from '../engine/utils';
|
|
6
|
+
import { useProps } from '../hooks/useProps';
|
|
7
|
+
|
|
8
|
+
export type ViewportFollowProps = {
|
|
9
|
+
viewportFollow?: boolean | {
|
|
10
|
+
speed?: SignalOrPrimitive<number>;
|
|
11
|
+
acceleration?: SignalOrPrimitive<number>;
|
|
12
|
+
radius?: SignalOrPrimitive<number>;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
5
15
|
|
|
6
16
|
export class ViewportFollow extends Directive {
|
|
7
17
|
onInit(element: Element<ComponentInstance>) {
|
|
8
18
|
|
|
9
19
|
}
|
|
10
20
|
onMount(element: Element) {
|
|
11
|
-
this.onUpdate(element.props, element)
|
|
21
|
+
this.onUpdate(element.props.viewportFollow, element)
|
|
12
22
|
}
|
|
13
|
-
onUpdate(
|
|
14
|
-
const { viewportFollow } = element.props
|
|
23
|
+
onUpdate(viewportFollow: any, element: Element) {
|
|
15
24
|
const { viewport } = element.props.context
|
|
16
25
|
if (!viewport) {
|
|
17
26
|
throw error('ViewportFollow directive requires a Viewport component to be mounted in the same context')
|
|
18
27
|
}
|
|
19
28
|
if (viewportFollow) {
|
|
20
|
-
|
|
29
|
+
if (viewportFollow === true) {
|
|
30
|
+
viewport.follow(element.componentInstance)
|
|
31
|
+
} else {
|
|
32
|
+
const options = useProps(viewportFollow, {
|
|
33
|
+
speed: undefined,
|
|
34
|
+
acceleration: undefined,
|
|
35
|
+
radius: undefined
|
|
36
|
+
})
|
|
37
|
+
viewport.follow(element.componentInstance, {
|
|
38
|
+
speed: options.speed(),
|
|
39
|
+
acceleration: options.acceleration(),
|
|
40
|
+
radius: options.radius()
|
|
41
|
+
})
|
|
42
|
+
}
|
|
21
43
|
} else {
|
|
22
44
|
viewport.plugins.remove('follow')
|
|
23
45
|
}
|
package/src/engine/reactive.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Signal, WritableArraySignal, WritableObjectSignal, isSignal } from "@signe/reactive";
|
|
1
|
+
import { ArrayChange, ObjectChange, Signal, WritableArraySignal, WritableObjectSignal, isComputed, isSignal, signal } from "@signe/reactive";
|
|
2
2
|
import {
|
|
3
3
|
Observable,
|
|
4
4
|
Subject,
|
|
@@ -17,25 +17,6 @@ export interface Props {
|
|
|
17
17
|
[key: string]: any;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export type ArrayChange<T> = {
|
|
21
|
-
type: "add" | "remove" | "update" | "init" | "reset";
|
|
22
|
-
index?: number;
|
|
23
|
-
items: T[];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type ObjectChange<T> = {
|
|
27
|
-
type: "add" | "remove" | "update" | "init" | "reset";
|
|
28
|
-
key?: string;
|
|
29
|
-
value?: T;
|
|
30
|
-
items: T[];
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
type ElementObservable<T> = Observable<
|
|
34
|
-
(ArrayChange<T> | ObjectChange<T>) & {
|
|
35
|
-
value: Element | Element[];
|
|
36
|
-
}
|
|
37
|
-
>;
|
|
38
|
-
|
|
39
20
|
type NestedSignalObjects = {
|
|
40
21
|
[Key in string]: NestedSignalObjects | Signal<any>;
|
|
41
22
|
};
|
|
@@ -104,11 +85,11 @@ function destroyElement(element: Element | Element[]) {
|
|
|
104
85
|
}
|
|
105
86
|
element.propSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
106
87
|
element.effectSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
88
|
+
element.effectUnmounts.forEach((fn) => fn?.());
|
|
107
89
|
for (let name in element.directives) {
|
|
108
90
|
element.directives[name].onDestroy?.(element);
|
|
109
91
|
}
|
|
110
92
|
element.componentInstance.onDestroy?.(element.parent as any);
|
|
111
|
-
element.effectUnmounts.forEach((fn) => fn?.());
|
|
112
93
|
}
|
|
113
94
|
|
|
114
95
|
/**
|
|
@@ -309,9 +290,17 @@ export function createComponent(tag: string, props?: Props): Element {
|
|
|
309
290
|
* @returns {Observable} An observable that emits the list of created child elements.
|
|
310
291
|
*/
|
|
311
292
|
export function loop<T>(
|
|
312
|
-
itemsSubject:
|
|
293
|
+
itemsSubject: any,
|
|
313
294
|
createElementFn: (item: T, index: number | string) => Element | null
|
|
314
295
|
): FlowObservable {
|
|
296
|
+
|
|
297
|
+
if (isComputed(itemsSubject) && itemsSubject.dependencies.size == 0) {
|
|
298
|
+
itemsSubject = signal(itemsSubject());
|
|
299
|
+
}
|
|
300
|
+
else if (!isSignal(itemsSubject)) {
|
|
301
|
+
itemsSubject = signal(itemsSubject);
|
|
302
|
+
}
|
|
303
|
+
|
|
315
304
|
return defer(() => {
|
|
316
305
|
let elements: Element[] = [];
|
|
317
306
|
let elementMap = new Map<string | number, Element>();
|