1+ import vtkInteractorStyle from '@kitware/vtk.js/Interaction/Style/InteractorStyle' ;
12import { ICameraInitialValues } from '@kitware/vtk.js/Rendering/Core/Camera' ;
2- import { Nullable , Vector3 } from '@kitware/vtk.js/types' ;
3+ import { Bounds , Nullable , Vector3 } from '@kitware/vtk.js/types' ;
34import {
45 CSSProperties ,
56 forwardRef ,
67 PropsWithChildren ,
8+ useCallback ,
79 useEffect ,
810 useImperativeHandle ,
911 useMemo ,
@@ -84,18 +86,11 @@ interface Props extends PropsWithChildren {
8486 autoResetCamera ?: boolean ;
8587
8688 /**
87- * Property use to trigger a render when changing.
88-
89- * TODO remove because the recommended way is to use a ref
90- */
91- // triggerRender?: number;
92-
93- /**
94- * Property use to trigger a resetCamera when changing.
89+ * Whether to automatically re-set the interactor style's center of rotation. (default: true)
9590 *
96- * TODO remove because the recommended way is to use a ref
91+ * This is a convenience property for interactor styles that support setCenterOfRotation().
9792 */
98- // triggerResetCamera ?: number ;
93+ autoCenterOfRotation ?: boolean ;
9994
10095 /**
10196 * List of picking listeners to bind. By default it is disabled (empty array).
@@ -152,6 +147,7 @@ interface Props extends PropsWithChildren {
152147const DefaultProps = {
153148 interactive : true ,
154149 autoResetCamera : true ,
150+ autoCenterOfRotation : true ,
155151 background : [ 0.2 , 0.3 , 0.4 ] as Vector3 ,
156152 style : {
157153 width : '100%' ,
@@ -202,6 +198,7 @@ export default forwardRef(function View(props: Props, fwdRef) {
202198 background = DefaultProps . background ,
203199 interactive = DefaultProps . interactive ,
204200 autoResetCamera = DefaultProps . autoResetCamera ,
201+ autoCenterOfRotation = DefaultProps . autoCenterOfRotation ,
205202 interactorSettings = DefaultProps . interactorSettings ,
206203 camera : cameraProps ,
207204 } = props ;
@@ -223,31 +220,53 @@ export default forwardRef(function View(props: Props, fwdRef) {
223220 useInteractorStyle ( getInteractor ) ;
224221 useInteractorStyleManipulatorSettings ( getInteractorStyle , interactorSettings ) ;
225222
226- // handle renders
223+ // --- rendering state --- //
224+
227225 const [ renderRequested , setRenderRequested ] = useState ( false ) ;
228226 const requestRender = ( ) => setRenderRequested ( true ) ;
229227
228+ // --- camera --- //
229+
230+ const getCamera = useCamera ( getRenderer , requestRender , cameraProps ) ;
231+
232+ const resetCamera = useCallback (
233+ ( boundsToUse ?: Bounds ) => {
234+ getRenderer ( ) . resetCamera ( boundsToUse ) ;
235+ if (
236+ autoCenterOfRotation &&
237+ 'setCenterOfRotation' in getInteractorStyle ( )
238+ ) {
239+ const style = getInteractorStyle ( ) as vtkInteractorStyle & {
240+ setCenterOfRotation ( center : Vector3 ) : boolean ;
241+ } ;
242+ style . setCenterOfRotation ( getCamera ( ) . getFocalPoint ( ) ) ;
243+ }
244+ } ,
245+ [ autoCenterOfRotation , getRenderer , getInteractorStyle , getCamera ]
246+ ) ;
247+
248+ // --- handle renders --- //
249+
230250 useEffect ( ( ) => {
231251 if ( renderRequested ) {
232252 if ( autoResetCamera ) {
233- getRenderer ( ) . resetCamera ( ) ;
253+ resetCamera ( ) ;
234254 }
235255 getRenderWindow ( ) . render ( ) ;
236256 setRenderRequested ( false ) ;
237257 }
238- } , [ renderRequested , autoResetCamera , getRenderer , getRenderWindow ] ) ;
258+ } , [ renderRequested , autoResetCamera , resetCamera , getRenderWindow ] ) ;
239259
240- // camera
241- const getCamera = useCamera ( getRenderer , requestRender , cameraProps ) ;
260+ // --- view API --- //
242261
243- // view API
244262 const view = useMemo < IView > ( ( ) => {
245263 return {
246264 getRenderer,
247265 getRenderWindow,
248266 getInteractor,
249267 getAPISpecificRenderWindow : getRWView ,
250268 getCamera,
269+ getInteractorStyle,
251270 setInteractorStyle,
252271 /**
253272 * Requests a vtk.js render.
@@ -259,8 +278,8 @@ export default forwardRef(function View(props: Props, fwdRef) {
259278 /**
260279 * Resets the camera.
261280 */
262- resetCamera : ( ) => {
263- getRenderer ( ) . resetCamera ( ) ;
281+ resetCamera : ( boundsToUse ?: Bounds ) => {
282+ resetCamera ( boundsToUse ) ;
264283 requestRender ( ) ;
265284 } ,
266285 } ;
@@ -270,7 +289,9 @@ export default forwardRef(function View(props: Props, fwdRef) {
270289 getRenderWindow ,
271290 getInteractor ,
272291 getCamera ,
292+ getInteractorStyle ,
273293 setInteractorStyle ,
294+ resetCamera ,
274295 ] ) ;
275296
276297 // expose the view as a ref for imperative control
0 commit comments