react-native-marquee
前言
最近在做 react-native
的需求有个顶部文字滚动的需求效果,即常见的跑马灯的效果。这个效果在网上应该能找到很多开源的库,但还是想要自己尝试下,最终实现效果如下:
分析
如果是 html
的话,用纯css
就能实现,但是react-native
不行,相对复杂点,特别是需要知道他的动画相关API,但实现思路是类似的。在结合 react-native
动画的特性做相关尝试和调整。
react-native
需要去计算容器的宽度和文本的宽度,如果文本宽度大于容器的宽度就滚动,思路很简单。但是在react-native
常规的布局下不行,Text
组件会自动截取。最终尝试需要 给 Text
组件在包裹一个ScrollView
组件,并禁止 ScrollView
的滚动。
实现
最终代码如下:
import React, {useRef, useEffect, useState} from 'react';
import {Animated, Easing} from 'react-native';
import styled from '@emotion/native';
const Wrapper = styled.View`
overflow: hidden;
flex-direction: row;
align-items: center;
`;
const Container = styled.ScrollView`
flex-direction: row;
`;
const Content = styled(Animated.Text)`
font-size: 14px;
`;
const Marquee = ({
children,
duration = 20000,
textStyle = {},
...restProps
}) => {
const [containerWidth, setContainerWidth] = useState(0);
const [textWidth, setTextWidth] = useState(0);
const animatedValue = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (containerWidth && textWidth && textWidth > containerWidth) {
startAnimation();
}
}, [containerWidth, textWidth]);
const startAnimation = () => {
animatedValue.setValue(containerWidth);
Animated.loop(
Animated.timing(animatedValue, {
toValue: -textWidth,
duration: duration,
easing: Easing.linear,
useNativeDriver: true,
}),
).start();
};
return (
<Wrapper
onLayout={e => {
setContainerWidth(e.nativeEvent.layout.width);
}}
{...restProps}>
<Container scrollEnabled={false}>
<Content
numberOfLines={1}
style={[
{...textStyle},
{
transform: [{translateX: animatedValue}],
},
]}
onLayout={e => {
setTextWidth(e.nativeEvent.layout.width);
}}>
{children}
</Content>
</Container>
</Wrapper>
);
};
export default Marquee;
总结
一个简单的跑马灯效果就实现了。当然还有些细节没有去处理,比如时长这个可以根据文本容器的宽度来计算,等等。。。以上代码80%
都是通过 ChartGPT
实现的,它会给你提供一个思路和大概的代码,然后在自己去修复,特别是在自己不熟悉的东西,ChartGPT
真的很有帮助,极大的提高了生产力,拥抱它就是了
转载自:https://juejin.cn/post/7391693209373016105