下面是一个使用React和TypeScript实现的无缝滚动组件,并实现鼠标移入停止动画,鼠标移出继续动画的示例代码:
import React, { useState, useEffect, useRef } from "react";
interface SeamlessScrollProps {
children: React.ReactNode;
speed?: number;
}
const SeamlessScroll: React.FC<SeamlessScrollProps> = ({
children,
speed = 50,
}) => {
const [isPaused, setIsPaused] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const container = containerRef.current;
const content = contentRef.current;
if (!container || !content) return;
const scrollWidth = content.offsetWidth - container.offsetWidth;
if (scrollWidth <= 0) return; // 不需要滚动
let animationFrameId: number | null = null;
let isMouseOver = false;
const animateScroll = () => {
if (isMouseOver) return;
container.scrollLeft += speed;
if (container.scrollLeft >= scrollWidth) {
container.scrollLeft -= scrollWidth;
}
animationFrameId = requestAnimationFrame(animateScroll);
};
animateScroll();
return () => {
cancelAnimationFrame(animationFrameId!);
};
}, [speed]);
const handleMouseEnter = () => {
setIsPaused(true);
};
const handleMouseLeave = () => {
setIsPaused(false);
};
return (
<div
ref={containerRef}
style={{ overflowX: "hidden" }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<div ref={contentRef} style={{ display: "inline-block" }}>
{children}
</div>
</div>
);
};
export default SeamlessScroll;
在这个示例中,我们创建了一个名为 SeamlessScroll
的组件,接受 children
和可选的 speed
属性。默认情况下,滚动速度为每帧移动50像素。
在 useEffect
钩子中,我们使用 requestAnimationFrame
实现了无缝滚动效果。如果鼠标未悬停在组件上,则容器元素会水平滚动,并循环地从右侧滚动到左侧。当容器滚动到末尾时,它会回滚到起始位置以实现无缝滚动。
通过调用 cancelAnimationFrame
取消请求的帧动画,在组件卸载时清理。
然后,在渲染部分,我们将容器和内容都使用了引用(ref)来获取对应的 DOM 元素。当鼠标进入或离开容器时,触发相应的事件处理函数 handleMouseEnter
和 handleMouseLeave
来控制是否暂停滚动。
最后,我们将子元素包装在容器内部,并根据需要添加样式和其他属性。
通过以上代码,你可以在React和TypeScript应用中实现一个具有无缝滚动功能,并能根据鼠标移入和移出状态来控制动画的暂停和继续。
内容由零声教学AI助手提供,问题来源于学员提问