refactor(viewport): Remove resize detector and optimize viewport resizing logic (#5006)
This commit is contained in:
parent
6337d2e9cb
commit
383f45823c
@ -1,5 +1,4 @@
|
|||||||
import React, { useEffect, useRef, useCallback, useState } from 'react';
|
import React, { useEffect, useRef, useCallback, useState } from 'react';
|
||||||
import { useResizeDetector } from 'react-resize-detector';
|
|
||||||
import * as cs3DTools from '@cornerstonejs/tools';
|
import * as cs3DTools from '@cornerstonejs/tools';
|
||||||
import { Enums, eventTarget, getEnabledElement } from '@cornerstonejs/core';
|
import { Enums, eventTarget, getEnabledElement } from '@cornerstonejs/core';
|
||||||
import { MeasurementService } from '@ohif/core';
|
import { MeasurementService } from '@ohif/core';
|
||||||
@ -110,7 +109,23 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
cornerstoneViewportService.resize();
|
cornerstoneViewportService.resize();
|
||||||
setImageScrollBarHeight();
|
setImageScrollBarHeight();
|
||||||
}
|
}
|
||||||
}, [elementRef]);
|
}, [elementRef, cornerstoneViewportService, setImageScrollBarHeight]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const element = elementRef.current;
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(onResize);
|
||||||
|
resizeObserver.observe(element);
|
||||||
|
|
||||||
|
// Cleanup function
|
||||||
|
return () => {
|
||||||
|
resizeObserver.unobserve(element);
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
};
|
||||||
|
}, [onResize]);
|
||||||
|
|
||||||
const cleanUpServices = useCallback(
|
const cleanUpServices = useCallback(
|
||||||
viewportInfo => {
|
viewportInfo => {
|
||||||
@ -350,10 +365,6 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
}
|
}
|
||||||
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
||||||
|
|
||||||
const { ref: resizeRef } = useResizeDetector({
|
|
||||||
onResize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Notification = customizationService.getCustomization('ui.notificationComponent');
|
const Notification = customizationService.getCustomization('ui.notificationComponent');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -364,10 +375,7 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
onContextMenu={e => e.preventDefault()}
|
onContextMenu={e => e.preventDefault()}
|
||||||
onMouseDown={e => e.preventDefault()}
|
onMouseDown={e => e.preventDefault()}
|
||||||
ref={el => {
|
ref={elementRef}
|
||||||
resizeRef.current = el;
|
|
||||||
elementRef.current = el;
|
|
||||||
}}
|
|
||||||
></div>
|
></div>
|
||||||
<CornerstoneOverlays
|
<CornerstoneOverlays
|
||||||
viewportId={viewportId}
|
viewportId={viewportId}
|
||||||
|
|||||||
@ -232,16 +232,6 @@ export default async function init({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// resize the cornerstone viewport service when the grid size changes
|
|
||||||
// IMPORTANT: this should happen outside of the OHIFCornerstoneViewport
|
|
||||||
// since it will trigger a rerender of each viewport and each resizing
|
|
||||||
// the offscreen canvas which would result in a performance hit, this should
|
|
||||||
// done only once per grid resize here. Doing it once here, allows us to reduce
|
|
||||||
// the refreshRage(in ms) to 10 from 50. I tried with even 1 or 5 ms it worked fine
|
|
||||||
viewportGridService.subscribe(viewportGridService.EVENTS.GRID_SIZE_CHANGED, () => {
|
|
||||||
cornerstoneViewportService.resize(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
initContextMenu({
|
initContextMenu({
|
||||||
cornerstoneViewportService,
|
cornerstoneViewportService,
|
||||||
customizationService,
|
customizationService,
|
||||||
|
|||||||
@ -38,6 +38,9 @@ const EVENTS = {
|
|||||||
VIEWPORT_VOLUMES_CHANGED: 'event::cornerstoneViewportService:viewportVolumesChanged',
|
VIEWPORT_VOLUMES_CHANGED: 'event::cornerstoneViewportService:viewportVolumesChanged',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MIN_STACK_VIEWPORTS_TO_ENQUEUE_RESIZE = 12;
|
||||||
|
const MIN_VOLUME_VIEWPORTS_TO_ENQUEUE_RESIZE = 6;
|
||||||
|
|
||||||
export const WITH_NAVIGATION = { withNavigation: true, withOrientation: false };
|
export const WITH_NAVIGATION = { withNavigation: true, withOrientation: false };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,9 +65,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
|||||||
beforeResizePositionPresentations: Map<string, PositionPresentation> = new Map();
|
beforeResizePositionPresentations: Map<string, PositionPresentation> = new Map();
|
||||||
|
|
||||||
// Some configs
|
// Some configs
|
||||||
enableResizeDetector: true;
|
|
||||||
resizeRefreshRateMs: 200;
|
|
||||||
resizeRefreshMode: 'debounce';
|
|
||||||
servicesManager: AppTypes.ServicesManager = null;
|
servicesManager: AppTypes.ServicesManager = null;
|
||||||
|
|
||||||
resizeQueue = [];
|
resizeQueue = [];
|
||||||
@ -125,13 +125,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
|||||||
/**
|
/**
|
||||||
* It triggers the resize on the rendering engine, and renders the viewports
|
* It triggers the resize on the rendering engine, and renders the viewports
|
||||||
*
|
*
|
||||||
* @param isGridResize - if the resize is triggered by a grid resize
|
|
||||||
* this is used to avoid double resize of the viewports since if the
|
|
||||||
* grid is resized, all viewports will be resized so there is no need
|
|
||||||
* to resize them individually which will get triggered by their
|
|
||||||
* individual resize observers
|
|
||||||
*/
|
*/
|
||||||
public resize(isGridResize = false) {
|
public resize() {
|
||||||
// https://stackoverflow.com/a/26279685
|
// https://stackoverflow.com/a/26279685
|
||||||
// This resize() call, among other things, rerenders the viewports. But when the entire viewer is
|
// This resize() call, among other things, rerenders the viewports. But when the entire viewer is
|
||||||
// display: none'd, it makes the size of all hidden elements 0, including the viewport canvas and its containers.
|
// display: none'd, it makes the size of all hidden elements 0, including the viewport canvas and its containers.
|
||||||
@ -147,12 +142,24 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const numStackViewportsInViewportGrid = Array.from(this.viewportsById.values()).filter(
|
||||||
|
viewportInfo => viewportInfo.getViewportType() === csEnums.ViewportType.STACK
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const numVolumeViewportsInViewportGrid = Array.from(this.viewportsById.values()).filter(
|
||||||
|
viewportInfo => viewportInfo.getViewportType() === csEnums.ViewportType.ORTHOGRAPHIC
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const isEasyResize =
|
||||||
|
numStackViewportsInViewportGrid <= MIN_STACK_VIEWPORTS_TO_ENQUEUE_RESIZE &&
|
||||||
|
numVolumeViewportsInViewportGrid <= MIN_VOLUME_VIEWPORTS_TO_ENQUEUE_RESIZE;
|
||||||
|
|
||||||
// if there is a grid resize happening, it means the viewport grid
|
// if there is a grid resize happening, it means the viewport grid
|
||||||
// has been manipulated (e.g., panels closed, added, etc.) and we need
|
// has been manipulated (e.g., panels closed, added, etc.) and we need
|
||||||
// to resize all viewports, so we will add a timeout here to make sure
|
// to resize all viewports, so we will add a timeout here to make sure
|
||||||
// we don't double resize the viewports when viewports in the grid are
|
// we don't double resize the viewports when viewports in the grid are
|
||||||
// resized individually
|
// resized individually
|
||||||
if (isGridResize) {
|
if (isEasyResize) {
|
||||||
this.performResize();
|
this.performResize();
|
||||||
this.resetGridResizeTimeout();
|
this.resetGridResizeTimeout();
|
||||||
this.resizeQueue = [];
|
this.resizeQueue = [];
|
||||||
|
|||||||
@ -35,9 +35,8 @@ export interface IViewportService {
|
|||||||
/**
|
/**
|
||||||
* It creates a resize observer for the viewport element, and observes
|
* It creates a resize observer for the viewport element, and observes
|
||||||
* the element for resizing events
|
* the element for resizing events
|
||||||
* @param {*} elementRef
|
|
||||||
*/
|
*/
|
||||||
resize(isGridResize: boolean): void;
|
resize(): void;
|
||||||
/**
|
/**
|
||||||
* Removes the viewport from cornerstone, and destroys the rendering engine
|
* Removes the viewport from cornerstone, and destroys the rendering engine
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React, { useEffect, useCallback, useRef, useMemo } from 'react';
|
import React, { useEffect, useCallback, useRef } from 'react';
|
||||||
import { useResizeDetector } from 'react-resize-detector';
|
|
||||||
import { Types, MeasurementService } from '@ohif/core';
|
import { Types, MeasurementService } from '@ohif/core';
|
||||||
import { ViewportGrid, ViewportPane } from '@ohif/ui-next';
|
import { ViewportGrid, ViewportPane } from '@ohif/ui-next';
|
||||||
import { useViewportGrid } from '@ohif/ui-next';
|
import { useViewportGrid } from '@ohif/ui-next';
|
||||||
@ -13,14 +12,6 @@ function ViewerViewportGrid(props: withAppTypes) {
|
|||||||
|
|
||||||
const { layout, activeViewportId, viewports, isHangingProtocolLayout } = viewportGrid;
|
const { layout, activeViewportId, viewports, isHangingProtocolLayout } = viewportGrid;
|
||||||
const { numCols, numRows } = layout;
|
const { numCols, numRows } = layout;
|
||||||
const { ref: resizeRef } = useResizeDetector({
|
|
||||||
refreshMode: 'debounce',
|
|
||||||
refreshRate: 7,
|
|
||||||
refreshOptions: { leading: true },
|
|
||||||
onResize: () => {
|
|
||||||
viewportGridService.setViewportGridSizeChanged();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const layoutHash = useRef(null);
|
const layoutHash = useRef(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -444,10 +435,7 @@ function ViewerViewportGrid(props: withAppTypes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="border-input h-[calc(100%-0.25rem)] w-full border">
|
||||||
ref={resizeRef}
|
|
||||||
className="border-input h-[calc(100%-0.25rem)] w-full border"
|
|
||||||
>
|
|
||||||
<ViewportGrid
|
<ViewportGrid
|
||||||
numRows={numRows}
|
numRows={numRows}
|
||||||
numCols={numCols}
|
numCols={numCols}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user