mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-07 02:06:18 +00:00
fix: better animation
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { Animated, Easing, View } from "react-native";
|
||||
import React, { useEffect } from "react";
|
||||
import { View } from "react-native";
|
||||
import Animated, {
|
||||
Easing,
|
||||
interpolate,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withDelay,
|
||||
withRepeat,
|
||||
withTiming,
|
||||
} from "react-native-reanimated";
|
||||
|
||||
interface Props {
|
||||
color?: string;
|
||||
@@ -9,6 +18,54 @@ interface Props {
|
||||
gap?: number;
|
||||
}
|
||||
|
||||
const MIN_SCALE = 0.35;
|
||||
const MAX_SCALE = 1;
|
||||
const DURATIONS = [800, 650, 750];
|
||||
const DELAYS = [0, 200, 100];
|
||||
|
||||
const Bar: React.FC<{
|
||||
color: string;
|
||||
barWidth: number;
|
||||
height: number;
|
||||
duration: number;
|
||||
delay: number;
|
||||
}> = ({ color, barWidth, height, duration, delay }) => {
|
||||
const progress = useSharedValue(0);
|
||||
|
||||
useEffect(() => {
|
||||
progress.value = withDelay(
|
||||
delay,
|
||||
withRepeat(
|
||||
withTiming(1, { duration, easing: Easing.inOut(Easing.ease) }),
|
||||
-1,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}, []);
|
||||
|
||||
const animatedStyle = useAnimatedStyle(() => ({
|
||||
transform: [
|
||||
{
|
||||
scaleY: interpolate(progress.value, [0, 1], [MIN_SCALE, MAX_SCALE]),
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
width: barWidth,
|
||||
height,
|
||||
backgroundColor: color,
|
||||
borderRadius: 1,
|
||||
},
|
||||
animatedStyle,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const AnimatedEqualizer: React.FC<Props> = ({
|
||||
color = "#9334E9",
|
||||
barWidth = 3,
|
||||
@@ -16,48 +73,6 @@ export const AnimatedEqualizer: React.FC<Props> = ({
|
||||
height = 12,
|
||||
gap = 2,
|
||||
}) => {
|
||||
const animations = useRef(
|
||||
Array.from({ length: barCount }, () => new Animated.Value(0)),
|
||||
).current;
|
||||
|
||||
useEffect(() => {
|
||||
const durations = [600, 700, 550];
|
||||
const minScale = [0.2, 0.3, 0.25];
|
||||
const maxScale = [1, 0.85, 0.95];
|
||||
|
||||
// Set initial staggered values
|
||||
animations.forEach((anim, index) => {
|
||||
anim.setValue(index === 1 ? 0.8 : index === 2 ? 0.4 : 0.2);
|
||||
});
|
||||
|
||||
const barAnimations = animations.map((anim, index) => {
|
||||
return Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(anim, {
|
||||
toValue: maxScale[index % maxScale.length],
|
||||
duration: durations[index % durations.length],
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(anim, {
|
||||
toValue: minScale[index % minScale.length],
|
||||
duration: durations[index % durations.length],
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
Animated.parallel(barAnimations).start();
|
||||
|
||||
return () => {
|
||||
animations.forEach((anim) => {
|
||||
anim.stopAnimation();
|
||||
});
|
||||
};
|
||||
}, [animations]);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
@@ -68,16 +83,14 @@ export const AnimatedEqualizer: React.FC<Props> = ({
|
||||
marginRight: 6,
|
||||
}}
|
||||
>
|
||||
{animations.map((anim, index) => (
|
||||
<Animated.View
|
||||
{Array.from({ length: barCount }).map((_, index) => (
|
||||
<Bar
|
||||
key={index}
|
||||
style={{
|
||||
width: barWidth,
|
||||
height,
|
||||
backgroundColor: color,
|
||||
borderRadius: 1,
|
||||
transform: [{ scaleY: anim }],
|
||||
}}
|
||||
color={color}
|
||||
barWidth={barWidth}
|
||||
height={height}
|
||||
duration={DURATIONS[index % DURATIONS.length]}
|
||||
delay={DELAYS[index % DELAYS.length]}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user