Skip to content

Commit ccf7552

Browse files
committed
feat(ts/View): add camera props
1 parent 7ff0eaa commit ccf7552

File tree

2 files changed

+47
-19
lines changed

2 files changed

+47
-19
lines changed

src/core-ts/View/index.tsx

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ICameraInitialValues } from '@kitware/vtk.js/Rendering/Core/Camera';
12
import { Nullable, Vector3 } from '@kitware/vtk.js/types';
23
import {
34
CSSProperties,
@@ -12,6 +13,7 @@ import {
1213
import { IView } from '../../types';
1314
import { useOrderedUnmountContext } from '../../utils-ts/useOrderedUnmountEffect';
1415
import { ViewContext } from '../contexts';
16+
import useCamera from './useCamera';
1517
import useInteractor from './useInteractor';
1618
import useRenderer from './useRenderer';
1719
import useRenderWindow from './useRenderWindow';
@@ -59,24 +61,9 @@ interface Props extends PropsWithChildren {
5961
interactive?: boolean;
6062

6163
/**
62-
* Initial camera position from an object in [0,0,0]
64+
* Camera properties, such as position, focal point, etc.
6365
*/
64-
cameraPosition?: Vector3;
65-
66-
/**
67-
* Initial camera focal point from an object in [0,0,0]
68-
*/
69-
cameraFocalPoint?: Vector3;
70-
71-
/**
72-
* Initial camera position from an object in [0,0,0]
73-
*/
74-
cameraViewUp?: Vector3;
75-
76-
/**
77-
* Use parallel projection (default: false)
78-
*/
79-
cameraParallelProjection?: boolean;
66+
camera?: ICameraInitialValues;
8067

8168
/**
8269
* Whether to automatically call resetCamera() (default: true)
@@ -174,6 +161,7 @@ export default forwardRef(function View(props: Props, fwdRef) {
174161
background = DefaultProps.background,
175162
interactive = DefaultProps.interactive,
176163
autoResetCamera = DefaultProps.autoResetCamera,
164+
camera: cameraProps,
177165
} = props;
178166

179167
const containerRef = useRef<Nullable<HTMLDivElement>>(null);
@@ -189,6 +177,7 @@ export default forwardRef(function View(props: Props, fwdRef) {
189177
interactive
190178
);
191179

180+
// handle renders
192181
const [renderRequested, setRenderRequested] = useState(false);
193182
const requestRender = () => setRenderRequested(true);
194183

@@ -202,13 +191,17 @@ export default forwardRef(function View(props: Props, fwdRef) {
202191
}
203192
}, [renderRequested, autoResetCamera, getRenderer, getRenderWindow]);
204193

194+
// camera
195+
const getCamera = useCamera(getRenderer, requestRender, cameraProps);
196+
197+
// view API
205198
const view = useMemo<IView>(() => {
206199
return {
207200
getRenderer,
208201
getRenderWindow,
209202
getInteractor,
210203
getAPISpecificRenderWindow: getRWView,
211-
getCamera: () => getRenderer().getActiveCamera(),
204+
getCamera,
212205
/**
213206
* Requests a vtk.js render.
214207
*
@@ -224,11 +217,12 @@ export default forwardRef(function View(props: Props, fwdRef) {
224217
requestRender();
225218
},
226219
};
227-
}, [getRWView, getRenderer, getRenderWindow, getInteractor]);
220+
}, [getRWView, getRenderer, getRenderWindow, getInteractor, getCamera]);
228221

229222
// expose the view as a ref for imperative control
230223
useImperativeHandle(fwdRef, () => view);
231224

225+
// handle resizing
232226
useViewResize(containerRef, view);
233227

234228
const { style = DefaultProps.style } = props;

src/core-ts/View/useCamera.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ICameraInitialValues } from '@kitware/vtk.js/Rendering/Core/Camera';
2+
import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
3+
import { useCallback } from 'react';
4+
import { compareShallowObject } from '../../utils-ts/comparators';
5+
import useComparableEffect from '../../utils-ts/useComparableEffect';
6+
7+
export default function useCamera(
8+
getRenderer: () => vtkRenderer,
9+
requestRender: () => void,
10+
cameraProps?: ICameraInitialValues
11+
) {
12+
const getCamera = useCallback(
13+
() => getRenderer().getActiveCamera(),
14+
[getRenderer]
15+
);
16+
17+
useComparableEffect(
18+
() => {
19+
if (!cameraProps) return;
20+
const camera = getCamera();
21+
const mtime = camera.getMTime();
22+
camera.set(cameraProps);
23+
// camera.set doesn't return whether a change occurred,
24+
// since setPosition/etc. don't return this flag.
25+
if (mtime < camera.getMTime()) {
26+
requestRender();
27+
}
28+
},
29+
[cameraProps],
30+
([cur], [prev]) => compareShallowObject(cur, prev)
31+
);
32+
33+
return getCamera;
34+
}

0 commit comments

Comments
 (0)