mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-04 20:08:56 +08:00
优化歌词详情页未激活状态歌词颜色
This commit is contained in:
parent
fa879a8c4e
commit
811c6dc9fb
@ -3,6 +3,7 @@ import { Text, type TextProps as _TextProps, StyleSheet, Animated, type ColorVal
|
|||||||
import { useTheme } from '@/store/theme/hook'
|
import { useTheme } from '@/store/theme/hook'
|
||||||
import { setSpText } from '@/utils/pixelRatio'
|
import { setSpText } from '@/utils/pixelRatio'
|
||||||
import { useAnimateColor } from '@/utils/hooks/useAnimateColor'
|
import { useAnimateColor } from '@/utils/hooks/useAnimateColor'
|
||||||
|
import { useAnimateNumber } from '@/utils/hooks/useAnimateNumber'
|
||||||
// import { AppColors } from '@/theme'
|
// import { AppColors } from '@/theme'
|
||||||
|
|
||||||
export interface TextProps extends _TextProps {
|
export interface TextProps extends _TextProps {
|
||||||
@ -38,15 +39,20 @@ export interface AnimatedColorTextProps extends _AnimatedTextProps {
|
|||||||
* 字体颜色
|
* 字体颜色
|
||||||
*/
|
*/
|
||||||
color?: string
|
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 theme = useTheme()
|
||||||
|
|
||||||
const [color] = useAnimateColor(_color ?? theme['c-font'])
|
const [color] = useAnimateColor(_color ?? theme['c-font'])
|
||||||
|
const [opacity] = useAnimateNumber(_opacity ?? 1)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.Text
|
<Animated.Text
|
||||||
style={StyleSheet.compose({ fontSize: setSpText(size), color: color as unknown as ColorValue }, style as TextStyle)}
|
style={StyleSheet.compose({ fontSize: setSpText(size), color: color as unknown as ColorValue, opacity }, style as TextStyle)}
|
||||||
{...props}
|
{...props}
|
||||||
>{children}</Animated.Text>
|
>{children}</Animated.Text>
|
||||||
)
|
)
|
||||||
|
@ -25,6 +25,6 @@ export default memo(() => {
|
|||||||
const styles = createStyle({
|
const styles = createStyle({
|
||||||
content: {
|
content: {
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
// marginBottom: 15,
|
marginBottom: 15,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -32,6 +32,6 @@ export default memo(() => {
|
|||||||
const styles = createStyle({
|
const styles = createStyle({
|
||||||
content: {
|
content: {
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
marginBottom: 15,
|
// marginBottom: 15,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -12,8 +12,8 @@ export default memo(() => {
|
|||||||
<>
|
<>
|
||||||
<Theme />
|
<Theme />
|
||||||
<IsAutoTheme />
|
<IsAutoTheme />
|
||||||
<IsDynamicBg />
|
|
||||||
<IsHideBgDark />
|
<IsHideBgDark />
|
||||||
|
<IsDynamicBg />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -35,10 +35,12 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => {
|
|||||||
return active ? [
|
return active ? [
|
||||||
theme['c-primary'],
|
theme['c-primary'],
|
||||||
theme['c-primary-alpha-200'],
|
theme['c-primary-alpha-200'],
|
||||||
] : [
|
1,
|
||||||
|
] as const : [
|
||||||
theme['c-350'],
|
theme['c-350'],
|
||||||
theme['c-300'],
|
theme['c-300'],
|
||||||
]
|
0.6,
|
||||||
|
] as const
|
||||||
}, [activeLine, lineNum, theme])
|
}, [activeLine, lineNum, theme])
|
||||||
|
|
||||||
const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => {
|
const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => {
|
||||||
@ -53,14 +55,14 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => {
|
|||||||
...styles.lineText,
|
...styles.lineText,
|
||||||
textAlign,
|
textAlign,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
}} textBreakStrategy="simple" color={colors[0]} size={size}>{line.text}</AnimatedColorText>
|
}} textBreakStrategy="simple" color={colors[0]} opacity={colors[2]} size={size}>{line.text}</AnimatedColorText>
|
||||||
{
|
{
|
||||||
line.extendedLyrics.map((lrc, index) => {
|
line.extendedLyrics.map((lrc, index) => {
|
||||||
return (<AnimatedColorText style={{
|
return (<AnimatedColorText style={{
|
||||||
...styles.lineTranslationText,
|
...styles.lineTranslationText,
|
||||||
textAlign,
|
textAlign,
|
||||||
lineHeight: lineHeight * 0.8,
|
lineHeight: lineHeight * 0.8,
|
||||||
}} textBreakStrategy="simple" key={index} color={colors[1]} size={size * 0.8}>{lrc}</AnimatedColorText>)
|
}} textBreakStrategy="simple" key={index} color={colors[1]} opacity={colors[2]} size={size * 0.8}>{lrc}</AnimatedColorText>)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
|
@ -74,10 +74,12 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => {
|
|||||||
return active ? [
|
return active ? [
|
||||||
theme['c-primary'],
|
theme['c-primary'],
|
||||||
theme['c-primary-alpha-200'],
|
theme['c-primary-alpha-200'],
|
||||||
] : [
|
1,
|
||||||
|
] as const : [
|
||||||
theme['c-350'],
|
theme['c-350'],
|
||||||
theme['c-300'],
|
theme['c-300'],
|
||||||
]
|
0.6,
|
||||||
|
] as const
|
||||||
}, [activeLine, lineNum, theme])
|
}, [activeLine, lineNum, theme])
|
||||||
|
|
||||||
const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => {
|
const handleLayout = ({ nativeEvent }: LayoutChangeEvent) => {
|
||||||
@ -93,14 +95,14 @@ const LrcLine = memo(({ line, lineNum, activeLine, onLayout }: LineProps) => {
|
|||||||
...styles.lineText,
|
...styles.lineText,
|
||||||
textAlign,
|
textAlign,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
}} textBreakStrategy="simple" color={colors[0]} size={size}>{line.text}</AnimatedColorText>
|
}} textBreakStrategy="simple" color={colors[0]} opacity={colors[2]} size={size}>{line.text}</AnimatedColorText>
|
||||||
{
|
{
|
||||||
line.extendedLyrics.map((lrc, index) => {
|
line.extendedLyrics.map((lrc, index) => {
|
||||||
return (<AnimatedColorText style={{
|
return (<AnimatedColorText style={{
|
||||||
...styles.lineTranslationText,
|
...styles.lineTranslationText,
|
||||||
textAlign,
|
textAlign,
|
||||||
lineHeight: lineHeight * 0.8,
|
lineHeight: lineHeight * 0.8,
|
||||||
}} textBreakStrategy="simple" key={index} color={colors[1]} size={size * 0.8}>{lrc}</AnimatedColorText>)
|
}} textBreakStrategy="simple" key={index} color={colors[1]} opacity={colors[2]} size={size * 0.8}>{lrc}</AnimatedColorText>)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
|
@ -21,10 +21,14 @@ export const useAnimateColor = (color: string) => {
|
|||||||
toValue: 1,
|
toValue: 1,
|
||||||
duration: ANIMATION_DURATION,
|
duration: ANIMATION_DURATION,
|
||||||
useNativeDriver: false,
|
useNativeDriver: false,
|
||||||
}).start(() => {
|
}).start((finished) => {
|
||||||
currentColor.current = nextColor
|
if (!finished) return
|
||||||
|
// currentColor.current = nextColor
|
||||||
setFinished(true)
|
setFinished(true)
|
||||||
})
|
})
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
currentColor.current = nextColor
|
||||||
|
})
|
||||||
}, [nextColor])
|
}, [nextColor])
|
||||||
|
|
||||||
return [animColor, finished] as const
|
return [animColor, finished] as const
|
||||||
|
35
src/utils/hooks/useAnimateNumber.ts
Normal file
35
src/utils/hooks/useAnimateNumber.ts
Normal file
@ -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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user