英文:
How to animate expo-linear-gradient with reanimated?
问题
我正在使用react-native-reanimated
,希望对我的expo-linear-gradient
进行颜色动画。不幸的是,什么都没有改变。我还创建了一个Expo Snack。
import * as React from 'react';
import { View, Button } from 'react-native';
import Animated, {
interpolateColor,
useAnimatedProps,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { LinearGradient } from 'expo-linear-gradient';
const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient);
export default function App() {
const colorsValue = useSharedValue(1);
const animatedProps = useAnimatedProps(() => {
return {
colors: [
interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#000000']),
interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#00ff00']),
],
};
});
return (
<View>
<AnimatedLinearGradient
animatedProps={animatedProps}
style={{ height: 400, width: '100%' }}
/>
<Button
title="Change colors"
onPress={() => (colorsValue.value = withTiming(0, { duration: 2000 }))}
/>
</View>
);
}
我在这里使用animatedProps错了吗?任何帮助将不胜感激。
英文:
I am using react-native-reanimated
and want to animate the colors of my expo-linear-gradient
. Unfortunately, nothing changes. I also created a Expo Snack.
import * as React from 'react';
import { View, Button } from 'react-native';
import Animated, {
interpolateColor,
useAnimatedProps,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { LinearGradient } from 'expo-linear-gradient';
const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient);
export default function App() {
const colorsValue = useSharedValue(1);
const animatedProps = useAnimatedProps(() => {
return {
colors: [
interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#000000']),
interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#00ff00']),
],
};
});
return (
<View>
<AnimatedLinearGradient
animatedProps={animatedProps}
style={{ height: 400, width: '100%' }}
/>
<Button
title="Change colors"
onPress={() => (colorsValue.value = withTiming(0, { duration: 2000 }))}
/>
</View>
);
}
Am I using animatedProps wrongly here? Any help would greatly be appreciated.
答案1
得分: 4
很抱歉,我不确定你是否可以做到这一点。您正确使用了useAnimatedProps
钩子,但通常它不会适用于所有属性。
如果您想实现这种类型的动画,我强烈建议您尝试使用@shopify/react-native-skia包中的LinearGradient组件。
您可以轻松地重用相同的逻辑,但使用Skia值:
const colorsValue = useSharedValue(1);
const skiaFirstColor = useValue(0);
const skiaSecondColor = useValue(0);
useSharedValueEffect(() => {
skiaFirstColor.current = interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#000000']);
skiaSecondColor.current = interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#00ff00']);
}, colorsValue); // 您可以将其他共享值作为额外参数传递
const colors = useComputedValue(() => {
return [skiaFirstColor.current, skiaSecondColor.current]
}, [skiaFirstColor, skiaSecondColor])
return (
<...
<Canvas>
<LinearGradient colors={colors} />
</Canvas>
</>)
希望对您有所帮助。
英文:
unfortunately, I'm not sure you can do that. You're using correctly the useAnimatedProps
hook, but usually it doesn't work for all properties.
If you want to achieve this type of animation, I highly recommend you to try the LinearGradient component from @shopify/react-native-skia package.
You can easily reuse the same logic, but with the Skia values:
const colorsValue = useSharedValue(1);
const skiaFirstColor = useValue(0);
const skiaSecondColor = useValue(0);
useSharedValueEffect(() => {
skiaFirstColor.current = interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#000000']);
skiaSecondColor.current = interpolateColor(colorsValue.value, [0, 1], ['#FFFFFF', '#00ff00']);
}, colorsValue); // you can pass other shared values as extra parameters
const colors = useComputedValue(() => {
return [skiaFirstColor.current, skiaSecondColor.current]
}, [skiaFirstColor, skiaSecondColor])
return (<...
<Canvas>
<LinearGradient colors={colors} />
</Canvas>
</>)
Let me know if it helps.
答案2
得分: 2
我认为使用 expo-linear-gradient
不太可能实现这个效果,因为这个组件在 iOS 等平台下底层使用的是 CALayer,如果你查看 Reanimated 文档中的 useAnimatedProps 部分,它指出:
> 只有“原生视图”的“本地”属性可以通过 useAnimatedProps 设置。这个钩子函数最常见的用法是在我们想要动画化某个第三方原生组件的属性时,因为大多数 React Native 核心组件的属性实际上都是样式的一部分(至少对于那些有意义的可动画化属性来说是这样的)。你可以使用以下函数来动画化 Reanimated 默认不支持的属性:
> addWhitelistedNativeProps() 用于动画化触发布局重新计算的属性,你可以在这里找到它们。
> addWhitelistedUIProps() 用于直接在 UI 线程上更新的属性,目前允许的属性在这里列出。
此外,看起来使用 SVG 也不太可能实现 - https://github.com/software-mansion/react-native-reanimated/issues/690
也许这个示例可以帮助你使用 SVG 构建动画 https://github.com/FullstackStation/react-native-svg-animated-linear-gradient
英文:
I think it is not possible to do this with expo-linear-gradient
because under the hood of this component on ios for example is CALayer and if you check reanimated docs for useAnimatedProps it says that:
> Only "native" properties of "native views" can be set via useAnimatedProps. The most common usecase for this hook is when we want to animate properties of some third-party native component, since most of the properties for the core React Native components are a part of the styles anyways (at least the properties for which it makes sense to be animated). You can use the following functions to animate properties that Reanimated don't support by default:
> addWhitelistedNativeProps() is used to animate properties that trigger layout recalculation, you can find them here.
> addWhitelistedUIProps() is used for properties that are updated directly on the UI thread, currently allowed props are listed here.
Also looks like it is not possible to do with SVG - https://github.com/software-mansion/react-native-reanimated/issues/690
Maybe this example can help you to build your animation with SVG https://github.com/FullstackStation/react-native-svg-animated-linear-gradient
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论