refactor(viewport): Remove resize detector and optimize viewport resizing logic (#5006)

This commit is contained in:
Alireza authored and GitHub committed 2025-05-05 11:27:26 -04:00
1 parent 6337d2e9cb
commit 383f45823c
5 files changed
+38 -46

No files matched your search

@@ -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}
-10
View File
@@ -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
*/