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 80 81 82 83 84 | 1x 94x 106x 55x 55x 7x 7x 55x 55x 55x 55x 21x 21x 55x 18x 18x 55x 55x 55x 7x 4x 3x 48x 48x 15x 33x 17x 46x 40x 6x | import type { DOMHelper, Rect } from 'roosterjs-content-model-types';
/**
* Scroll a given rectangle into view within a scroll container
* @param scrollContainer The container to scroll
* @param visibleRect The currently visible rectangle within the scroll container
* @param domHelper The DOM helper of the editor
* @param targetRect The target rectangle to scroll into view
* @param scrollMargin Optional margin to apply when scrolling
* @param preferTop Optional flag to indicate whether to prefer aligning the top or bottom of the target rect when the target rect is higher than visible rect @default false
*/
export function scrollRectIntoView(
scrollContainer: HTMLElement,
visibleRect: Rect,
domHelper: DOMHelper,
targetRect: Rect,
scrollMargin: number = 0,
preferTop: boolean = false
) {
let zoomScale: number | undefined;
let margin = 0;
if (scrollMargin != 0) {
zoomScale = getZoomScale(domHelper, zoomScale);
margin = Math.max(
0,
Math.min(
scrollMargin * zoomScale,
(visibleRect.bottom - visibleRect.top - targetRect.bottom + targetRect.top) / 2
)
);
}
const top = targetRect.top - margin;
const bottom = targetRect.bottom + margin;
const height = bottom - top;
// Define scroll operations
const scrollUp = () => {
zoomScale = getZoomScale(domHelper, zoomScale);
scrollContainer.scrollTop -= (visibleRect.top - top) / zoomScale;
};
const scrollDown = () => {
zoomScale = getZoomScale(domHelper, zoomScale);
scrollContainer.scrollTop += (bottom - visibleRect.bottom) / zoomScale;
};
// Determine which operations to perform and in what order
const needsScrollUp = top < visibleRect.top;
const needsScrollDown = bottom > visibleRect.bottom;
if (height > visibleRect.bottom - visibleRect.top) {
// If the target rect is larger than visible rect, only perform one scroll operation
if (preferTop) {
scrollUp();
} else {
scrollDown();
}
} else Iif (preferTop) {
if (needsScrollUp) {
scrollUp();
} else if (needsScrollDown) {
scrollDown();
}
} else {
if (needsScrollDown) {
scrollDown();
} else if (needsScrollUp) {
scrollUp();
}
}
}
// domHelper.calculateZoomScale() may be an expensive call, so we cache the value during a single operation
function getZoomScale(domHelper: DOMHelper, knownZoomScale: number | undefined): number {
if (knownZoomScale === undefined) {
return domHelper.calculateZoomScale();
} else {
return knownZoomScale;
}
}
|