diff --git a/apps/storybook/src/Utilities.mdx b/apps/storybook/src/Utilities.mdx index 3f67c7f96..f716fe320 100644 --- a/apps/storybook/src/Utilities.mdx +++ b/apps/storybook/src/Utilities.mdx @@ -378,20 +378,24 @@ useGeometry< >( Ctor: new (len: number) => H5WebGeometry, dataLength: number, - params: Params | false | undefined, // skip updates by passing `false` or `undefined` - isInteractive = false, // `true` to recompute bounding sphere on every update for raycasting purposes + params: Params, + config?: { + skipUpdates?: boolean; // set to `true` when R3F object is hidden + isInteractive?: boolean; // set to `true` to keep bounding sphere up to date for raycaster + }, ): H5WebGeometry const lineGeometry = useGeometry( LineGeometry, ordinates.length, - visible && { + { abscissas, ordinates, abscissaScale, ordinateScale, ignoreValue, }, + { skipUpdates: !visible } ); ``` diff --git a/packages/lib/src/vis/hooks.ts b/packages/lib/src/vis/hooks.ts index 768ed69a1..870612b18 100644 --- a/packages/lib/src/vis/hooks.ts +++ b/packages/lib/src/vis/hooks.ts @@ -108,37 +108,53 @@ export function useGeometry< >( Ctor: new (len: number) => H5WebGeometry, dataLength: number, - params: Params | false | undefined, // skip updates by passing `false` or `undefined` - isInteractive = false, // keep bounding sphere up to date for raycaster + params: Params, + config: { + skipUpdates?: boolean; // set to `true` when R3F object is hidden + isInteractive?: boolean; // set to `true` to keep bounding sphere up to date for raycaster + } = {}, ): H5WebGeometry { + const { skipUpdates = false, isInteractive = false } = config; + const geometry = useMemo(() => new Ctor(dataLength), [Ctor, dataLength]); const invalidate = useThree((state) => state.invalidate); - useLayoutEffect(() => { - if (!params) { - return; - } - - geometry.prepare(params); - - for (let i = 0; i < dataLength; i += 1) { - geometry.update(i); - } - - if (isInteractive) { - geometry.computeBoundingSphere(); // https://github.com/mrdoob/three.js/issues/1170#issuecomment-3617180 - } - - Object.values(geometry.attributes).forEach((attr) => { - attr.needsUpdate = true; - }); - - if (geometry.index) { - geometry.index.needsUpdate = true; - } - - invalidate(); - }, [geometry, ...Object.values(params || {}), invalidate]); // eslint-disable-line react-hooks/exhaustive-deps + useLayoutEffect( + () => { + if (skipUpdates) { + return; + } + + geometry.prepare(params); + + for (let i = 0; i < dataLength; i += 1) { + geometry.update(i); + } + + if (isInteractive) { + geometry.computeBoundingSphere(); // https://github.com/mrdoob/three.js/issues/1170#issuecomment-3617180 + } + + Object.values(geometry.attributes).forEach((attr) => { + attr.needsUpdate = true; + }); + + if (geometry.index) { + geometry.index.needsUpdate = true; + } + + invalidate(); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + geometry, + dataLength, + ...Object.values(params), // eslint-disable-line react-hooks/exhaustive-deps + skipUpdates, + isInteractive, + invalidate, + ], + ); return geometry; } diff --git a/packages/lib/src/vis/line/ErrorBars.tsx b/packages/lib/src/vis/line/ErrorBars.tsx index a2815aa7b..b2ebf84a5 100644 --- a/packages/lib/src/vis/line/ErrorBars.tsx +++ b/packages/lib/src/vis/line/ErrorBars.tsx @@ -20,7 +20,7 @@ function ErrorBars(props: Props) { const { abscissas, ordinates, errors, color, visible, ignoreValue } = props; const { abscissaScale, ordinateScale } = useVisCanvasContext(); - const geometryParams = visible && { + const geometryParams = { abscissas, ordinates, errors, @@ -33,12 +33,14 @@ function ErrorBars(props: Props) { ErrorBarsGeometry, ordinates.length, geometryParams, + { skipUpdates: !visible }, ); const capsGeometry = useGeometry( ErrorCapsGeometry, ordinates.length, geometryParams, + { skipUpdates: !visible }, ); return ( diff --git a/packages/lib/src/vis/line/Glyphs.tsx b/packages/lib/src/vis/line/Glyphs.tsx index 8bbb24795..172c00a3f 100644 --- a/packages/lib/src/vis/line/Glyphs.tsx +++ b/packages/lib/src/vis/line/Glyphs.tsx @@ -35,14 +35,17 @@ function Glyphs(props: Props) { const geometry = useGeometry( GlyphsGeometry, ordinates.length, - visible && { + { abscissas, ordinates, abscissaScale, ordinateScale, ignoreValue, }, - hasR3FEventHandlers(pointsProps), + { + skipUpdates: !visible, + isInteractive: hasR3FEventHandlers(pointsProps), + }, ); return ( diff --git a/packages/lib/src/vis/line/Line.tsx b/packages/lib/src/vis/line/Line.tsx index cccc7f092..8cd3ccde6 100644 --- a/packages/lib/src/vis/line/Line.tsx +++ b/packages/lib/src/vis/line/Line.tsx @@ -41,14 +41,17 @@ function Line(props: Props) { const geometry = useGeometry( LineGeometry, ordinates.length, - visible && { + { abscissas, ordinates, abscissaScale, ordinateScale, ignoreValue, }, - hasR3FEventHandlers(lineProps), + { + skipUpdates: !visible, + isInteractive: hasR3FEventHandlers(lineProps), + }, ); return ( diff --git a/packages/lib/src/vis/scatter/ScatterPoints.tsx b/packages/lib/src/vis/scatter/ScatterPoints.tsx index 3cc4f5b44..d98841da4 100644 --- a/packages/lib/src/vis/scatter/ScatterPoints.tsx +++ b/packages/lib/src/vis/scatter/ScatterPoints.tsx @@ -96,7 +96,7 @@ function ScatterPoints(props: Props) { colorScale, interpolator, }, - true, + { isInteractive: true }, ); return (