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 { useResizeDetector } from 'react-resize-detector';
|
||||
import * as cs3DTools from '@cornerstonejs/tools';
|
||||
import { Enums, eventTarget, getEnabledElement } from '@cornerstonejs/core';
|
||||
import { MeasurementService } from '@ohif/core';
|
||||
@ -110,7 +109,23 @@ const OHIFCornerstoneViewport = React.memo(
|
||||
cornerstoneViewportService.resize();
|
||||
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(
|
||||
viewportInfo => {
|
||||
@ -350,10 +365,6 @@ const OHIFCornerstoneViewport = React.memo(
|
||||
}
|
||||
}, [displaySets, viewportId, viewportActionCornersService, servicesManager, commandsManager]);
|
||||
|
||||
const { ref: resizeRef } = useResizeDetector({
|
||||
onResize,
|
||||
});
|
||||
|
||||
const Notification = customizationService.getCustomization('ui.notificationComponent');
|
||||
|
||||
return (
|
||||
@ -364,10 +375,7 @@ const OHIFCornerstoneViewport = React.memo(
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
onContextMenu={e => e.preventDefault()}
|
||||
onMouseDown={e => e.preventDefault()}
|
||||
ref={el => {
|
||||
resizeRef.current = el;
|
||||
elementRef.current = el;
|
||||
}}
|
||||
ref={elementRef}
|
||||
></div>
|
||||
<CornerstoneOverlays
|
||||
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({
|
||||
cornerstoneViewportService,
|
||||
customizationService,
|
||||
|
||||
@ -38,6 +38,9 @@ const EVENTS = {
|
||||
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 };
|
||||
|
||||
/**
|
||||
@ -62,9 +65,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
beforeResizePositionPresentations: Map<string, PositionPresentation> = new Map();
|
||||
|
||||
// Some configs
|
||||
enableResizeDetector: true;
|
||||
resizeRefreshRateMs: 200;
|
||||
resizeRefreshMode: 'debounce';
|
||||
servicesManager: AppTypes.ServicesManager = null;
|
||||
|
||||
resizeQueue = [];
|
||||
@ -125,13 +125,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
/**
|
||||
* 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
|
||||
// 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.
|
||||
@ -147,12 +142,24 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
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
|
||||
// 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
|
||||
// we don't double resize the viewports when viewports in the grid are
|
||||
// resized individually
|
||||
if (isGridResize) {
|
||||
if (isEasyResize) {
|
||||
this.performResize();
|
||||
this.resetGridResizeTimeout();
|
||||
this.resizeQueue = [];
|
||||
|
||||
@ -35,9 +35,8 @@ export interface IViewportService {
|
||||
/**
|
||||
* It creates a resize observer for the viewport element, and observes
|
||||
* the element for resizing events
|
||||
* @param {*} elementRef
|
||||
*/
|
||||
resize(isGridResize: boolean): void;
|
||||
resize(): void;
|
||||
/**
|
||||
* Removes the viewport from cornerstone, and destroys the rendering engine
|
||||
*/
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import React, { useEffect, useCallback, useRef, useMemo } from 'react';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
import React, { useEffect, useCallback, useRef } from 'react';
|
||||
import { Types, MeasurementService } from '@ohif/core';
|
||||
import { ViewportGrid, ViewportPane } 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 { numCols, numRows } = layout;
|
||||
const { ref: resizeRef } = useResizeDetector({
|
||||
refreshMode: 'debounce',
|
||||
refreshRate: 7,
|
||||
refreshOptions: { leading: true },
|
||||
onResize: () => {
|
||||
viewportGridService.setViewportGridSizeChanged();
|
||||
},
|
||||
});
|
||||
const layoutHash = useRef(null);
|
||||
|
||||
const {
|
||||
@ -444,10 +435,7 @@ function ViewerViewportGrid(props: withAppTypes) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={resizeRef}
|
||||
className="border-input h-[calc(100%-0.25rem)] w-full border"
|
||||
>
|
||||
<div className="border-input h-[calc(100%-0.25rem)] w-full border">
|
||||
<ViewportGrid
|
||||
numRows={numRows}
|
||||
numCols={numCols}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user