scrollToActive fixed

This commit is contained in:
mrjvs 2023-03-19 19:10:56 +01:00
parent 37d5aaede9
commit ffe817388a

View File

@ -43,6 +43,8 @@ export function ScrollToActive(props: ScrollToActiveProps) {
const ref = createRef<HTMLDivElement>(); const ref = createRef<HTMLDivElement>();
const inited = useRef<boolean>(false); const inited = useRef<boolean>(false);
const SAFE_OFFSET = 30;
// Scroll to "active" child on first load (AKA mount except React dumb) // Scroll to "active" child on first load (AKA mount except React dumb)
useEffect(() => { useEffect(() => {
if (inited.current) return; if (inited.current) return;
@ -61,27 +63,31 @@ export function ScrollToActive(props: ScrollToActiveProps) {
wrapper?.querySelector(".active"); wrapper?.querySelector(".active");
if (wrapper && active) { if (wrapper && active) {
let activeYPositionCentered = 0; let wrapperHeight = 0;
const setActiveYPositionCentered = () => { let activePos = 0;
activeYPositionCentered = let activeHeight = 0;
active.getBoundingClientRect().top - let wrapperScroll = 0;
wrapper.getBoundingClientRect().top +
active.offsetHeight / 2; const getCoords = () => {
const activeRect = active.getBoundingClientRect();
const wrapperRect = wrapper.getBoundingClientRect();
wrapperHeight = wrapperRect.height;
activeHeight = activeRect.height;
activePos = activeRect.top - wrapperRect.top + wrapper.scrollTop;
wrapperScroll = wrapper.scrollTop;
}; };
setActiveYPositionCentered(); getCoords();
if (activeYPositionCentered >= wrapper.offsetHeight / 2) { const isVisible =
// Check if the active element is below the vertical center line, then scroll it into center activePos + activeHeight <
wrapperScroll + wrapperHeight - SAFE_OFFSET ||
activePos > wrapperScroll + SAFE_OFFSET;
if (isVisible) {
const activeMiddlePos = activePos + activeHeight / 2; // pos of middle of active element
const viewMiddle = wrapperHeight / 2; // half of the available height
const pos = activeMiddlePos - viewMiddle;
wrapper.scrollTo({ wrapper.scrollTo({
top: activeYPositionCentered - wrapper.offsetHeight / 2, top: pos,
});
}
setActiveYPositionCentered();
if (activeYPositionCentered > wrapper.offsetHeight / 2) {
// If the element is over the vertical center line, scroll to the end
wrapper.scrollTo({
top: wrapper.scrollHeight,
}); });
} }
} }