react-native-design-kit
Advanced tools
@@ -6,5 +6,7 @@ import { ReactNode } from 'react'; | ||
| speed?: number; | ||
| delay?: number; | ||
| cooldown?: number; | ||
| byPassAnimationCallback?: boolean; | ||
| children: ReactNode; | ||
| } | ||
| export default function Marquee({ containerStyle, speed, cooldown, children, }: MarqueeProps): JSX.Element; | ||
| export default function Marquee({ speed, delay, containerStyle, byPassAnimationCallback, children, }: MarqueeProps): JSX.Element; |
@@ -1,31 +0,41 @@ | ||
| import React, { useState, useEffect } from 'react'; | ||
| import { ScrollView, StyleSheet, View, Platform } from 'react-native'; | ||
| export default function Marquee({ containerStyle, speed = 1, cooldown = 1000, children, }) { | ||
| const [width, setWidth] = useState(0); | ||
| const [length, setLength] = useState(0); | ||
| const [offset, setOffset] = useState(); | ||
| useEffect(() => { | ||
| if (offset !== undefined) { | ||
| const scale = Platform.select({ android: 1.5, default: 1 }); | ||
| const speedScaled = speed * scale; | ||
| if (offset <= -length - (cooldown / 10) * speedScaled) { | ||
| setOffset(width); | ||
| } | ||
| else { | ||
| const timeout = setTimeout(() => { | ||
| setOffset(offset - speedScaled); | ||
| }, 10); | ||
| return () => clearTimeout(timeout); | ||
| } | ||
| import React, { useState, useMemo, useRef, useCallback } from 'react'; | ||
| import { ScrollView, StyleSheet, View, Animated } from 'react-native'; | ||
| import { useDidUpdate } from '../../utilities'; | ||
| export default function Marquee({ speed = 0.125, delay, containerStyle, byPassAnimationCallback = false, children, }) { | ||
| const [layoutWidth, setLayoutWidth] = useState(); | ||
| const [contentWidth, setContentWidth] = useState(0); | ||
| const [lastCycle, setLastCycle] = useState(); | ||
| const animation = useRef(new Animated.Value(0)).current; | ||
| const lineWidth = useMemo(() => (layoutWidth ? layoutWidth + contentWidth * 2 : undefined), [layoutWidth, contentWidth]); | ||
| const duration = useMemo(() => (lineWidth ? lineWidth / speed : undefined), [ | ||
| lineWidth, | ||
| speed, | ||
| ]); | ||
| const handleRunAnimation = useCallback(() => { | ||
| if (duration) { | ||
| animation.setValue(0); | ||
| Animated.timing(animation, { | ||
| duration, | ||
| delay, | ||
| toValue: 1, | ||
| useNativeDriver: true, | ||
| }).start(callback => (byPassAnimationCallback || callback.finished) && | ||
| setLastCycle(new Date())); | ||
| } | ||
| }, [offset]); | ||
| useEffect(() => { | ||
| setWidth(width); | ||
| setOffset(width); | ||
| }, [width]); | ||
| return (React.createElement(View, { style: StyleSheet.flatten([styles.container, containerStyle]), onLayout: event => setWidth(event.nativeEvent.layout.width) }, offset !== undefined && (React.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, showsVerticalScrollIndicator: false, bounces: false, scrollEnabled: false, contentContainerStyle: StyleSheet.flatten([ | ||
| styles.sectionContent, | ||
| { marginLeft: offset }, | ||
| ]) }, | ||
| React.createElement(View, { onLayout: event => setLength(event.nativeEvent.layout.width) }, children))))); | ||
| }, [duration, animation, delay, byPassAnimationCallback]); | ||
| const handleRenderMarquee = useMemo(() => layoutWidth ? (React.createElement(ScrollView, { horizontal: true, testID: "marquee", showsHorizontalScrollIndicator: false, showsVerticalScrollIndicator: false, bounces: false, onContentSizeChange: w => setContentWidth(w), scrollEnabled: false, contentContainerStyle: StyleSheet.flatten([styles.sectionContent]) }, | ||
| React.createElement(Animated.View, { style: StyleSheet.flatten([ | ||
| { | ||
| translateX: animation.interpolate({ | ||
| inputRange: [0, 1], | ||
| outputRange: [layoutWidth, -contentWidth], | ||
| }), | ||
| }, | ||
| ]) }, children))) : null, [layoutWidth, contentWidth, children]); | ||
| useDidUpdate(handleRunAnimation, [ | ||
| lastCycle, | ||
| layoutWidth, | ||
| handleRunAnimation, | ||
| ]); | ||
| return (React.createElement(View, { testID: "container", style: StyleSheet.flatten([styles.container, containerStyle]), onLayout: event => setLayoutWidth(event.nativeEvent.layout.width) }, handleRenderMarquee)); | ||
| } | ||
@@ -32,0 +42,0 @@ const styles = StyleSheet.create({ |
+2
-1
| { | ||
| "name": "react-native-design-kit", | ||
| "version": "1.1.5", | ||
| "version": "1.1.6", | ||
| "description": "All in one react native material design", | ||
@@ -21,2 +21,3 @@ "main": "dist/index.js", | ||
| "build": "tsc --project tsconfig.prod.json", | ||
| "prepublish": "npm run build", | ||
| "test": "jest --coverage", | ||
@@ -23,0 +24,0 @@ "test:watch": "npm run test -- --watch", |
145535
0.6%3364
0.36%