@lukekaalim/act-three 5.1.0 → 5.2.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.
@@ -1,26 +1,37 @@
1
1
  // @flow strict
2
2
  /*:: import type { Component, Ref } from '@lukekaalim/act'; */
3
- /*:: import type { Euler, Group } from "three"; */
3
+ /*:: import type { Euler, Group, Object3D } from "three"; */
4
4
  /*:: import type { GroupProps, RefProp } from '../components'; */
5
5
 
6
6
  import { h, useEffect, useRef, useState } from '@lukekaalim/act';
7
7
  import { Matrix4, Vector3 } from "three";
8
8
  import { group } from '../components.js';
9
9
 
10
- export const LookAtGroup/*: Component<{ ...$Diff<GroupProps, { rotation?: Euler, ref?: RefProp<Group> }>, target: Vector3 }>*/ = ({
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>*/ = ({
11
19
  target,
12
20
  children,
13
21
  position = new Vector3(0, 0, 0),
22
+ deps = [],
14
23
  ...groupProps
15
24
  }) => {
16
- const [groupNode, setGroup] = useState(null);
25
+ const groupRef = useRef(null);
26
+
17
27
  useEffect(() => {
28
+ const { current: groupNode } = groupRef;
18
29
  if (!groupNode)
19
30
  return;
20
31
 
21
32
  groupNode.setRotationFromMatrix(new Matrix4().lookAt(position, target, new Vector3(0, 1, 0)));
22
33
  groupNode.updateMatrix();
23
- }, [groupNode, target.x, target.y, target.z, position.x, position.y, position.z]);
34
+ }, [target.x, target.y, target.z, position.x, position.y, position.z, ...deps]);
24
35
 
25
- return h(group, { ...groupProps, position, ref: setGroup }, children);
36
+ return h(group, { ...groupProps, position, ref: groupRef }, children);
26
37
  }
@@ -0,0 +1,28 @@
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.js CHANGED
@@ -21,12 +21,13 @@ export type WebGLOptions = {
21
21
  */
22
22
 
23
23
  export const useWebGLRenderer = (
24
- canvas/*: ?HTMLCanvasElement*/,
24
+ canvasRef/*: Ref<?HTMLCanvasElement>*/,
25
25
  options/*: WebGLOptions*/ = {},
26
26
  deps/*: mixed[]*/ = []
27
27
  )/*: ?WebGLRenderer*/ => {
28
28
  const [renderer, setRenderer] = useState/*:: <?WebGLRenderer>*/(null);
29
29
  useEffect(() => {
30
+ const { current: canvas } = canvasRef;
30
31
  if (!canvas)
31
32
  return;
32
33
 
@@ -38,7 +39,7 @@ export const useWebGLRenderer = (
38
39
  setRenderer(null);
39
40
  renderer.dispose();
40
41
  }
41
- }, [canvas, ...deps]);
42
+ }, deps);
42
43
 
43
44
  return renderer;
44
45
  };
@@ -46,9 +47,13 @@ export const useWebGLRenderer = (
46
47
  // Resize the canvas's resolution whenever it changes size
47
48
  // useful for when the canvas is some percentage of the screen
48
49
  // like: width: 100%
49
- export const useResizingRenderer = (canvas/*: ?HTMLCanvasElement*/, renderer/*: ?WebGLRenderer*/)/*: ?Vector2*/ => {
50
+ export const useResizingRenderer = (
51
+ canvasRef/*: Ref<?HTMLCanvasElement>*/,
52
+ renderer/*: ?WebGLRenderer*/
53
+ )/*: ?Vector2*/ => {
50
54
  const [size, setSize] = useState(null)
51
55
  useEffect(() => {
56
+ const { current: canvas } = canvasRef;
52
57
  if (!canvas || !renderer)
53
58
  return null;
54
59
 
@@ -67,16 +72,19 @@ export const useResizingRenderer = (canvas/*: ?HTMLCanvasElement*/, renderer/*:
67
72
  observer.unobserve(canvas);
68
73
  setSize(null);
69
74
  }
70
- }, [canvas, renderer]);
75
+ }, [renderer]);
71
76
 
72
77
  return size;
73
78
  }
74
79
 
75
80
  export const useAnimationFrame = (
76
- onAnimate/*: (now: DOMHighResTimeStamp, delta: number) => mixed*/,
81
+ onAnimate/*: ?(now: DOMHighResTimeStamp, delta: number) => mixed*/ = null,
77
82
  deps/*: mixed[]*/ = []
78
83
  ) => {
79
84
  useEffect(() => {
85
+ if (!onAnimate)
86
+ return;
87
+
80
88
  let lastFrame = performance.now();
81
89
  const animate = (now) => {
82
90
  const delta = now - lastFrame;
@@ -96,22 +104,23 @@ export const useAnimationFrame = (
96
104
 
97
105
  export const useRenderLoop = (
98
106
  renderer/*: ?WebGLRenderer*/,
99
- camera/*: ?Camera*/,
100
- scene/*: ?Scene*/,
107
+ camera/*: Ref<?Camera>*/,
108
+ scene/*: Ref<?Scene>*/,
101
109
  onAnimate/*: (now: DOMHighResTimeStamp, delta: number) => mixed*/ = (_, __) => {},
102
110
  deps/*: mixed[]*/ = []
103
111
  ) => {
104
- const renderFunction = renderer && camera && scene ? (now, delta) => {
112
+ const renderFunction = renderer && ((now, delta) => {
105
113
  onAnimate(now, delta);
106
- renderer.render(scene, camera);
107
- } : () => {};
114
+ if (camera.current && scene.current)
115
+ renderer.render(scene.current, camera.current);
116
+ });
108
117
 
109
118
  useEffect(() => {
110
- if (scene && camera && renderer)
111
- renderer.render(scene, camera);
112
- }, [renderer, camera, scene, ...deps])
119
+ if (renderFunction)
120
+ renderFunction(performance.now(), 0);
121
+ }, [renderer, ...deps])
113
122
 
114
- useAnimationFrame(renderFunction, [renderer, camera, scene, ...deps])
123
+ useAnimationFrame(renderFunction, [renderer, ...deps])
115
124
  }
116
125
 
117
126
  /*::
@@ -163,3 +172,6 @@ export const useTexture = (url/*: string*/)/*: Texture*/ => {
163
172
 
164
173
  return texture;
165
174
  };
175
+
176
+
177
+ export * from './hooks/matrix.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukekaalim/act-three",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "Render threejs content using act",
5
5
  "main": "entry.js",
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@lukekaalim/act": "^2.2.0",
19
- "@lukekaalim/act-renderer-core": "^3.0.0",
20
- "@lukekaalim/act-reconciler": "^2.1.0",
21
- "@lukekaalim/act-web": "^1.1.0"
19
+ "@lukekaalim/act-renderer-core": "^3.1.1",
20
+ "@lukekaalim/act-reconciler": "^3.0.0",
21
+ "@lukekaalim/act-web": "^1.2.0"
22
22
  }
23
23
  }
package/reconciler.js CHANGED
@@ -21,6 +21,7 @@ export const render = (element/*: Element*/, node/*: HTMLElement*/) => {
21
21
  const options = {
22
22
  onDiff,
23
23
  scheduleWork: (c) => requestAnimationFrame(() => void c()),
24
+ cancelWork: (t) => cancelAnimationFrame(t),
24
25
  };
25
26
  const tree = createTree(element, options);
26
27
  };