效果1
import {CaretUpOutlined,CaretDownOutlined} from "@ant-design/icons";
const wrap = useRef<HTMLDivElement | null>(null);
const scrollTo = useCallback(
// dir:0 向下滾動 1 向上滾動
(dom, height, dir = 0) =>
() => {
const sTop = dom.scrollTop;
const valid = dir ? sTop > height : sTop < height;
if (valid) {
window.requestAnimationFrame(scrollTo(dom, height, dir));
const diff = Math.abs(sTop - height);
const dis = diff / 8;
//差距不足 8 時滾動 4 2 1 0
const nextScrollDis = dis < 1 ? Math.ceil(diff / 2) : dis;
let y = sTop - nextScrollDis;
// 向下滾動
!dir && (y = sTop + nextScrollDis);
dom.scrollTo(0, y);
}
},
[]
);
const onDownScroll = useCallback(() => {
const { offsetHeight, scrollTop, scrollHeight } =
wrap.current as HTMLDivElement;
const maxHeight = scrollHeight - offsetHeight;
const target = offsetHeight + scrollTop;
scrollTo(wrap.current, target > maxHeight ? maxHeight : target)();
}, [scrollTo]);
const onUpScroll = useCallback(() => {
const { offsetHeight, scrollTop } = wrap.current as HTMLDivElement;
const target = scrollTop - offsetHeight;
scrollTo(wrap.current, target < 0 ? 0 : target, 1)();
}, [scrollTo]);
return (
<Container ref={wrap}>
<TotalTitle>
<span data-fill>
TOTAL: <b>{pokerList.length}</b>
</span>
<CaretUpOutlined onClick={onUpScroll} />
<CaretDownOutlined onClick={onDownScroll} />
</TotalTitle>
.....
效果 2
思路
第一次 滾動100 的10分之一 里烦,一次時 100-10的十分之一耳标,下下次是 100-10-10的十分之一 依次類推
看起來就會一點點慢下來
//! 移動最小1 0.x不能移動
export const animateScrollToTop = (top: number, element: HTMLElement) => () => {
const { scrollTop, scrollHeight, clientHeight } = element;
if (clientHeight + scrollTop < scrollHeight) {
const diff = top - scrollTop;
// console.log(top, scrollTop, diff);
const dis = diff / 6;
// const scrollDis = dis < 1 ? 1 : dis;
const scrollDis = dis < 1 ? Math.ceil(diff / 2) : dis;
if (scrollTop < top) {
requestAnimationFrame(animateScrollToTop(top, element));
element.scrollTo(0, scrollTop + scrollDis);
}
}
};
滾動到最上方
export const scrollToTop = () => {
let sTop = document.documentElement.scrollTop || document.body.scrollTop;
if (sTop > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, sTop - sTop / 8);
}
};