@lukekaalim/act-three 5.15.0 → 6.0.0
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/deps.ts +3 -0
- package/elements.ts +69 -0
- package/mod.ts +5 -0
- package/package.json +9 -21
- package/props.ts +39 -0
- package/render.ts +14 -0
- package/space.ts +33 -0
- package/components/groups.js +0 -37
- package/components/lights.js +0 -1
- package/components/scene.js +0 -21
- package/components.d.ts +0 -129
- package/components.js +0 -138
- package/entry.d.ts +0 -5
- package/entry.js +0 -8
- package/hooks/matrix.js +0 -28
- package/hooks.d.ts +0 -19
- package/hooks.js +0 -190
- package/objects.js +0 -69
- package/props.d.ts +0 -7
- package/props.js +0 -160
- package/reconciler.d.ts +0 -3
- package/reconciler.js +0 -54
- package/renderer.d.ts +0 -13
- package/renderer.js +0 -60
package/deps.ts
ADDED
package/elements.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { DirectionalLight, Group, Line, LineLoop, LineSegments, Mesh, Object3D, OrthographicCamera, PerspectiveCamera, PointLight, Points, Scene, SkinnedMesh, Sprite } from "three";
|
|
2
|
+
import { act } from "./deps";
|
|
3
|
+
import { Object3DProps, setProps } from "./props";
|
|
4
|
+
import { Component, ElementType, h, Node } from "@lukekaalim/act";
|
|
5
|
+
|
|
6
|
+
const handlers = new Map<string | Symbol, ThreeNodeHandler<any>>();
|
|
7
|
+
|
|
8
|
+
export type ThreeNodeHandler<T extends Object3D> = {
|
|
9
|
+
type: string | Symbol,
|
|
10
|
+
create: (props: act.Props) => T,
|
|
11
|
+
setProps: (instance: T, prevProps: null | act.Props, nextProps: act.Props) => unknown,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const registerElementHandler = <T extends Object3D>(handler: ThreeNodeHandler<T>): void => {
|
|
15
|
+
handlers.set(handler.type, handler);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const getElementHandler = (type: act.ElementType): null | ThreeNodeHandler<Object3D> => {
|
|
19
|
+
if (typeof type === 'string' || typeof type === 'symbol') {
|
|
20
|
+
const handler = handlers.get(type);
|
|
21
|
+
if (handler)
|
|
22
|
+
return handler;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type Newable<T> = { new (): T; };
|
|
28
|
+
|
|
29
|
+
export const addSimpleElement = <T extends Object3D>(type: string | symbol, ElementClass: Newable<T>) => {
|
|
30
|
+
registerElementHandler<T>({
|
|
31
|
+
type,
|
|
32
|
+
create() {
|
|
33
|
+
return new ElementClass();
|
|
34
|
+
},
|
|
35
|
+
setProps(instance, prevProps, nextProps) {
|
|
36
|
+
setProps(instance, nextProps as Object3DProps<T>);
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const elementMap = {
|
|
42
|
+
mesh: Mesh,
|
|
43
|
+
points: Points,
|
|
44
|
+
group: Group,
|
|
45
|
+
scene: Scene,
|
|
46
|
+
sprite: Sprite,
|
|
47
|
+
skinnedMesh: SkinnedMesh,
|
|
48
|
+
|
|
49
|
+
pointLight: PointLight,
|
|
50
|
+
directionalLight: DirectionalLight,
|
|
51
|
+
|
|
52
|
+
line: Line,
|
|
53
|
+
lineLoop: LineLoop,
|
|
54
|
+
lineSegments: LineSegments,
|
|
55
|
+
|
|
56
|
+
perspectiveCamera: PerspectiveCamera,
|
|
57
|
+
orthographicCamera: OrthographicCamera,
|
|
58
|
+
} as const;
|
|
59
|
+
type ElementMap = typeof elementMap;
|
|
60
|
+
|
|
61
|
+
for (const key in elementMap) {
|
|
62
|
+
addSimpleElement(key, elementMap[key as keyof ElementMap] as any)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type ElementNodes = {
|
|
66
|
+
readonly [key in keyof ElementMap]: Component<Object3DProps<InstanceType<ElementMap[key]>>>
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const node: ElementNodes = Object.fromEntries(Object.keys(elementMap).map(k => [k, k as ElementType])) as ElementNodes;
|
package/mod.ts
ADDED
package/package.json
CHANGED
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukekaalim/act-three",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"main": "entry.js",
|
|
6
|
-
"types": "entry.d.ts",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"test": "cd ../../; npm test;",
|
|
10
|
-
"postversion": "../../scripts/postversion.sh",
|
|
11
|
-
"preversion": "npm run test"
|
|
12
|
-
},
|
|
13
|
-
"author": "Luke Kaalim",
|
|
14
|
-
"license": "ISC",
|
|
15
|
-
"peerDependencies": {
|
|
16
|
-
"three": "^0.155.0"
|
|
17
|
-
},
|
|
3
|
+
"main": "mod.ts",
|
|
4
|
+
"version": "6.0.0",
|
|
18
5
|
"dependencies": {
|
|
19
|
-
"@
|
|
20
|
-
"@lukekaalim/act-
|
|
21
|
-
"@lukekaalim/act
|
|
22
|
-
"@lukekaalim/act-
|
|
6
|
+
"@types/three": ">= 0.171.0",
|
|
7
|
+
"@lukekaalim/act-web": "^3.0.0",
|
|
8
|
+
"@lukekaalim/act": "^3.0.0",
|
|
9
|
+
"@lukekaalim/act-recon": "^1.0.0",
|
|
10
|
+
"@lukekaalim/act-backstage": "^1.0.0"
|
|
23
11
|
},
|
|
24
|
-
"
|
|
25
|
-
"
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"three": ">= 0.171.0"
|
|
26
14
|
}
|
|
27
15
|
}
|
package/props.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Object3D } from "three";
|
|
2
|
+
import { act, three } from "./deps";
|
|
3
|
+
|
|
4
|
+
export type Object3DProps<T extends Object3D> = {
|
|
5
|
+
position?: three.Vector3,
|
|
6
|
+
scale?: three.Vector3,
|
|
7
|
+
quaternion?: three.Quaternion,
|
|
8
|
+
rotation?: three.Euler,
|
|
9
|
+
|
|
10
|
+
ref?: act.ReadonlyRef<null | three.Object3D>,
|
|
11
|
+
}
|
|
12
|
+
& (T extends three.Mesh ? { geometry?: three.BufferGeometry, material?: three.Material } : {})
|
|
13
|
+
& (T extends three.Scene ? { background?: three.Color } : {})
|
|
14
|
+
|
|
15
|
+
export const setProps = <T extends Object3D>(object: T, props: Object3DProps<T>) => {
|
|
16
|
+
if (props.position)
|
|
17
|
+
object.position.copy(props.position as three.Vector3);
|
|
18
|
+
if (props.scale)
|
|
19
|
+
object.scale.copy(props.scale as three.Vector3);
|
|
20
|
+
if (props.quaternion)
|
|
21
|
+
object.quaternion.copy(props.quaternion as three.Quaternion);
|
|
22
|
+
if (props.rotation)
|
|
23
|
+
object.rotation.copy(props.rotation as three.Euler);
|
|
24
|
+
if (props.ref)
|
|
25
|
+
(props.ref as Record<string, unknown>).current = object;
|
|
26
|
+
|
|
27
|
+
if (object instanceof three.Mesh) {
|
|
28
|
+
const meshProps = props as Object3DProps<three.Mesh>;
|
|
29
|
+
object.geometry = meshProps.geometry;
|
|
30
|
+
object.material = meshProps.material;
|
|
31
|
+
}
|
|
32
|
+
if (object instanceof three.PerspectiveCamera) {
|
|
33
|
+
object.updateProjectionMatrix();
|
|
34
|
+
}
|
|
35
|
+
if (object instanceof three.Scene) {
|
|
36
|
+
const sceneProps = props as Object3DProps<three.Scene>;
|
|
37
|
+
object.background = (sceneProps.background as three.Color);
|
|
38
|
+
}
|
|
39
|
+
};
|
package/render.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createRenderFunction, RenderSpace, Scheduler } from "@lukekaalim/act-backstage";
|
|
2
|
+
import { createWebSpace } from '@lukekaalim/act-web';
|
|
3
|
+
import { createFinaleSpace } from "./space";
|
|
4
|
+
|
|
5
|
+
const intervalScheduler: Scheduler<NodeJS.Timeout> = {
|
|
6
|
+
duration: 10,
|
|
7
|
+
request: func => setInterval(func, 10),
|
|
8
|
+
cancel: id => clearInterval(id),
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const render = createRenderFunction<NodeJS.Timeout, HTMLElement>(intervalScheduler, (tree, root) => RenderSpace.combine([
|
|
12
|
+
createWebSpace(tree, root),
|
|
13
|
+
createFinaleSpace(tree),
|
|
14
|
+
]));
|
package/space.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createSimpleRenderSpace } from "@lukekaalim/act-backstage/mod.ts"
|
|
2
|
+
import { act, recon, three } from "./deps"
|
|
3
|
+
import { setProps } from "./props";
|
|
4
|
+
import { primitiveNodeTypes } from "@lukekaalim/act";
|
|
5
|
+
import { getElementHandler } from "./elements";
|
|
6
|
+
|
|
7
|
+
export const ThreeJS: act.Component = ({ children }) => act.h(primitiveNodeTypes.render, { type: 'threejs' }, children)
|
|
8
|
+
|
|
9
|
+
export const createFinaleSpace = (tree: recon.CommitTree) => {
|
|
10
|
+
return createSimpleRenderSpace(tree, {
|
|
11
|
+
rootTypes: new Set(['threejs']),
|
|
12
|
+
create(element) {
|
|
13
|
+
const handler = getElementHandler(element.type);
|
|
14
|
+
if (handler)
|
|
15
|
+
return handler.create(element.props);
|
|
16
|
+
return null;
|
|
17
|
+
},
|
|
18
|
+
update(el, next, prev) {
|
|
19
|
+
const handler = getElementHandler(next.type);
|
|
20
|
+
if (handler)
|
|
21
|
+
handler.setProps(el, prev && prev.props, next.props);
|
|
22
|
+
},
|
|
23
|
+
link(el, parent) {
|
|
24
|
+
parent && parent.add(el)
|
|
25
|
+
},
|
|
26
|
+
destroy(el) {
|
|
27
|
+
if (el.parent)
|
|
28
|
+
el.removeFromParent()
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const finale = createFinaleSpace;
|
package/components/groups.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Component, Ref } from '@lukekaalim/act'; */
|
|
3
|
-
/*:: import type { Euler, Group, Object3D } from "three"; */
|
|
4
|
-
/*:: import type { GroupProps, RefProp } from '../components'; */
|
|
5
|
-
|
|
6
|
-
import { h, useEffect, useRef, useState } from '@lukekaalim/act';
|
|
7
|
-
import { Matrix4, Vector3 } from "three";
|
|
8
|
-
import { group } from '../components.js';
|
|
9
|
-
|
|
10
|
-
/*::
|
|
11
|
-
export type LookAtGroupProps = {
|
|
12
|
-
...$Diff<GroupProps, { rotation?: Euler, ref?: RefProp<Group> }>,
|
|
13
|
-
target: Vector3,
|
|
14
|
-
deps?: mixed[],
|
|
15
|
-
};
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
export const LookAtGroup/*: Component<LookAtGroupProps>*/ = ({
|
|
19
|
-
target,
|
|
20
|
-
children,
|
|
21
|
-
position = new Vector3(0, 0, 0),
|
|
22
|
-
deps = [],
|
|
23
|
-
...groupProps
|
|
24
|
-
}) => {
|
|
25
|
-
const groupRef = useRef(null);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
const { current: groupNode } = groupRef;
|
|
29
|
-
if (!groupNode)
|
|
30
|
-
return;
|
|
31
|
-
|
|
32
|
-
groupNode.setRotationFromMatrix(new Matrix4().lookAt(position, target, new Vector3(0, 1, 0)));
|
|
33
|
-
groupNode.updateMatrix();
|
|
34
|
-
}, [target.x, target.y, target.z, position.x, position.y, position.z, ...deps]);
|
|
35
|
-
|
|
36
|
-
return h(group, { ...groupProps, position, ref: groupRef }, children);
|
|
37
|
-
}
|
package/components/lights.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
package/components/scene.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*::
|
|
3
|
-
import type { SceneProps } from "../components";
|
|
4
|
-
import type { Scene, Texture } from "three";
|
|
5
|
-
*/
|
|
6
|
-
import { Color } from "three";
|
|
7
|
-
|
|
8
|
-
/*::
|
|
9
|
-
export type PropSetters<T> = {
|
|
10
|
-
[string]: (object: T, nextProp: any, prevProp: any) => void,
|
|
11
|
-
}
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
export const scenePropSetters/*: PropSetters<Scene>*/ = {
|
|
15
|
-
'background': (scene/*: Scene*/, prop/*: null | Color | Texture*/) => {
|
|
16
|
-
if (scene.background instanceof Color && prop instanceof Color)
|
|
17
|
-
scene.background.copy(prop)
|
|
18
|
-
else
|
|
19
|
-
scene.background = prop;
|
|
20
|
-
}
|
|
21
|
-
}
|
package/components.d.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { Component, Ref } from "@lukekaalim/act";
|
|
2
|
-
import {
|
|
3
|
-
AmbientLight,
|
|
4
|
-
DirectionalLight,
|
|
5
|
-
Euler,
|
|
6
|
-
Group,
|
|
7
|
-
HemisphereLight,
|
|
8
|
-
Light,
|
|
9
|
-
Line,
|
|
10
|
-
LineLoop,
|
|
11
|
-
LineSegments,
|
|
12
|
-
Mesh,
|
|
13
|
-
PerspectiveCamera,
|
|
14
|
-
PointLight,
|
|
15
|
-
Points,
|
|
16
|
-
Quaternion,
|
|
17
|
-
Scene,
|
|
18
|
-
Sprite,
|
|
19
|
-
Texture,
|
|
20
|
-
Vector3,
|
|
21
|
-
} from "three";
|
|
22
|
-
|
|
23
|
-
export type ReferenceProps<T> = {
|
|
24
|
-
ref?: ((reference: T) => unknown) | Ref<null | T>;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type PropsFromList<TObject, TPropList extends (keyof TObject)[]> = {
|
|
28
|
-
[Property in TPropList[number]]?: undefined | TObject[Property];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type Object3DProps<T> =
|
|
32
|
-
& ReferenceProps<T>
|
|
33
|
-
& {
|
|
34
|
-
name?: string;
|
|
35
|
-
position?: Vector3;
|
|
36
|
-
rotation?: Euler;
|
|
37
|
-
quaternion?: Quaternion;
|
|
38
|
-
visible?: boolean;
|
|
39
|
-
scale?: Vector3;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const scene: Component<SceneProps>;
|
|
43
|
-
export type SceneProps =
|
|
44
|
-
& Object3DProps<Scene>
|
|
45
|
-
& PropsFromList<Scene, [
|
|
46
|
-
"fog",
|
|
47
|
-
"backgroundBlurriness",
|
|
48
|
-
"backgroundIntensity",
|
|
49
|
-
"overrideMaterial",
|
|
50
|
-
"background",
|
|
51
|
-
"environment",
|
|
52
|
-
]>;
|
|
53
|
-
|
|
54
|
-
export const group: Component<GroupProps>;
|
|
55
|
-
export type GroupProps = Object3DProps<Group>;
|
|
56
|
-
|
|
57
|
-
export const mesh: Component<MeshProps>;
|
|
58
|
-
export type MeshProps =
|
|
59
|
-
& Object3DProps<Mesh>
|
|
60
|
-
& PropsFromList<Mesh, ["geometry", "material"]>;
|
|
61
|
-
|
|
62
|
-
export const sprite: Component<SpriteProps>;
|
|
63
|
-
export type SpriteProps =
|
|
64
|
-
& Object3DProps<Sprite>
|
|
65
|
-
& PropsFromList<Sprite, ["geometry", "material", "center"]>;
|
|
66
|
-
|
|
67
|
-
export const points: Component<PointsProps>;
|
|
68
|
-
export type PointsProps =
|
|
69
|
-
& Object3DProps<Points>
|
|
70
|
-
& PropsFromList<Points, ["geometry", "material"]>;
|
|
71
|
-
|
|
72
|
-
export const line: Component<LineProps>;
|
|
73
|
-
export const lineLoop: Component<LineProps>;
|
|
74
|
-
export const lineSegments: Component<LineProps>;
|
|
75
|
-
export type LineProps =
|
|
76
|
-
& Object3DProps<Line>
|
|
77
|
-
& PropsFromList<Line, ["geometry", "material"]>;
|
|
78
|
-
|
|
79
|
-
export type LightProps = PropsFromList<Light, [
|
|
80
|
-
"color",
|
|
81
|
-
"intensity",
|
|
82
|
-
"shadow",
|
|
83
|
-
]>;
|
|
84
|
-
|
|
85
|
-
export const pointLight: Component<PointerLightProps>;
|
|
86
|
-
export type PointerLightProps =
|
|
87
|
-
& Object3DProps<PointLight>
|
|
88
|
-
& LightProps
|
|
89
|
-
& PropsFromList<PointLight, [
|
|
90
|
-
"distance",
|
|
91
|
-
"castShadow",
|
|
92
|
-
"decay",
|
|
93
|
-
"shadow",
|
|
94
|
-
"power",
|
|
95
|
-
]>;
|
|
96
|
-
|
|
97
|
-
export const ambientLight: Component<AmbientLightProps>;
|
|
98
|
-
export type AmbientLightProps =
|
|
99
|
-
& Object3DProps<AmbientLight>
|
|
100
|
-
& LightProps;
|
|
101
|
-
|
|
102
|
-
export const directionalLight: Component<DirectionalLightProps>;
|
|
103
|
-
export type DirectionalLightProps =
|
|
104
|
-
& Object3DProps<DirectionalLight>
|
|
105
|
-
& LightProps
|
|
106
|
-
& PropsFromList<DirectionalLight, [
|
|
107
|
-
"shadow",
|
|
108
|
-
"target",
|
|
109
|
-
]>;
|
|
110
|
-
|
|
111
|
-
export const hemisphereLight: Component<HemisphereLightProps>;
|
|
112
|
-
export type HemisphereLightProps =
|
|
113
|
-
& Object3DProps<HemisphereLight>
|
|
114
|
-
& LightProps;
|
|
115
|
-
|
|
116
|
-
export const perspectiveCamera: Component<PerspectiveCameraProps>;
|
|
117
|
-
export type PerspectiveCameraProps =
|
|
118
|
-
& Object3DProps<PerspectiveCamera>
|
|
119
|
-
& PropsFromList<PerspectiveCamera, [
|
|
120
|
-
"aspect",
|
|
121
|
-
"near",
|
|
122
|
-
"far",
|
|
123
|
-
"zoom",
|
|
124
|
-
"fov",
|
|
125
|
-
"focus",
|
|
126
|
-
"view",
|
|
127
|
-
"filmGauge",
|
|
128
|
-
"filmOffset",
|
|
129
|
-
]>;
|
package/components.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Component } from '@lukekaalim/act'; */
|
|
3
|
-
/*:: import type {
|
|
4
|
-
Vector3,
|
|
5
|
-
Vector2,
|
|
6
|
-
Object3D,
|
|
7
|
-
Quaternion,
|
|
8
|
-
BufferGeometry,
|
|
9
|
-
Material,
|
|
10
|
-
Texture,
|
|
11
|
-
Color,
|
|
12
|
-
Group,
|
|
13
|
-
Camera,
|
|
14
|
-
PerspectiveCamera,
|
|
15
|
-
Euler,
|
|
16
|
-
Scene,
|
|
17
|
-
CubeTexture,
|
|
18
|
-
Fog,
|
|
19
|
-
Line,
|
|
20
|
-
LineSegments,
|
|
21
|
-
WebGLRenderer,
|
|
22
|
-
} from "three"; */
|
|
23
|
-
/*:: import * as Three from 'three'; */
|
|
24
|
-
|
|
25
|
-
/*::
|
|
26
|
-
export type RefProp<T> = ((reference: T) => mixed) | { current: T | any }
|
|
27
|
-
|
|
28
|
-
export type Object3DProps<T> = {
|
|
29
|
-
ref?: RefProp<?T>,
|
|
30
|
-
|
|
31
|
-
name?: string,
|
|
32
|
-
position?: Vector3,
|
|
33
|
-
rotation?: Euler,
|
|
34
|
-
quaternion?: Quaternion,
|
|
35
|
-
visible?: boolean,
|
|
36
|
-
scale?: Vector3,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type SceneProps = {
|
|
40
|
-
...Object3DProps<Scene>,
|
|
41
|
-
autoUpdate?: ?boolean,
|
|
42
|
-
background?: ?(Color | Texture | CubeTexture),
|
|
43
|
-
environment?: ?Texture,
|
|
44
|
-
fog?: ?Fog,
|
|
45
|
-
overrideMaterial?: ?Material
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export type MeshProps = {
|
|
49
|
-
...Object3DProps<Three.Mesh>,
|
|
50
|
-
geometry?: BufferGeometry,
|
|
51
|
-
material?: Material,
|
|
52
|
-
};
|
|
53
|
-
export type SpriteProps = {
|
|
54
|
-
...Object3DProps<Three.Sprite>,
|
|
55
|
-
material: Material;
|
|
56
|
-
center: Vector2;
|
|
57
|
-
};
|
|
58
|
-
export type InstancedMeshProps = {
|
|
59
|
-
...MeshProps,
|
|
60
|
-
...Object3DProps<Three.InstancedMesh>,
|
|
61
|
-
};
|
|
62
|
-
export type PointLightsProps = {
|
|
63
|
-
...Object3DProps<Three.PointLight>,
|
|
64
|
-
distance?: number,
|
|
65
|
-
decay?: number,
|
|
66
|
-
intensity?: number,
|
|
67
|
-
power?: number,
|
|
68
|
-
};
|
|
69
|
-
export type DirectionalLightProps = {
|
|
70
|
-
...Object3DProps<Three.DirectionalLight>,
|
|
71
|
-
distance?: number,
|
|
72
|
-
decay?: number,
|
|
73
|
-
intensity?: number,
|
|
74
|
-
power?: number,
|
|
75
|
-
};
|
|
76
|
-
export type AmbientLightProps = {
|
|
77
|
-
...Object3DProps<Three.AmbientLight>,
|
|
78
|
-
intensity?: number,
|
|
79
|
-
power?: number,
|
|
80
|
-
};
|
|
81
|
-
export type PointsProps = {
|
|
82
|
-
...Object3DProps<Three.Points>,
|
|
83
|
-
geometry?: BufferGeometry,
|
|
84
|
-
material?: Material,
|
|
85
|
-
};
|
|
86
|
-
export type GroupProps = {
|
|
87
|
-
...Object3DProps<Three.Group>,
|
|
88
|
-
group?: ?Three.Object3D,
|
|
89
|
-
}
|
|
90
|
-
export type PerspectiveCameraProps = {
|
|
91
|
-
...Object3DProps<Three.PerspectiveCamera>,
|
|
92
|
-
aspect?: number,
|
|
93
|
-
near?: number,
|
|
94
|
-
far?: number,
|
|
95
|
-
fov?: number,
|
|
96
|
-
zoom?: number,
|
|
97
|
-
}
|
|
98
|
-
export type OrthographicCameraProps = {
|
|
99
|
-
...Object3DProps<Three.OrthographicCamera>,
|
|
100
|
-
aspect?: number,
|
|
101
|
-
near?: number,
|
|
102
|
-
far?: number,
|
|
103
|
-
zoom?: number,
|
|
104
|
-
}
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
export const scene = ('scene'/*: Component<SceneProps>*/);
|
|
108
|
-
export const group = ('group'/*: Component<GroupProps>*/);
|
|
109
|
-
|
|
110
|
-
export const perspectiveCamera = ('perspectiveCamera'/*: Component<PerspectiveCameraProps>*/);
|
|
111
|
-
export const orthographicCamera = ('orthographicCamera'/*: Component<OrthographicCameraProps>*/);
|
|
112
|
-
|
|
113
|
-
export const mesh = ('mesh'/*: Component<MeshProps>*/);
|
|
114
|
-
export const sprite = ('sprite'/*: Component<SpriteProps>*/);
|
|
115
|
-
export const instancedMesh = ('instancedMesh'/*: Component<InstancedMeshProps>*/);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
export const points = ('points'/*: Component<PointsProps>*/);
|
|
119
|
-
|
|
120
|
-
/*::
|
|
121
|
-
export type LineProps = {
|
|
122
|
-
...Object3DProps<Line>,
|
|
123
|
-
geometry?: BufferGeometry,
|
|
124
|
-
material?: Material,
|
|
125
|
-
}
|
|
126
|
-
*/
|
|
127
|
-
export const line = ('line'/*: Component<LineProps>*/);
|
|
128
|
-
export const lineLoop = ('lineLoop'/*: Component<LineProps>*/);
|
|
129
|
-
export const lineSegments = ('lineSegments'/*: Component<LineProps>*/);
|
|
130
|
-
|
|
131
|
-
export const pointLight = ('pointLight'/*: Component<PointLightsProps>*/);
|
|
132
|
-
export const ambientLight = ('ambientLight'/*: Component<AmbientLightProps>*/);
|
|
133
|
-
export const hemisphereLight = ('hemisphereLight'/*: Component<PointLightsProps>*/);
|
|
134
|
-
export const directionalLight = ('directionalLight'/*: Component<DirectionalLightProps>*/);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
export * from './components/groups.js';
|
|
138
|
-
export * from './components/lights.js';
|
package/entry.d.ts
DELETED
package/entry.js
DELETED
package/hooks/matrix.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Component, Ref } from '@lukekaalim/act'; */
|
|
3
|
-
/*:: import type { Euler, Group, Object3D } from "three"; */
|
|
4
|
-
/*:: import type { GroupProps, RefProp } from '../components'; */
|
|
5
|
-
|
|
6
|
-
import { h, useEffect, useRef, useState } from '@lukekaalim/act';
|
|
7
|
-
import { Matrix4, Vector3 } from "three";
|
|
8
|
-
import { group } from '../components.js';
|
|
9
|
-
|
|
10
|
-
export const defaultUp/*: Vector3*/ = new Vector3(0, 1, 0);
|
|
11
|
-
|
|
12
|
-
export const useLookAt = /*:: <T: Object3D>*/(
|
|
13
|
-
objectRef/*: Ref<?T>*/,
|
|
14
|
-
target/*: Vector3*/,
|
|
15
|
-
deps/*: mixed[]*/ = [],
|
|
16
|
-
up/*: Vector3*/ = defaultUp,
|
|
17
|
-
) => {
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const { current: object } = objectRef;
|
|
21
|
-
if (!object)
|
|
22
|
-
return;
|
|
23
|
-
|
|
24
|
-
object.setRotationFromMatrix(new Matrix4().lookAt(object.position, target, up));
|
|
25
|
-
object.updateMatrix();
|
|
26
|
-
|
|
27
|
-
}, [target.x, target.y, target.z, ...deps]);
|
|
28
|
-
}
|
package/hooks.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Deps, Ref } from "@lukekaalim/act";
|
|
2
|
-
import { WebGLRenderer } from "three";
|
|
3
|
-
|
|
4
|
-
export type WebGLOptions = {
|
|
5
|
-
antialias?: boolean,
|
|
6
|
-
alpha?: boolean,
|
|
7
|
-
|
|
8
|
-
shadowMap?: {
|
|
9
|
-
enabled?: boolean,
|
|
10
|
-
autoUpdate?: boolean,
|
|
11
|
-
type?: number,
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export function useWebGLRenderer(
|
|
16
|
-
canvasRef: Ref<null | HTMLCanvasElement>,
|
|
17
|
-
options?: WebGLOptions,
|
|
18
|
-
deps?: Deps
|
|
19
|
-
): null | WebGLRenderer
|
package/hooks.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Ref } from '@lukekaalim/act'; */
|
|
3
|
-
/*:: import type {
|
|
4
|
-
Camera,
|
|
5
|
-
Scene,
|
|
6
|
-
Texture,
|
|
7
|
-
Object3D,
|
|
8
|
-
PerspectiveCamera,
|
|
9
|
-
OrthographicCamera,
|
|
10
|
-
} from "three"; */
|
|
11
|
-
import { TextureLoader, Vector2, WebGLRenderer } from "three";
|
|
12
|
-
|
|
13
|
-
import { useEffect, useState } from "@lukekaalim/act";
|
|
14
|
-
import { useRef } from "@lukekaalim/act";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/*::
|
|
18
|
-
export type WebGLOptions = {
|
|
19
|
-
antialias?: boolean,
|
|
20
|
-
alpha?: boolean,
|
|
21
|
-
|
|
22
|
-
shadowMap?: {
|
|
23
|
-
enabled?: boolean,
|
|
24
|
-
autoUpdate?: boolean,
|
|
25
|
-
type?: number,
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
export const useWebGLRenderer = (
|
|
31
|
-
canvasRef/*: Ref<?HTMLCanvasElement>*/,
|
|
32
|
-
options/*: WebGLOptions*/ = {},
|
|
33
|
-
deps/*: mixed[]*/ = []
|
|
34
|
-
)/*: ?WebGLRenderer*/ => {
|
|
35
|
-
const [renderer, setRenderer] = useState/*:: <?WebGLRenderer>*/(null);
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
const { current: canvas } = canvasRef;
|
|
38
|
-
if (!canvas)
|
|
39
|
-
return;
|
|
40
|
-
|
|
41
|
-
const renderer = new WebGLRenderer({ ...options, canvas });
|
|
42
|
-
renderer.shadowMap.enabled = options.shadowMap?.enabled || false;
|
|
43
|
-
setRenderer(renderer);
|
|
44
|
-
|
|
45
|
-
return () => {
|
|
46
|
-
setRenderer(null);
|
|
47
|
-
renderer.dispose();
|
|
48
|
-
}
|
|
49
|
-
}, deps);
|
|
50
|
-
|
|
51
|
-
return renderer;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Resize the canvas's resolution whenever it changes size
|
|
55
|
-
// useful for when the canvas is some percentage of the screen
|
|
56
|
-
// like: width: 100%
|
|
57
|
-
export const useResizingRenderer = (
|
|
58
|
-
canvasRef/*: Ref<?HTMLCanvasElement>*/,
|
|
59
|
-
renderer/*: ?WebGLRenderer*/,
|
|
60
|
-
cameraRef/*: ?Ref<?PerspectiveCamera>*/ = null,
|
|
61
|
-
onResize/*: () => mixed*/ = () => {},
|
|
62
|
-
)/*: ?Vector2*/ => {
|
|
63
|
-
const [size, setSize] = useState(null)
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
const { current: canvas } = canvasRef;
|
|
66
|
-
const { current: camera } = (cameraRef || { current: null })
|
|
67
|
-
if (!canvas || !renderer)
|
|
68
|
-
return null;
|
|
69
|
-
|
|
70
|
-
const observer = new ResizeObserver((entries) => {
|
|
71
|
-
for (const entry of entries.filter(e => e.target === canvas)) {
|
|
72
|
-
const width = entry.contentBoxSize[0].inlineSize;
|
|
73
|
-
const height = entry.contentBoxSize[0].blockSize;
|
|
74
|
-
const size = new Vector2(width, height);
|
|
75
|
-
setSize(size);
|
|
76
|
-
renderer.setSize(width, height, false);
|
|
77
|
-
if (camera) {
|
|
78
|
-
camera.aspect = width / height;
|
|
79
|
-
camera.updateProjectionMatrix();
|
|
80
|
-
}
|
|
81
|
-
onResize();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
observer.observe(canvas, { box: 'content-box' });
|
|
85
|
-
|
|
86
|
-
return () => {
|
|
87
|
-
observer.unobserve(canvas);
|
|
88
|
-
setSize(null);
|
|
89
|
-
}
|
|
90
|
-
}, [renderer]);
|
|
91
|
-
|
|
92
|
-
return size;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export const useAnimationFrame = (
|
|
96
|
-
onAnimate/*: ?(now: DOMHighResTimeStamp, delta: number) => mixed*/ = null,
|
|
97
|
-
deps/*: mixed[]*/ = []
|
|
98
|
-
) => {
|
|
99
|
-
useEffect(() => {
|
|
100
|
-
if (!onAnimate)
|
|
101
|
-
return;
|
|
102
|
-
|
|
103
|
-
let lastFrame = performance.now();
|
|
104
|
-
const animate = (now) => {
|
|
105
|
-
const delta = now - lastFrame;
|
|
106
|
-
lastFrame = now;
|
|
107
|
-
|
|
108
|
-
onAnimate(now, delta);
|
|
109
|
-
id = requestAnimationFrame(animate);
|
|
110
|
-
};
|
|
111
|
-
let id = requestAnimationFrame(animate);
|
|
112
|
-
|
|
113
|
-
return () => {
|
|
114
|
-
if (id)
|
|
115
|
-
cancelAnimationFrame(id);
|
|
116
|
-
}
|
|
117
|
-
}, deps);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export const useRenderLoop = /*:: <TCamera: Camera, TScene: Object3D>*/(
|
|
121
|
-
renderer/*: ?WebGLRenderer*/,
|
|
122
|
-
camera/*: Ref<?TCamera>*/,
|
|
123
|
-
scene/*: Ref<?TScene>*/,
|
|
124
|
-
onAnimate/*: (now: DOMHighResTimeStamp, delta: number) => mixed*/ = (_, __) => {},
|
|
125
|
-
deps/*: mixed[]*/ = []
|
|
126
|
-
) => {
|
|
127
|
-
const renderFunction = renderer && ((now, delta) => {
|
|
128
|
-
onAnimate(now, delta);
|
|
129
|
-
if (camera.current && scene.current)
|
|
130
|
-
renderer.render(scene.current, camera.current);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (renderFunction)
|
|
135
|
-
renderFunction(performance.now(), 0);
|
|
136
|
-
}, [renderer, ...deps])
|
|
137
|
-
|
|
138
|
-
useAnimationFrame(renderFunction, [renderer, ...deps])
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/*::
|
|
142
|
-
export interface Disposable {
|
|
143
|
-
dispose(): void;
|
|
144
|
-
}
|
|
145
|
-
*/
|
|
146
|
-
|
|
147
|
-
export const useDisposable = /*:: <T: Disposable>*/(
|
|
148
|
-
create/*: () => T*/,
|
|
149
|
-
deps/*: mixed[]*/ = []
|
|
150
|
-
)/*: T*/ => {
|
|
151
|
-
const [resource, setResource] = useState/*:: <T>*/(() => create());
|
|
152
|
-
const disposedRef = useRef(false);
|
|
153
|
-
|
|
154
|
-
useEffect(() => {
|
|
155
|
-
const { current: disposed } = disposedRef
|
|
156
|
-
|
|
157
|
-
if (disposed) {
|
|
158
|
-
setResource(create());
|
|
159
|
-
disposedRef.current = false;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return () => {
|
|
163
|
-
resource.dispose();
|
|
164
|
-
disposedRef.current = true;
|
|
165
|
-
}
|
|
166
|
-
}, deps);
|
|
167
|
-
return resource;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export const useTexture = (url/*: string*/)/*: Texture*/ => {
|
|
171
|
-
const [texture, setTexture] = useState(null)
|
|
172
|
-
useEffect(() => {
|
|
173
|
-
const loader = new TextureLoader();
|
|
174
|
-
|
|
175
|
-
const texture = loader.load(url);
|
|
176
|
-
setTexture(texture);
|
|
177
|
-
|
|
178
|
-
return () => {
|
|
179
|
-
texture.dispose();
|
|
180
|
-
}
|
|
181
|
-
}, []);
|
|
182
|
-
|
|
183
|
-
if (!texture)
|
|
184
|
-
throw { type: 'loading' };
|
|
185
|
-
|
|
186
|
-
return texture;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
export * from './hooks/matrix.js';
|
package/objects.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { PropDiff } from '@lukekaalim/act-renderer-core'; */
|
|
3
|
-
import {
|
|
4
|
-
Group,
|
|
5
|
-
Mesh,
|
|
6
|
-
PerspectiveCamera,
|
|
7
|
-
PointLight,
|
|
8
|
-
Points,
|
|
9
|
-
Scene,
|
|
10
|
-
InstancedMesh,
|
|
11
|
-
OrthographicCamera,
|
|
12
|
-
DirectionalLight,
|
|
13
|
-
HemisphereLight,
|
|
14
|
-
AmbientLight,
|
|
15
|
-
Skeleton,
|
|
16
|
-
LineSegments,
|
|
17
|
-
Line,
|
|
18
|
-
LineLoop,
|
|
19
|
-
Bone,
|
|
20
|
-
Sprite,
|
|
21
|
-
LOD,
|
|
22
|
-
Object3D,
|
|
23
|
-
} from "three";
|
|
24
|
-
|
|
25
|
-
export const threeObjectClasses/*: { [string]: Class<Object3D> }*/ = Object.fromEntries(Object.entries({
|
|
26
|
-
// grouping
|
|
27
|
-
Scene,
|
|
28
|
-
Group,
|
|
29
|
-
Object3D,
|
|
30
|
-
|
|
31
|
-
// lights
|
|
32
|
-
DirectionalLight,
|
|
33
|
-
HemisphereLight,
|
|
34
|
-
PointLight,
|
|
35
|
-
AmbientLight,
|
|
36
|
-
|
|
37
|
-
// camera
|
|
38
|
-
PerspectiveCamera,
|
|
39
|
-
OrthographicCamera,
|
|
40
|
-
|
|
41
|
-
// lines
|
|
42
|
-
Points,
|
|
43
|
-
LineSegments,
|
|
44
|
-
Line,
|
|
45
|
-
LineLoop,
|
|
46
|
-
|
|
47
|
-
// skinning
|
|
48
|
-
Skeleton,
|
|
49
|
-
Bone,
|
|
50
|
-
|
|
51
|
-
Sprite,
|
|
52
|
-
|
|
53
|
-
// mesh
|
|
54
|
-
Mesh,
|
|
55
|
-
InstancedMesh,
|
|
56
|
-
LOD,
|
|
57
|
-
}).map(([key, value]) => [key.toLowerCase(), (value/*: any*/)]));
|
|
58
|
-
|
|
59
|
-
class UnsupportedObjectTypeError extends Error {}
|
|
60
|
-
|
|
61
|
-
export const createObject = (type/*: string*/)/*: Object3D*/ => {
|
|
62
|
-
const objectClass = threeObjectClasses[type.toLowerCase()];
|
|
63
|
-
|
|
64
|
-
if (!objectClass) {
|
|
65
|
-
throw new UnsupportedObjectTypeError()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return new objectClass();
|
|
69
|
-
};
|
package/props.d.ts
DELETED
package/props.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { WebGLRenderer, LightShadow } from "three"; */
|
|
3
|
-
/*::
|
|
4
|
-
import type { Props } from '@lukekaalim/act';
|
|
5
|
-
import type { PropDiff, PropDiffRegistry } from '@lukekaalim/act-renderer-core';
|
|
6
|
-
import type { CommitDiff, Diff3, DiffSet } from '@lukekaalim/act-reconciler';
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { calculatePropsDiff, setRef2 } from '@lukekaalim/act-renderer-core'
|
|
10
|
-
import { setHTMLProp } from "@lukekaalim/act-web";
|
|
11
|
-
import {
|
|
12
|
-
BufferGeometry,
|
|
13
|
-
Camera,
|
|
14
|
-
Color,
|
|
15
|
-
DirectionalLight,
|
|
16
|
-
Euler,
|
|
17
|
-
Group,
|
|
18
|
-
Light,
|
|
19
|
-
Material,
|
|
20
|
-
Matrix3,
|
|
21
|
-
Matrix4,
|
|
22
|
-
Object3D,
|
|
23
|
-
OrthographicCamera,
|
|
24
|
-
Quaternion,
|
|
25
|
-
Scene,
|
|
26
|
-
Vector2,
|
|
27
|
-
Vector3,
|
|
28
|
-
} from "three";
|
|
29
|
-
import { setRef } from "@lukekaalim/act-renderer-core";
|
|
30
|
-
import { scenePropSetters } from './components/scene';
|
|
31
|
-
|
|
32
|
-
export const setTransformProp = (target/*: mixed*/, diff/*: PropDiff*/)/*: boolean*/ => {
|
|
33
|
-
if (target instanceof Vector2 && diff.next instanceof Vector2) {
|
|
34
|
-
target.copy(diff.next);
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
if (target instanceof Vector3 && diff.next instanceof Vector3) {
|
|
38
|
-
target.copy(diff.next);
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
if (target instanceof Matrix3 && diff.next instanceof Matrix3) {
|
|
42
|
-
target.copy(diff.next);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
if (target instanceof Matrix4 && diff.next instanceof Matrix4) {
|
|
46
|
-
target.copy(diff.next);
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
if (target instanceof Quaternion && diff.next instanceof Quaternion) {
|
|
50
|
-
target.copy(diff.next);
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
if (target instanceof Euler && diff.next instanceof Euler) {
|
|
54
|
-
target.copy(diff.next);
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
export const setValueProp = (object/*: { [string]: mixed }*/, name/*: string*/, diff/*: PropDiff*/)/*: boolean*/ => {
|
|
60
|
-
if (typeof object[name] !== typeof diff.next)
|
|
61
|
-
return false;
|
|
62
|
-
|
|
63
|
-
switch (typeof object[name]) {
|
|
64
|
-
case 'string':
|
|
65
|
-
case 'number':
|
|
66
|
-
case 'boolean':
|
|
67
|
-
object[name] = diff.next;
|
|
68
|
-
return true;
|
|
69
|
-
default:
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export const setMeshProp = (object/*: { [string]: mixed }*/, name/*: string*/, diff/*: PropDiff*/)/*: boolean*/ => {
|
|
74
|
-
if (object[name] instanceof BufferGeometry && diff.next instanceof BufferGeometry) {
|
|
75
|
-
object[name] = diff.next;
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
if (object[name] instanceof Material && diff.next instanceof Material) {
|
|
79
|
-
object[name] = diff.next;
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
export const setInstanceProp = (object/*: { [string]: mixed }*/, name/*: string*/, diff/*: PropDiff*/)/*: boolean*/ => {
|
|
85
|
-
if (object[name] instanceof Color) {
|
|
86
|
-
if (diff.next instanceof Color || typeof diff.next === 'string' || typeof diff.next === 'number') {
|
|
87
|
-
object[name].set(diff.next)
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export const setLightShadowProps = (
|
|
95
|
-
diffs/*: PropDiffRegistry*/,
|
|
96
|
-
lightShadow/*: LightShadow*/,
|
|
97
|
-
) => {
|
|
98
|
-
for (const [key, propDiff] of diffs.map) {
|
|
99
|
-
const target = (lightShadow/*: any*/)[key];
|
|
100
|
-
if (setTransformProp(target, propDiff))
|
|
101
|
-
continue;
|
|
102
|
-
if (setValueProp((lightShadow/*: any*/), key, propDiff))
|
|
103
|
-
continue;
|
|
104
|
-
if (target instanceof Object3D) {
|
|
105
|
-
if (propDiff.next instanceof Object3D) {
|
|
106
|
-
(lightShadow/*: any*/)[key] = propDiff.next;
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const propRegistry = calculatePropsDiff((propDiff.prev/*: any*/) || {}, (propDiff.next/*: any*/) || {});
|
|
110
|
-
setObjectProps2(propRegistry, target);
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
console.warn(`Unhandled prop ${key}`, propDiff.next, target);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const skipProps = new Set(['ref', 'key', 'children'])
|
|
119
|
-
|
|
120
|
-
export const setObjectProps2 = (
|
|
121
|
-
diff/*: PropDiffRegistry*/,
|
|
122
|
-
object/*: Object3D*/,
|
|
123
|
-
) => {
|
|
124
|
-
for (const [key, propDiff] of diff.map) {
|
|
125
|
-
if (skipProps.has(key))
|
|
126
|
-
continue;
|
|
127
|
-
|
|
128
|
-
const target = (object/*: any*/)[key];
|
|
129
|
-
if (key === 'shadow' && object instanceof Light) {
|
|
130
|
-
const propRegistry = calculatePropsDiff((propDiff.prev/*: any*/) || {}, (propDiff.next/*: any*/) || {});
|
|
131
|
-
setLightShadowProps(propRegistry, target)
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (setInstanceProp((object/*: any*/), key, propDiff))
|
|
135
|
-
continue;
|
|
136
|
-
|
|
137
|
-
if (setMeshProp((object/*: any*/), key, propDiff)) {
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
if (setTransformProp(target, propDiff))
|
|
141
|
-
continue;
|
|
142
|
-
if (setValueProp((object/*: any*/), key, propDiff))
|
|
143
|
-
continue;
|
|
144
|
-
if (object instanceof Scene) {
|
|
145
|
-
const setter = scenePropSetters[propDiff.key];
|
|
146
|
-
if (setter) {
|
|
147
|
-
setter(object, propDiff.next, propDiff.prev);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
console.warn(`Unhandled prop ${key}`, propDiff.next, object);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (object instanceof OrthographicCamera)
|
|
158
|
-
object.updateProjectionMatrix();
|
|
159
|
-
|
|
160
|
-
}
|
package/reconciler.d.ts
DELETED
package/reconciler.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Element } from '@lukekaalim/act'; */
|
|
3
|
-
/*:: import type { Renderer } from '@lukekaalim/act-renderer-core'; */
|
|
4
|
-
|
|
5
|
-
import { createBoundaryService, createEffectService, createReconciler, createSchedule2, createTree, createTreeService2 } from "@lukekaalim/act-reconciler";
|
|
6
|
-
import { createNullRenderer2 } from "@lukekaalim/act-renderer-core";
|
|
7
|
-
import { createWebRenderer, setNodeChildren } from "@lukekaalim/act-web";
|
|
8
|
-
import { setNodeChildren2 } from "@lukekaalim/act-web/node";
|
|
9
|
-
|
|
10
|
-
import { createObjectRenderer } from "./renderer.js";
|
|
11
|
-
|
|
12
|
-
export const render = (element/*: Element*/, node/*: HTMLElement*/) => {
|
|
13
|
-
const webToThree = createNullRenderer2(() => object, ['three']);
|
|
14
|
-
const threeToWeb = createNullRenderer2(() => web, ['web']);
|
|
15
|
-
|
|
16
|
-
const object = createObjectRenderer((type) => {
|
|
17
|
-
switch (type) {
|
|
18
|
-
case 'web':
|
|
19
|
-
return threeToWeb;
|
|
20
|
-
default:
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
const web = createWebRenderer(type => {
|
|
25
|
-
switch (type) {
|
|
26
|
-
case 'scene':
|
|
27
|
-
case 'three':
|
|
28
|
-
return webToThree;
|
|
29
|
-
default:
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const scheduler = createSchedule2((callback) => {
|
|
35
|
-
const id = requestAnimationFrame(() => callback(16));
|
|
36
|
-
return () => cancelAnimationFrame(id);
|
|
37
|
-
})
|
|
38
|
-
const effect = createEffectService(scheduler);
|
|
39
|
-
const boundary = createBoundaryService();
|
|
40
|
-
|
|
41
|
-
const reconciler = createReconciler(scheduler);
|
|
42
|
-
|
|
43
|
-
reconciler.diff.subscribeDiff(set => {
|
|
44
|
-
const children = web.render(set, set.root);
|
|
45
|
-
setNodeChildren2(node, children);
|
|
46
|
-
|
|
47
|
-
reconciler.tree.live.registry = effect.runEffectRegistry(set.registry);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const map = boundary.calcBoundaryMap(set);
|
|
51
|
-
boundary.getRootBoundaryValue(set.suspensions, set, map);
|
|
52
|
-
})
|
|
53
|
-
reconciler.tree.mount(element);
|
|
54
|
-
};
|
package/renderer.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ElementType } from "@lukekaalim/act";
|
|
2
|
-
import { Renderer2 } from "@lukekaalim/act-renderer-core";
|
|
3
|
-
import { Object3D } from "three";
|
|
4
|
-
|
|
5
|
-
export declare function createObjectRenderer(
|
|
6
|
-
getNextRenderer?: null | ((type: ElementType) => null | Renderer2<Object3D>)
|
|
7
|
-
): Renderer2<Object3D>;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A scene renderer is just an object renderer connected to
|
|
11
|
-
* a null renderer
|
|
12
|
-
*/
|
|
13
|
-
export declare function createSceneRenderer<T>(): Renderer2<T>;
|
package/renderer.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
/*:: import type { Renderer, RenderResult, PropDiff } from '@lukekaalim/act-renderer-core'; */
|
|
3
|
-
/*:: import type { Component, ElementType } from '@lukekaalim/act'; */
|
|
4
|
-
/*:: import type { CommitDiff, CommitID } from '@lukekaalim/act-reconciler'; */
|
|
5
|
-
/*::
|
|
6
|
-
import type { Object3D } from 'three';
|
|
7
|
-
import type { Renderer2 } from "../core/renderer2";
|
|
8
|
-
*/
|
|
9
|
-
import { calculatePropsDiff, createRenderer2, createNullRenderer2, setRef2 } from '@lukekaalim/act-renderer-core';
|
|
10
|
-
import { createObject } from "./objects";
|
|
11
|
-
import { setObjectProps2 } from "./props";
|
|
12
|
-
|
|
13
|
-
export const createObjectRenderer = (
|
|
14
|
-
getNextRenderer/*: null | ((type: ElementType) => null | Renderer2<Object3D>)*/ = null
|
|
15
|
-
)/*: Renderer2<Object3D>*/ => {
|
|
16
|
-
|
|
17
|
-
const getRenderer = (set, commitId) => {
|
|
18
|
-
const commit = set.nexts.map.get(commitId) || set.prevs.get(commitId);
|
|
19
|
-
return getNextRenderer && getNextRenderer(commit.element.type) || objectRenderer;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const getNodes = (set, commitId) => {
|
|
23
|
-
const renderer = getRenderer(set, commitId)
|
|
24
|
-
return renderer.getNodes(set, commitId);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const render = (set, commitId) => {
|
|
28
|
-
const renderer = getRenderer(set, commitId)
|
|
29
|
-
return renderer.render(set, commitId);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const objectRenderer = createRenderer2({
|
|
33
|
-
remove(object) {
|
|
34
|
-
object.removeFromParent();
|
|
35
|
-
},
|
|
36
|
-
update(object, set, diff) {
|
|
37
|
-
setRef2(object, diff.commit, diff.change);
|
|
38
|
-
const prev = set.prevs.map.get(diff.commit.id);
|
|
39
|
-
const propDiff = calculatePropsDiff(prev ? prev.element.props : {}, diff.commit.element.props)
|
|
40
|
-
setObjectProps2(propDiff, object);
|
|
41
|
-
},
|
|
42
|
-
create(type) {
|
|
43
|
-
return createObject(type);
|
|
44
|
-
},
|
|
45
|
-
attach(object, set, diff, children) {
|
|
46
|
-
const missingChildren = children
|
|
47
|
-
.filter(n => n.parent !== object);
|
|
48
|
-
|
|
49
|
-
if (missingChildren.length > 0)
|
|
50
|
-
object.add(...missingChildren);
|
|
51
|
-
}
|
|
52
|
-
}, { getNodes, render });
|
|
53
|
-
|
|
54
|
-
return objectRenderer;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const createSceneRenderer = /*:: <T>*/()/*: Renderer2<T>*/ => {
|
|
58
|
-
const object = createObjectRenderer();
|
|
59
|
-
return createNullRenderer2(object);
|
|
60
|
-
}
|