Skip to content

Commit

Permalink
implement consecutive feature (ref kyo504#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
teaualune committed Jul 29, 2022
1 parent 444ee6a commit 980aa00
Showing 1 changed file with 49 additions and 6 deletions.
55 changes: 49 additions & 6 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export interface MarqueeTextProps extends TextProps {
* A callback for when the marquee finishes animation and stops
*/
onMarqueeComplete?: () => void;
/**
* A flag to enable consecutive mode that imitates the default behavior of HTML marquee element
* Does not take effect if loop is false
*/
consecutive?: boolean;
}

export interface MarqueeTextHandles {
Expand All @@ -56,6 +61,10 @@ const createAnimation = (
loop: boolean;
delay: number;
},
consecutive?: {
resetToValue: number;
duration: number;
},
): Animated.CompositeAnimation => {
const baseAnimation = Animated.timing(animatedValue, {
easing: Easing.linear,
Expand All @@ -64,6 +73,26 @@ const createAnimation = (
});

if (config.loop) {
if (consecutive) {
return Animated.sequence([
baseAnimation,
Animated.loop(
Animated.sequence([
Animated.timing(animatedValue, {
toValue: consecutive.resetToValue,
duration: 0,
useNativeDriver: true,
}),
Animated.timing(animatedValue, {
easing: Easing.linear,
useNativeDriver: true,
...config,
duration: consecutive.duration,
}),
]),
),
]);
}
return Animated.loop(Animated.sequence([baseAnimation, Animated.delay(1000)]));
}

Expand All @@ -77,6 +106,7 @@ const MarqueeText = (props: MarqueeTextProps, ref: Ref<MarqueeTextHandles>): JSX
speed = 1,
loop = true,
delay = 0,
consecutive = false,
onMarqueeComplete,
children,
...restProps
Expand All @@ -96,11 +126,13 @@ const MarqueeText = (props: MarqueeTextProps, ref: Ref<MarqueeTextHandles>): JSX
speed: number;
loop: boolean;
delay: number;
consecutive: boolean;
}>({
marqueeOnStart,
speed,
loop,
delay,
consecutive,
});

const stopAnimation = useCallback(() => {
Expand All @@ -125,11 +157,22 @@ const MarqueeText = (props: MarqueeTextProps, ref: Ref<MarqueeTextHandles>): JSX
return;
}

animation.current = createAnimation(animatedValue.current, {
...config.current,
toValue: -distance,
duration: PixelRatio.getPixelSizeForLayoutSize(marqueeTextWidth.current) / config.current.speed,
});
const baseDuration = PixelRatio.getPixelSizeForLayoutSize(marqueeTextWidth.current) / config.current.speed;
const { consecutive } = config.current;
animation.current = createAnimation(
animatedValue.current,
{
...config.current,
toValue: consecutive ? -marqueeTextWidth.current : -distance,
duration: consecutive ? baseDuration * (marqueeTextWidth.current / distance) : baseDuration,
},
consecutive
? {
resetToValue: containerWidth.current,
duration: baseDuration * ((containerWidth.current + marqueeTextWidth.current) / distance),
}
: undefined,
);

animation.current.start((): void => {
setIsAnimating(false);
Expand Down Expand Up @@ -169,7 +212,7 @@ const MarqueeText = (props: MarqueeTextProps, ref: Ref<MarqueeTextHandles>): JSX

const measureWidth = (component: ScrollView | Text): Promise<number> =>
new Promise(resolve => {
UIManager.measure(findNodeHandle(component), (x: number, y: number, w: number) => {
UIManager.measure(findNodeHandle(component), (_x: number, _y: number, w: number) => {
return resolve(w);
});
});
Expand Down

0 comments on commit 980aa00

Please sign in to comment.