How to change icon name with Reanimated
AuroPick opened this issue · 1 comments
- Review the documentation: https://github.com/oblador/react-native-vector-icons
- Search for existing issues (including closed ones): https://github.com/oblador/react-native-vector-icons/issues
Environment
Description
I want to use shared value as name prop but it is not working.
I created an Animated component with
const AnimatedFontAwesome6Icon = Animated.createAnimatedComponent(FontAwesome6Icon)
and used it like this
<AnimatedFontAwesome6Icon animatedProps={iconAnimatedProps} size={20)} />
animatedProps is calculated like this
const iconAnimatedProps = useAnimatedProps<FontAwesome6IconProps>(() => ({
name: iconName.value,
color: fontColor.value
}))
color is working fine but name prop is not changing even through iconName.value is changing
this is how iconName is calculated
const iconName = useDerivedValue(() => {
if (isActive) {
const foundPointIndex = points.findIndex((point) => point.date === chartState.x.value.value)
if (foundPointIndex === -1) return 'minus'
const previousPoint = points[foundPointIndex - 1]
if (!previousPoint) return 'minus'
if (chartState.y.value.value.value > previousPoint.value) return 'caret-up'
if (chartState.y.value.value.value < previousPoint.value) return 'caret-down'
return 'minus'
}
const lastPoint = points[points.length - 1]
const previousPoint = points[points.length - 2]
if (!lastPoint || !previousPoint) return 'minus'
if (lastPoint.value > previousPoint.value) return 'caret-up'
if (lastPoint.value < previousPoint.value) return 'caret-down'
return 'minus'
})
Demo
You can use https://snack.expo.io/ to create a demo that can help users to better understand your problem.
Okay I found a way. Instead of using font component I created a text input like suggested in reanimated website
https://docs.swmansion.com/react-native-reanimated/examples/slider. You can found at the bottom of the page
const iconName = useDerivedValue(() => {
if (isActive) {
const foundPointIndex = points.findIndex((point) => point.date === chartState.x.value.value)
if (foundPointIndex === -1) return String.fromCodePoint(61544)
const previousPoint = points[foundPointIndex - 1]
if (!previousPoint) return String.fromCodePoint(61544)
if (chartState.y.value.value.value > previousPoint.value) return String.fromCodePoint(61656)
if (chartState.y.value.value.value < previousPoint.value) return String.fromCodePoint(61655)
return String.fromCodePoint(61544)
}
const lastPoint = points[points.length - 1]
const previousPoint = points[points.length - 2]
if (!lastPoint || !previousPoint) return String.fromCodePoint(61544)
if (lastPoint.value > previousPoint.value) return String.fromCodePoint(61656)
if (lastPoint.value < previousPoint.value) return String.fromCodePoint(61655)
return String.fromCodePoint(61544)
})
I got the numbers from glyphmaps folder
https://github.com/oblador/react-native-vector-icons/tree/e3e7ba7cf27ca38152e8994eeffd9afec7a1b97b/glyphmaps
got the font family like this
const fontAwesome6FontFamily = (FontAwesome6Icon as any).getFontFamily('solid') as Font
used it like this
<AnimatedDescription
fontFamily={fontAwesome6FontFamily}
styleOverride={styles.icon}
fontColor={changeFontColor}
text={iconName}
fontSize={wp(5)}
/>
this is the AnimatedDescription component
import React, { memo } from 'react'
import { ColorValue, StyleSheet, TextInput, TextStyle } from 'react-native'
import Animated, {
useAnimatedProps,
useAnimatedStyle,
type SharedValue
} from 'react-native-reanimated'
import { Font } from '../../core/font'
import { useDynamicColors } from '../../hooks/useDynamicColors'
const AnimText = Animated.createAnimatedComponent(TextInput)
Animated.addWhitelistedNativeProps({ text: true })
type AnimatedDescriptionProps = {
text: SharedValue<string>
styleOverride?: TextStyle
fontSize?: number
fontColor?: SharedValue<ColorValue>
numberOfLines?: number
textCenter?: boolean
fontFamily?: Font
}
function AnimatedDescriptionComponent({
text,
styleOverride,
fontSize,
fontColor,
numberOfLines,
textCenter,
fontFamily
}: AnimatedDescriptionProps) {
const dynamicColors = useDynamicColors()
const animProps = useAnimatedProps(() => ({
text: text.value,
defaultValue: text.value
}))
const textStyle = useAnimatedStyle(
() => ({
...styles.text,
color: dynamicColors.text,
...(fontSize && { fontSize }),
...(fontColor && { color: fontColor.value }),
...(textCenter && styles.center),
...(fontFamily && { fontFamily }),
...(styleOverride && styleOverride)
}),
[styleOverride, fontSize, fontColor, textCenter, fontFamily, dynamicColors.text]
)
return (
<AnimText
style={textStyle}
// @ts-ignore
animatedProps={animProps}
editable={false}
numberOfLines={numberOfLines}
/>
)
}
export const AnimatedDescription = memo(AnimatedDescriptionComponent)
const styles = StyleSheet.create({
text: {
fontFamily: 'Inter-Regular',
fontSize: 12,
flexShrink: 1
},
center: {
textAlign: 'center'
}
})