diff --git a/src/components/common/Text.tsx b/src/components/common/Text.tsx index 2cc8c5b..532bd77 100644 --- a/src/components/common/Text.tsx +++ b/src/components/common/Text.tsx @@ -3,6 +3,7 @@ import { Text, type TextProps as _TextProps, StyleSheet, Animated, type ColorVal import { useTheme } from '@/store/theme/hook' import { setSpText } from '@/utils/pixelRatio' import { useAnimateColor } from '@/utils/hooks/useAnimateColor' +import { useAnimateNumber } from '@/utils/hooks/useAnimateNumber' // import { AppColors } from '@/theme' export interface TextProps extends _TextProps { @@ -38,15 +39,20 @@ export interface AnimatedColorTextProps extends _AnimatedTextProps { * 字体颜色 */ color?: string + /** + * 字体透明度 + */ + opacity?: number } -export const AnimatedColorText = ({ style, size = 15, color: _color, children, ...props }: AnimatedColorTextProps) => { +export const AnimatedColorText = ({ style, size = 15, opacity: _opacity, color: _color, children, ...props }: AnimatedColorTextProps) => { const theme = useTheme() const [color] = useAnimateColor(_color ?? theme['c-font']) + const [opacity] = useAnimateNumber(_opacity ?? 1) return ( {children} ) diff --git a/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx b/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx index cc4a1b5..39be67d 100644 --- a/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx +++ b/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx @@ -25,6 +25,6 @@ export default memo(() => { const styles = createStyle({ content: { marginTop: 5, - // marginBottom: 15, + marginBottom: 15, }, }) diff --git a/src/screens/Home/Views/Setting/settings/Theme/IsHideBgDark.tsx b/src/screens/Home/Views/Setting/settings/Theme/IsHideBgDark.tsx index a71d768..165f297 100644 --- a/src/screens/Home/Views/Setting/settings/Theme/IsHideBgDark.tsx +++ b/src/screens/Home/Views/Setting/settings/Theme/IsHideBgDark.tsx @@ -32,6 +32,6 @@ export default memo(() => { const styles = createStyle({ content: { marginTop: 5, - marginBottom: 15, + // marginBottom: 15, }, }) diff --git a/src/screens/Home/Views/Setting/settings/Theme/index.tsx b/src/screens/Home/Views/Setting/settings/Theme/index.tsx index 3400235..8d5176a 100644 --- a/src/screens/Home/Views/Setting/settings/Theme/index.tsx +++ b/src/screens/Home/Views/Setting/settings/Theme/index.tsx @@ -12,8 +12,8 @@ export default memo(() => { <> - + ) }) diff --git a/src/screens/PlayDetail/Horizontal/Lyric.tsx b/src/screens/PlayDetail/Horizontal/Lyric.tsx index 4d4a7aa..f3d57b1 100644 --- a/src/screens/PlayDetail/Horizontal/Lyric.tsx +++ b/src/screens/PlayDetail/Horizontal/Lyric.tsx @@ -35,10 +35,12 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => { return active ? [ theme['c-primary'], theme['c-primary-alpha-200'], - ] : [ + 1, + ] as const : [ theme['c-350'], theme['c-300'], - ] + 0.6, + ] as const }, [activeLine, lineNum, theme]) const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => { @@ -53,14 +55,14 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => { ...styles.lineText, textAlign, lineHeight, - }} textBreakStrategy="simple" color={colors[0]} size={size}>{line.text} + }} textBreakStrategy="simple" color={colors[0]} opacity={colors[2]} size={size}>{line.text} { line.extendedLyrics.map((lrc, index) => { return ({lrc}) + }} textBreakStrategy="simple" key={index} color={colors[1]} opacity={colors[2]} size={size * 0.8}>{lrc}) }) } diff --git a/src/screens/PlayDetail/Vertical/Lyric.tsx b/src/screens/PlayDetail/Vertical/Lyric.tsx index 014b1a6..8a6f57d 100644 --- a/src/screens/PlayDetail/Vertical/Lyric.tsx +++ b/src/screens/PlayDetail/Vertical/Lyric.tsx @@ -74,10 +74,12 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => { return active ? [ theme['c-primary'], theme['c-primary-alpha-200'], - ] : [ + 1, + ] as const : [ theme['c-350'], theme['c-300'], - ] + 0.6, + ] as const }, [activeLine, lineNum, theme]) const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => { @@ -93,14 +95,14 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => { ...styles.lineText, textAlign, lineHeight, - }} textBreakStrategy="simple" color={colors[0]} size={size}>{line.text} + }} textBreakStrategy="simple" color={colors[0]} opacity={colors[2]} size={size}>{line.text} { line.extendedLyrics.map((lrc, index) => { return ({lrc}) + }} textBreakStrategy="simple" key={index} color={colors[1]} opacity={colors[2]} size={size * 0.8}>{lrc}) }) } diff --git a/src/utils/hooks/useAnimateColor.ts b/src/utils/hooks/useAnimateColor.ts index 9cc1854..460a1a9 100644 --- a/src/utils/hooks/useAnimateColor.ts +++ b/src/utils/hooks/useAnimateColor.ts @@ -21,10 +21,14 @@ export const useAnimateColor = (color: string) => { toValue: 1, duration: ANIMATION_DURATION, useNativeDriver: false, - }).start(() => { - currentColor.current = nextColor + }).start((finished) => { + if (!finished) return + // currentColor.current = nextColor setFinished(true) }) + requestAnimationFrame(() => { + currentColor.current = nextColor + }) }, [nextColor]) return [animColor, finished] as const diff --git a/src/utils/hooks/useAnimateNumber.ts b/src/utils/hooks/useAnimateNumber.ts new file mode 100644 index 0000000..7529334 --- /dev/null +++ b/src/utils/hooks/useAnimateNumber.ts @@ -0,0 +1,35 @@ +import { useEffect, useMemo, useRef, useState } from 'react' +import { Animated } from 'react-native' + + +const ANIMATION_DURATION = 800 + +export const useAnimateNumber = (val: number) => { + const anim = useMemo(() => new Animated.Value(0), [val]) + const [finished, setFinished] = useState(true) + const currentNumber = useRef(val) + const nextNumber = useMemo(() => val, [val]) + + const animNumber = anim.interpolate({ + inputRange: [0, 1], + outputRange: [currentNumber.current, nextNumber], + }) + + useEffect(() => { + setFinished(false) + Animated.timing(anim, { + toValue: 1, + duration: ANIMATION_DURATION, + useNativeDriver: false, + }).start((finished) => { + if (!finished) return + // currentNumber.current = nextNumber + setFinished(true) + }) + requestAnimationFrame(() => { + currentNumber.current = nextNumber + }) + }, [nextNumber]) + + return [animNumber, finished] as const +}