setting SVG fill color via useAnimatedProps fails with "Too few elements in array"
Description
I try to set the fill color of an SVG element via useAnimatedProps.
The color's string value seems to be interpreted as an array instead of a plain string and I get the error message ""Too few elements in array...".
If the color is set directly via the fill property (without using useAnimatedProps) the behavior is as expected.
When I use rgba(137, 41, 233, 1) instead of #8929E9, the error does not occur.
Expected behavior
Color value is set correctly.
Actual behavior & steps to reproduce
Click on "change color" button in the below example, then the following error is thrown:

Snack or minimal code example
import React from 'react';
import {Button, View} from 'react-native';
import Animated, {
useAnimatedProps,
useSharedValue,
} from 'react-native-reanimated';
import Svg, {Rect} from 'react-native-svg';
const AnimatedRect = Animated.createAnimatedComponent(Rect);
function App() {
const currentNumberIndex = useSharedValue(1);
const animatedProps = useAnimatedProps(() => ({
fill: currentNumberIndex.value === 0 ? '#8929E9' : '#C4C4C4',
}));
return (
<View style={{flex: 1}}>
<Svg width={200} height={200}>
<AnimatedRect
x={100}
y={100}
width={100}
height={10}
animatedProps={animatedProps}
/>
</Svg>
<Button
title="change color"
onPress={() => (currentNumberIndex.value = 0)}
/>
</View>
);
}
Package versions
- React Native: 0.64.1
- React Native Reanimated: 2.3.0-beta.3
- react-native-svg: 12.2.0
Affected platforms
- [x] iOS
Issue validator
The issue is valid!
Use interpolateColor
Like:
interpolateColor(currentNumberIndex.value, [0, 1], ['#8929E9', '#C4C4C4'])
@schiller-manuel Can you please check if interpolateColor works for you on Reanimated 2.3.1?
@schiller-manuel Can you please check if
interpolateColorworks for you on Reanimated 2.3.1?
Hi @tomekzaw,
I tried interpolateColor, it did not work:
const animatedProps = useAnimatedProps(() => {
const fill = interpolateColor(
currentNumberIndex.value,
[0, 1],
['#8929E9', '#C4C4C4'],
);
return {
fill,
};
});
resulted in:
Attempted to assign to readonly property.
_f@/Users/app/node_modules/react-native-reanimated/src/reanimated2/Colors.ts (693:32):1:816
@[native code]
_f@/Users/app/node_modules/react-native-reanimated/src/reanimated2/Colors.ts (772:32):1:376
@[native code]
_f@/Users/app/src/BugReports.tsx (17:4):1:103
@[native code]
_f@/Users/app/node_modules/react-native-reanimated/src/reanimated2/hook/useAnimatedStyle.ts (473:18):1:83
@[native code]
styleUpdater@/Users/app/node_modules/react-native-reanimated/src/reanimated2/hook/useAnimatedStyle.ts (183:0):1:376
@[native code]
_f@/Users/app/node_modules/react-native-reanimated/src/reanimated2/hook/useAnimatedStyle.ts (498:12):1:141
@[native code]
reanimated::REAIOSErrorHandler::raiseSpec()
REAIOSErrorHandler.mm:18
reanimated::ErrorHandler::raise()::'lambda'()::operator()()
decltype(std::__1::forward<reanimated::ErrorHandler::raise()::'lambda'()&>(fp)()) std::__1::__invoke<reanimated::ErrorHandler::raise()::'lambda'()&>(reanimated::ErrorHandler::raise()::'lambda'()&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<reanimated::ErrorHandler::raise()::'lambda'()&>(reanimated::ErrorHandler::raise()::'lambda'()&)
std::__1::__function::__alloc_func<reanimated::ErrorHandler::raise()::'lambda'(), std::__1::allocator<reanimated::ErrorHandler::raise()::'lambda'()>, void ()>::operator()()
std::__1::__function::__func<reanimated::ErrorHandler::raise()::'lambda'(), std::__1::allocator<reanimated::ErrorHandler::raise()::'lambda'()>, void ()>::operator()()
std::__1::__function::__value_func<void ()>::operator()() const
std::__1::function<void ()>::operator()() const
reanimated::REAIOSScheduler::scheduleOnUI(std::__1::function<void ()>)
reanimated::ErrorHandler::raise()
reanimated::NativeReanimatedModule::onRender(double)
reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1::operator()(double) const
decltype(std::__1::forward<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1&>(fp)(std::__1::forward<double>(fp0))) std::__1::__invoke<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1&, double>(reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1&, double&&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1&, double>(reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1&, double&&)
std::__1::__function::__alloc_func<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1, std::__1::allocator<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1>, void (double)>::operator()(double&&)
std::__1::__function::__func<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1, std::__1::allocator<reanimated::NativeReanimatedModule::NativeReanimatedModule(std::__1::shared_ptr<facebook::react::CallInvoker>, std::__1::shared_ptr<reanimated::Scheduler>, std::__1::shared_ptr<facebook::jsi::Runtime>, std::__1::shared_ptr<reanimated::ErrorHandler>, std::__1::function<facebook::jsi::Value (facebook::jsi::Runtime&, int, facebook::jsi::String const&)>, std::__1::shared_ptr<reanimated::LayoutAnimationsProxy>, reanimated::PlatformDepMethodsHolder)::$_1>, void (double)>::operator()(double&&)
std::__1::__function::__value_func<void (double)>::operator()(double&&) const
std::__1::function<void (double)>::operator()(double) const
invocation function for block in reanimated::createReanimatedModule(RCTBridge*, std::__1::shared_ptr<facebook::react::CallInvoker>)::$_2::operator()(std::__1::function<void (double)>, facebook::jsi::Runtime&) const
-[REANodesManager onAnimationFrame:]
CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long)
display_timer_callback(__CFMachPort*, void*, long, void*)
__CFMachPortPerform
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
__CFRunLoopDoSource1
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
main
start_sim
0x0
However, even if it did work: Why would I have to use interpolate colors if I just want to switch between to color values?
The fill colour is not animated in my case and sticks to the first colour before transitioning.
Hi @schiller-manuel!
The problem is that your rectangle expects RGBA instead of #RRGGBB for its fill colour. You don't have to convert your colors manually, you can use our function processColor.