Skip to content

Instantly share code, notes, and snippets.

@damikdk
Created June 10, 2024 13:57
Show Gist options
  • Save damikdk/fa04c2f5815395a16e1b184d604b0ab9 to your computer and use it in GitHub Desktop.
Save damikdk/fa04c2f5815395a16e1b184d604b0ab9 to your computer and use it in GitHub Desktop.
Modern reanimated react-native horizontal marquee marquee
import { StyleSheet, View } from "react-native";
import React, { useEffect, useState } from "react";
import Animated, {
useAnimatedRef,
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
} from "react-native-reanimated";
const Marquee = ({ children, style }) => {
const scrollRef = useAnimatedRef();
const offset = useSharedValue(0);
const [scrollViewWidth, setScrollViewWidth] = useState(0);
const [childWidth, setChildWidth] = useState(0);
useEffect(() => {
if (scrollViewWidth < childWidth) {
offset.value = withRepeat(
withTiming(scrollViewWidth - childWidth, { duration: 5000 }),
-1,
true
);
}
}, [childWidth, scrollViewWidth]);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
}));
return (
<View
style={style}
onLayout={(event) => setScrollViewWidth(event.nativeEvent.layout?.width)}
>
<Animated.ScrollView
ref={scrollRef}
horizontal
scrollEnabled={false}
contentContainerStyle={styles.flexGrow}
onContentSizeChange={(width, height) => setChildWidth(width)}
>
<Animated.View style={animatedStyle}>{children}</Animated.View>
</Animated.ScrollView>
</View>
);
};
export default Marquee;
const styles = StyleSheet.create({
flexGrow: {
flexGrow: 1,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment