react 字轮播滚动
一、用计时器来实现
React 字符串滚动轮播,可以使用 setInterval
函数和 React 的生命周期方法来实现。以下是一个简单的示例:
import React from "react";
export default class TextScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
text: props.text,
currentIndex: 0,
};
}
componentDidMount() {
this.intervalId = setInterval(() => {
const { text, currentIndex } = this.state;
const nextIndex = (currentIndex + 1) % text.length;
this.setState({ currentIndex: nextIndex });
}, 2000);
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
render() {
const { text, currentIndex } = this.state;
const displayText = `${text.slice(currentIndex)}${text.slice(0, currentIndex)}`;
return <div>{displayText}</div>;
}
}
在上述代码中,我们创建了一个名为 TextScroll
的 React 组件。该组件接受一个 text
属性作为字符串输入,并将其滚动显示。
在组件的构造函数中初始化了组件的 state,包括要滚动显示的文本 text
和当前的索引 currentIndex
。
在组件的 componentDidMount
生命周期方法中,我们使用 setInterval
函数创建了一个定时器,每隔 2 秒钟就更新一次 currentIndex
的值。这个定时器的 ID 被保存在组件的实例变量 intervalId
中。
在组件的 componentWillUnmount
生命周期方法中,我们清除了 setInterval
定时器,以避免内存泄漏。
最后,在组件的 render
方法中,我们根据当前的 currentIndex
将文本分成两部分,并将它们重新拼接成一个新的字符串。这个新字符串就是要滚动显示的文本,它被渲染到页面上。
请注意,在实际开发中,需要考虑更多的细节和优化。例如,可以添加控制按钮来暂停或重新启动滚动,或者使用 requestAnimationFrame
代替 setInterval
来提高性能等。
二、用requestAnimationFrame
来实现
当使用 requestAnimationFrame
代替 setInterval
来实现滚动时,可以利用 React 组件的 requestAnimationFrame
方法来进行调度。以下是更新后的示例代码:
import React from "react";
export default class TextScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
text: props.text,
currentIndex: 0,
};
this.animationId = null;
}
componentDidMount() {
this.startAnimation();
}
componentWillUnmount() {
this.stopAnimation();
}
startAnimation() {
const animate = () => {
const { text, currentIndex } = this.state;
const nextIndex = (currentIndex + 1) % text.length;
this.setState({ currentIndex: nextIndex });
this.animationId = requestAnimationFrame(animate);
};
this.animationId = requestAnimationFrame(animate);
}
stopAnimation() {
cancelAnimationFrame(this.animationId);
}
render() {
const { text, currentIndex } = this.state;
const displayText = `${text.slice(currentIndex)}${text.slice(0, currentIndex)}`;
return <div>{displayText}</div>;
}
}
在更新后的代码中,我们添加了一个实例变量 animationId
来存储 requestAnimationFrame
的 ID。
在组件的 componentDidMount
生命周期函数中,调用了 startAnimation
方法,该方法会启动动画循环。
在 startAnimation
方法中,我们定义了一个名为 animate
的递归函数。该函数更新 currentIndex
的值,并通过调用 setState
方法来触发重新渲染。然后,我们使用 requestAnimationFrame
来调度下一帧动画,并将 animate
函数作为回调传递给它。
在组件的 componentWillUnmount
生命周期函数中,调用了 stopAnimation
方法来取消动画循环。
最后,在组件的 render
方法中,我们根据当前的 currentIndex
将文本分成两部分,并将它们重新拼接成一个新的字符串。这个新字符串就是要滚动显示的文本,它被渲染到页面上。
通过使用 requestAnimationFrame
,可以更好地与浏览器的渲染机制进行协调,以提供更流畅的滚动效果。
三、实现每秒轮播
要实现每秒轮播,可以在 requestAnimationFrame
的回调函数中添加一个时间控制逻辑来实现。以下是更新后的代码示例:
import React from "react";
export default class TextScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
text: props.text,
currentIndex: 0,
lastTime: 0,
};
this.animationId = null;
}
componentDidMount() {
this.startAnimation();
}
componentWillUnmount() {
this.stopAnimation();
}
startAnimation() {
const animate = (timestamp) => {
const { lastTime, text, currentIndex } = this.state;
if (!lastTime || timestamp - lastTime >= 1000) {
const nextIndex = (currentIndex + 1) % text.length;
this.setState({ currentIndex: nextIndex, lastTime: timestamp });
}
this.animationId = requestAnimationFrame(animate);
};
this.animationId = requestAnimationFrame(animate);
}
stopAnimation() {
cancelAnimationFrame(this.animationId);
}
render() {
const { text, currentIndex } = this.state;
const displayText = `${text.slice(currentIndex)}${text.slice(0, currentIndex)}`;
return <div>{displayText}</div>;
}
}
在更新后的代码中,我们将 lastTime
加入了组件的 state 中,用于记录上一次动画触发的时间戳。
在 startAnimation
方法中的 animate
函数中,我们首先获取当前的时间戳 timestamp
,然后判断距离上一次动画触发是否已经过去了 1000 毫秒(即 1 秒)。如果条件成立,就更新 currentIndex
的值,并将当前时间戳赋给 lastTime
,然后触发重新渲染;否则,继续等待下一帧动画。
这样就实现了每秒一次的轮播效果。当然,在实际开发中,还可以根据需求进行更灵活的时间控制和动画效果的调整。