Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import { Events, OrientationAxis } from '../../../enums';
import triggerEvent from '../../../utilities/triggerEvent';
import type { IImage } from '../../../types';
import type { PlanarViewState } from './PlanarViewportTypes';
interface PlanarImageEventContext {
viewportId: string;
renderingEngineId: string;
viewport: { element: HTMLDivElement };
}
interface PlanarNewImageArgs {
image?: IImage;
imageId?: string;
imageIdIndex?: number;
}
export function triggerPlanarNewImage(
ctx: PlanarImageEventContext,
args: PlanarNewImageArgs = {}
): void {
triggerEvent(ctx.viewport.element, Events.STACK_NEW_IMAGE, {
image: args.image,
imageId: args.imageId ?? args.image?.imageId,
imageIdIndex: args.imageIdIndex,
viewportId: ctx.viewportId,
renderingEngineId: ctx.renderingEngineId,
});
}
export function triggerPlanarVolumeNewImage(
ctx: PlanarImageEventContext,
params: {
camera: PlanarViewState | undefined;
acquisitionOrientation?: PlanarViewState['orientation'];
imageIds: string[];
imageIdIndex: number | undefined;
maxImageIdIndex: number;
}
): void {
const orientation = params.camera?.orientation;
const isAcquisitionAligned =
!orientation ||
orientation === OrientationAxis.ACQUISITION ||
(params.acquisitionOrientation !== undefined &&
orientation === params.acquisitionOrientation);
if (
isAcquisitionAligned &&
typeof params.imageIdIndex === 'number' &&
params.imageIds[params.imageIdIndex]
) {
triggerPlanarNewImage(ctx, {
imageId: params.imageIds[params.imageIdIndex],
imageIdIndex: params.imageIdIndex,
});
} else {
triggerPlanarNewImage(ctx);
}
// A volume-backed slice change must also emit VOLUME_NEW_IMAGE so that
// volume-aware consumers (volume scroll indicators, MPR slice synchronizers,
// segmentation slice tracking) react. The native volume-slice path previously
// emitted only STACK_NEW_IMAGE, which those consumers do not listen for, so
// every slice change on a PLANAR_NEXT volume viewport was missed.
//
// Only emit when the slice index is known: defaulting an unknown index to 0
// would incorrectly snap volume-aware consumers to the first slice (this
// happens on oblique/reformatted planes that do not map to a discrete index).
if (typeof params.imageIdIndex === 'number') {
triggerEvent(ctx.viewport.element, Events.VOLUME_NEW_IMAGE, {
imageIndex: params.imageIdIndex,
numberOfSlices: params.maxImageIdIndex + 1,
viewportId: ctx.viewportId,
renderingEngineId: ctx.renderingEngineId,
});
}
}
|