fix(rerendering): reduce the re-rendering of the viewport grid (#3558)
This commit is contained in:
parent
cab8d322c2
commit
d8f628b125
@ -10,13 +10,7 @@ import {
|
||||
utilities as csUtils,
|
||||
} from '@cornerstonejs/core';
|
||||
import { MeasurementService } from '@ohif/core';
|
||||
import {
|
||||
CinePlayer,
|
||||
useCine,
|
||||
useViewportGrid,
|
||||
Notification,
|
||||
useViewportDialog,
|
||||
} from '@ohif/ui';
|
||||
import { Notification, useViewportDialog } from '@ohif/ui';
|
||||
import {
|
||||
IStackViewport,
|
||||
IVolumeViewport,
|
||||
@ -28,6 +22,7 @@ import './OHIFCornerstoneViewport.css';
|
||||
import CornerstoneOverlays from './Overlays/CornerstoneOverlays';
|
||||
import getSOPInstanceAttributes from '../utils/measurementServiceMappings/utils/getSOPInstanceAttributes';
|
||||
import CornerstoneServices from '../types/CornerstoneServices';
|
||||
import CinePlayer from '../components/CinePlayer';
|
||||
|
||||
const STACK = 'stack';
|
||||
|
||||
@ -127,8 +122,6 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
} = props;
|
||||
|
||||
const [scrollbarHeight, setScrollbarHeight] = useState('100px');
|
||||
const [{ isCineEnabled, cines }, cineService] = useCine();
|
||||
const [{ activeViewportIndex }] = useViewportGrid();
|
||||
const [enabledVPElement, setEnabledVPElement] = useState(null);
|
||||
const elementRef = useRef();
|
||||
|
||||
@ -145,74 +138,6 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
} = servicesManager.services as CornerstoneServices;
|
||||
|
||||
const [viewportDialogState] = useViewportDialog();
|
||||
|
||||
const cineHandler = () => {
|
||||
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cine = cines[viewportIndex];
|
||||
const isPlaying = cine.isPlaying || false;
|
||||
const frameRate = cine.frameRate || 24;
|
||||
|
||||
const validFrameRate = Math.max(frameRate, 1);
|
||||
|
||||
if (isPlaying) {
|
||||
cineService.playClip(enabledVPElement, {
|
||||
framesPerSecond: validFrameRate,
|
||||
});
|
||||
} else {
|
||||
cineService.stopClip(enabledVPElement);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
eventTarget.addEventListener(
|
||||
Enums.Events.STACK_VIEWPORT_NEW_STACK,
|
||||
cineHandler
|
||||
);
|
||||
|
||||
return () => {
|
||||
cineService.setCine({ id: viewportIndex, isPlaying: false });
|
||||
eventTarget.removeEventListener(
|
||||
Enums.Events.STACK_VIEWPORT_NEW_STACK,
|
||||
cineHandler
|
||||
);
|
||||
};
|
||||
}, [enabledVPElement]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
cineHandler();
|
||||
|
||||
return () => {
|
||||
if (enabledVPElement && cines?.[viewportIndex]?.isPlaying) {
|
||||
cineService.stopClip(enabledVPElement);
|
||||
}
|
||||
};
|
||||
}, [cines, viewportIndex, cineService, enabledVPElement, cineHandler]);
|
||||
|
||||
const cine = cines[viewportIndex];
|
||||
const isPlaying = (cine && cine.isPlaying) || false;
|
||||
|
||||
const handleCineClose = () => {
|
||||
toolbarService.recordInteraction({
|
||||
groupId: 'MoreTools',
|
||||
itemId: 'cine',
|
||||
interactionType: 'toggle',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleCine',
|
||||
commandOptions: {},
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
// useCallback for scroll bar height calculation
|
||||
const setImageScrollBarHeight = useCallback(() => {
|
||||
const scrollbarHeight = `${elementRef.current.clientHeight - 20}px`;
|
||||
@ -482,6 +407,8 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
};
|
||||
}, [displaySets, elementRef, viewportIndex]);
|
||||
|
||||
console.debug('OHIFCornerstoneViewport rendering');
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="viewport-wrapper">
|
||||
@ -505,25 +432,11 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
scrollbarHeight={scrollbarHeight}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
{isCineEnabled && (
|
||||
<CinePlayer
|
||||
className="absolute left-1/2 -translate-x-1/2 bottom-3"
|
||||
isPlaying={isPlaying}
|
||||
onClose={handleCineClose}
|
||||
onPlayPauseChange={isPlaying =>
|
||||
cineService.setCine({
|
||||
id: activeViewportIndex,
|
||||
isPlaying,
|
||||
})
|
||||
}
|
||||
onFrameRateChange={frameRate =>
|
||||
cineService.setCine({
|
||||
id: activeViewportIndex,
|
||||
frameRate,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<CinePlayer
|
||||
enabledVPElement={enabledVPElement}
|
||||
viewportIndex={viewportIndex}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute w-full">
|
||||
{viewportDialogState.viewportIndex === viewportIndex && (
|
||||
|
||||
107
extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx
Normal file
107
extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx
Normal file
@ -0,0 +1,107 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { CinePlayer, useCine, useViewportGrid } from '@ohif/ui';
|
||||
import { Enums, eventTarget } from '@cornerstonejs/core';
|
||||
|
||||
function WrappedCinePlayer({
|
||||
enabledVPElement,
|
||||
viewportIndex,
|
||||
servicesManager,
|
||||
}) {
|
||||
const { toolbarService, customizationService } = servicesManager.services;
|
||||
const [{ isCineEnabled, cines }, cineService] = useCine();
|
||||
const [{ activeViewportIndex }] = useViewportGrid();
|
||||
|
||||
const { component: CinePlayerComponent = CinePlayer } =
|
||||
customizationService.get('cinePlayer') ?? {};
|
||||
|
||||
const handleCineClose = () => {
|
||||
toolbarService.recordInteraction({
|
||||
groupId: 'MoreTools',
|
||||
itemId: 'cine',
|
||||
interactionType: 'toggle',
|
||||
commands: [
|
||||
{
|
||||
commandName: 'toggleCine',
|
||||
commandOptions: {},
|
||||
context: 'CORNERSTONE',
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
const cineHandler = () => {
|
||||
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cine = cines[viewportIndex];
|
||||
const isPlaying = cine.isPlaying || false;
|
||||
const frameRate = cine.frameRate || 24;
|
||||
|
||||
const validFrameRate = Math.max(frameRate, 1);
|
||||
|
||||
if (isPlaying) {
|
||||
cineService.playClip(enabledVPElement, {
|
||||
framesPerSecond: validFrameRate,
|
||||
});
|
||||
} else {
|
||||
cineService.stopClip(enabledVPElement);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
eventTarget.addEventListener(
|
||||
Enums.Events.STACK_VIEWPORT_NEW_STACK,
|
||||
cineHandler
|
||||
);
|
||||
|
||||
return () => {
|
||||
cineService.setCine({ id: viewportIndex, isPlaying: false });
|
||||
eventTarget.removeEventListener(
|
||||
Enums.Events.STACK_VIEWPORT_NEW_STACK,
|
||||
cineHandler
|
||||
);
|
||||
};
|
||||
}, [enabledVPElement]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
cineHandler();
|
||||
|
||||
return () => {
|
||||
if (enabledVPElement && cines?.[viewportIndex]?.isPlaying) {
|
||||
cineService.stopClip(enabledVPElement);
|
||||
}
|
||||
};
|
||||
}, [cines, viewportIndex, cineService, enabledVPElement, cineHandler]);
|
||||
|
||||
const cine = cines[viewportIndex];
|
||||
const isPlaying = (cine && cine.isPlaying) || false;
|
||||
|
||||
return (
|
||||
isCineEnabled && (
|
||||
<CinePlayerComponent
|
||||
className="absolute left-1/2 -translate-x-1/2 bottom-3"
|
||||
isPlaying={isPlaying}
|
||||
onClose={handleCineClose}
|
||||
onPlayPauseChange={isPlaying =>
|
||||
cineService.setCine({
|
||||
id: activeViewportIndex,
|
||||
isPlaying,
|
||||
})
|
||||
}
|
||||
onFrameRateChange={frameRate =>
|
||||
cineService.setCine({
|
||||
id: activeViewportIndex,
|
||||
frameRate,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default WrappedCinePlayer;
|
||||
@ -0,0 +1,3 @@
|
||||
import CinePlayer from './CinePlayer';
|
||||
|
||||
export default CinePlayer;
|
||||
@ -36,7 +36,7 @@ ContextMenu.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
action: PropTypes.func.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
),
|
||||
};
|
||||
|
||||
export default ContextMenu;
|
||||
|
||||
@ -184,7 +184,10 @@ const SplitButton = ({
|
||||
const listItemRenderer = renderer || DefaultListItemRenderer;
|
||||
|
||||
return (
|
||||
<OutsideClickHandler onOutsideClick={outsideClickHandler}>
|
||||
<OutsideClickHandler
|
||||
onOutsideClick={outsideClickHandler}
|
||||
disabled={!state.isExpanded}
|
||||
>
|
||||
<div name="SplitButton" className="relative">
|
||||
<div
|
||||
className={classes.Button({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user