mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +01:00
scrollToActive fixed
This commit is contained in:
parent
37d5aaede9
commit
ffe817388a
1 changed files with 24 additions and 18 deletions
|
@ -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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue