[TScroller, TVirtualGridList, AutoScrollArea] autofocus 로직 분리, 가독성 향상을 위한 리팩토링-수정

This commit is contained in:
hyunwoo93.cha
2024-02-29 13:35:06 +09:00
parent d14b7bf365
commit f0be1b1af4
2 changed files with 101 additions and 90 deletions

View File

@@ -1,9 +1,10 @@
import React, { useCallback } from "react";
import React, { useCallback, useRef } from "react";
import classNames from "classnames";
import Spottable from "@enact/spotlight/Spottable";
import { AUTO_SCROLL_GAP } from "../../utils/Config";
import css from "./AutoScrollArea.module.less";
const AutoScrollComponent = Spottable("div");
@@ -15,12 +16,92 @@ const POSITION = {
bottom: "bottom",
};
export default function AutoScrollArea({ position, onFocus, onBlur }) {
export default function AutoScrollArea({
position,
autoScroll,
scrollHorizontalPos,
scrollVerticalPos,
scrollToRef,
scrollPosition,
direction,
}) {
const requestIdRef = useRef();
const handleFocusAutoScroll = useCallback(() => {
if (!autoScroll) return;
const scrollStep =
position === "right" || position === "bottom"
? AUTO_SCROLL_GAP
: -AUTO_SCROLL_GAP;
let start = null;
const animationScroll = (timestamp) => {
if (!start) start = timestamp;
const progress = timestamp - start;
const step = Math.min(progress / 1000, 1);
if (direction === "horizontal") {
scrollHorizontalPos.current += scrollStep * step;
scrollToRef.current({
position: { x: scrollHorizontalPos.current },
animate: false,
});
} else if (direction === "vertical") {
scrollVerticalPos.current += scrollStep * step;
scrollToRef.current({
position: { y: scrollVerticalPos.current },
animate: false,
});
}
if (
direction === "horizontal" &&
((position === "right" && scrollPosition.current === "right") ||
(position === "left" && scrollPosition.current === "left"))
) {
if (typeof window === "object") {
window.cancelAnimationFrame(requestIdRef.current);
}
} else if (
direction === "vertical" &&
((position === "bottom" && scrollPosition.current === "bottom") ||
(position === "top" && scrollPosition.current === "top"))
) {
if (typeof window === "object") {
window.cancelAnimationFrame(requestIdRef.current);
}
} else {
if (typeof window === "object") {
requestIdRef.current = window.requestAnimationFrame(animationScroll);
}
}
};
if (typeof window === "object") {
requestIdRef.current = window.requestAnimationFrame(animationScroll);
}
}, [
autoScroll,
position,
scrollHorizontalPos,
scrollVerticalPos,
scrollToRef,
scrollPosition,
direction,
]);
const handleBlur = useCallback(() => {
if (requestIdRef.current && typeof window === "object") {
window.cancelAnimationFrame(requestIdRef.current);
}
}, [autoScroll, direction]);
return (
<AutoScrollComponent
className={classNames(css.autoScrollArea, position && css[position])}
onFocus={onFocus}
onBlur={onBlur}
onFocus={handleFocusAutoScroll}
onBlur={handleBlur}
/>
);
}

View File

@@ -5,9 +5,9 @@ import { useSelector } from "react-redux";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import { AUTO_SCROLL_GAP } from "../../utils/Config";
import { scaleH, scaleW } from "../../utils/helperMethods";
import AutoScrollArea, { POSITION } from "../AutoScrollArea/AutoScrollArea";
import { getRelevantPositions } from "../TScroller/TScroller";
import css from "./TVirtualGridList.module.less";
export default function TVirtualGridList({
@@ -36,7 +36,6 @@ export default function TVirtualGridList({
const scrollPosition = useRef("top");
const scrollToRef = useRef(null);
const requestIdRef = useRef();
const scrollHorizontalPos = useRef(0);
const scrollVerticalPos = useRef(0);
@@ -92,62 +91,7 @@ export default function TVirtualGridList({
[cbScrollTo]
);
const handleFocusAutoScroll = useCallback((position) => {
if (!autoScroll) return;
const scrollStep =
position === POSITION.right || position === POSITION.bottom
? AUTO_SCROLL_GAP
: -AUTO_SCROLL_GAP;
let start = null;
const animateScroll = (timestamp) => {
if (!start) start = timestamp;
const progress = timestamp - start;
const step = Math.min(progress / 1000, 1);
if (direction === "horizontal") {
scrollHorizontalPos.current += scrollStep * step;
scrollToRef.current({
position: { x: scrollHorizontalPos.current },
animate: false,
});
} else if (direction === "vertical") {
scrollVerticalPos.current += scrollStep * step;
scrollToRef.current({
position: { y: scrollVerticalPos.current },
animate: false,
});
}
if (
direction === "horizontal" &&
((position === POSITION.right && scrollPosition.current === "right") ||
(position === POSITION.left && scrollPosition.current === "left"))
) {
window.cancelAnimationFrame(requestIdRef.current);
} else if (
direction === "vertical" &&
((position === POSITION.bottom &&
scrollPosition.current === "bottom") ||
(position === POSITION.top && scrollPosition.current === "top"))
) {
window.cancelAnimationFrame(requestIdRef.current);
} else {
requestIdRef.current = window.requestAnimationFrame(animateScroll);
}
};
if (typeof window === "object") {
requestIdRef.current = window.requestAnimationFrame(animateScroll);
}
}, []);
const handleBlur = useCallback(() => {
if (requestIdRef.current && typeof window === "object") {
window.cancelAnimationFrame(requestIdRef.current);
}
}, [autoScroll, direction]);
const relevantPositions = getRelevantPositions(direction);
return (
<div
@@ -176,34 +120,20 @@ export default function TVirtualGridList({
spotlightId={spotlightId}
{...rest}
/>
{direction === "horizontal" && cursorVisible && autoScroll && (
<AutoScrollArea
position={POSITION.left}
onFocus={() => handleFocusAutoScroll(POSITION.left)}
onBlur={handleBlur}
/>
)}
{direction === "horizontal" && cursorVisible && autoScroll && (
<AutoScrollArea
position={POSITION.right}
onFocus={() => handleFocusAutoScroll(POSITION.right)}
onBlur={handleBlur}
/>
)}
{direction === "vertical" && cursorVisible && autoScroll && (
<AutoScrollArea
position={POSITION.top}
onFocus={() => handleFocusAutoScroll(POSITION.top)}
onBlur={handleBlur}
/>
)}
{direction === "vertical" && cursorVisible && autoScroll && (
<AutoScrollArea
position={POSITION.bottom}
onFocus={() => handleFocusAutoScroll(POSITION.bottom)}
onBlur={handleBlur}
/>
)}
{cursorVisible &&
autoScroll &&
relevantPositions.map((pos) => (
<AutoScrollArea
key={pos}
position={POSITION[pos]}
autoScroll={autoScroll}
scrollHorizontalPos={scrollHorizontalPos}
scrollVerticalPos={scrollVerticalPos}
scrollToRef={scrollToRef}
scrollPosition={scrollPosition}
direction={direction}
/>
))}
</div>
);
}