분석레포트 타임라인 표시
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { useLayoutEffect, type RefObject } from 'react';
|
||||
|
||||
/** 봉 시간축 — 시간 레일이 스크롤 영역 중앙(세로·가로)에 오도록 조정 */
|
||||
export function useCenterAxisTimelineScroll(
|
||||
scrollRef: RefObject<HTMLElement | null>,
|
||||
trackRef: RefObject<HTMLElement | null>,
|
||||
enabled: boolean,
|
||||
deps: unknown[] = [],
|
||||
): void {
|
||||
useLayoutEffect(() => {
|
||||
if (!enabled) return;
|
||||
const scroll = scrollRef.current;
|
||||
const track = trackRef.current;
|
||||
if (!scroll || !track) return;
|
||||
|
||||
const center = () => {
|
||||
const rail = track.querySelector('.arp-timeline-axis-rail') as HTMLElement | null;
|
||||
if (rail) {
|
||||
const scrollRect = scroll.getBoundingClientRect();
|
||||
const railRect = rail.getBoundingClientRect();
|
||||
const railMidInContent =
|
||||
scroll.scrollTop + (railRect.top - scrollRect.top) + railRect.height / 2;
|
||||
const targetTop = railMidInContent - scroll.clientHeight / 2;
|
||||
scroll.scrollTop = Math.max(0, Math.min(
|
||||
targetTop,
|
||||
scroll.scrollHeight - scroll.clientHeight,
|
||||
));
|
||||
}
|
||||
|
||||
const targetLeft = (scroll.scrollWidth - scroll.clientWidth) / 2;
|
||||
scroll.scrollLeft = Math.max(0, targetLeft);
|
||||
};
|
||||
|
||||
center();
|
||||
requestAnimationFrame(center);
|
||||
|
||||
const ro = new ResizeObserver(() => center());
|
||||
ro.observe(scroll);
|
||||
ro.observe(track);
|
||||
return () => ro.disconnect();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [enabled, scrollRef, trackRef, ...deps]);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { useEffect, type RefObject } from 'react';
|
||||
|
||||
/** 가로 overflow 컨테이너 — 세로 휠을 좌우 스크롤로 변환 */
|
||||
export function useHorizontalWheelScroll(
|
||||
ref: RefObject<HTMLElement | null>,
|
||||
enabled = true,
|
||||
): void {
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
const onWheel = (e: WheelEvent) => {
|
||||
if (el.scrollWidth <= el.clientWidth + 1) return;
|
||||
|
||||
const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY;
|
||||
if (delta === 0) return;
|
||||
|
||||
const prev = el.scrollLeft;
|
||||
el.scrollLeft += delta;
|
||||
if (el.scrollLeft !== prev) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
el.addEventListener('wheel', onWheel, { passive: false });
|
||||
return () => el.removeEventListener('wheel', onWheel);
|
||||
}, [enabled, ref]);
|
||||
}
|
||||
Reference in New Issue
Block a user