question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Expo 44, Reanimated V2.3.1 bug on interpolateColor

See original GitHub issue

Description

The error reads as Exception in HostFunction: Javascript worklet error [native code]

[native code]

the error originates from interpolateColor. I managed to fix the error by using my own implementation of interpolateColor. Note: the same code base worked fine in previous Reanimated V2 versions.

Expected behavior

The interpolateColor should return a color value interpolated between the first and second colors. Instead, it throws Exception in HostFunction: Javascript worklet error [native code]

[native code]

Snack or minimal code example

problematic code

const isActive = useSharedValue(false);
const activeProgress = useDerivedValue(()=>{
    return withTiming(isActive.value ? 100 : 0); 
}, [isActive.value]);

const rStyle = useAnimatedStyle(()=>{
        return {
            backgroundColor: interpolateColor(
                activeProgress.value,
                [0, 100],
                [color1, color2]
            ),
        }
}, [activeProgress.value, color1, color2]);

the rStyle is assigned to an Animated.View component as usual.

Quick Fix

until the bug is resolved, fellow programmers can use this code as a replacement for interpolateColor. please note that the below code does not work with color names like “red” and “yellow”. But it would work with both 6 digit, and 8 digit hex values. any rgba and rgb value would also work.

import {interpolate} from "react-native-reanimated";

function hexToRGBA(hw: string){
    'worklet';
    if (hw.length === 4){
        return {
            r: parseInt(hw.substr(1, 1), 16),
            g: parseInt(hw.substr(2, 1), 16),
            b: parseInt(hw.substr(3, 1), 16),
            a: 1
        }
    }
    const r = parseInt(hw.slice(1, 3), 16);
    const g = parseInt(hw.slice(3, 5), 16);
    const b = parseInt(hw.slice(5, 7), 16);
    const a = hw.length === 9 ? parseInt(hw.slice(7, 9), 16)/255 : 1;

    return {
        r,g,b,a
    }
}

function colorToRGBA(color: string|{r:number, g: number, b: number}|{r:number, g: number, b: number, a: number}){
    'worklet';
    if (typeof color === 'string'){
        if (color.startsWith("rgba(")){
            const colorProcessed = color.split("(")[1].split(")")[0].split(",");
            return {
                r: parseInt(colorProcessed[0].trim()),
                g: parseInt(colorProcessed[1].trim()),
                b: parseInt(colorProcessed[2].trim()),
                a: parseInt(colorProcessed[3].trim()),
            }
        }
        else if (color.startsWith("rgb(")){
            const colorProcessed = color.split("(")[1].split(")")[0].split(",");
            return {
                r: parseInt(colorProcessed[0].trim()),
                g: parseInt(colorProcessed[1].trim()),
                b: parseInt(colorProcessed[2].trim()),
                a: 1,
            }
        }
        else {
            return hexToRGBA(color);
        }
    } else {
        return {
            r: color.r,
            g: color.g,
            b: color.b,
            // @ts-ignore
            a: Object.keys(color).includes('a') ? color.a : 1,
        }
    }
}

export default function interpolateColorBugFix(value: number, inputRange: readonly number[], outputRange: readonly (string | number)[]){
    'worklet';
    const outputRangeProcessed = outputRange.map(i => colorToRGBA(i as string));
    const values = {
        r: interpolate(
            value,
            inputRange,
            outputRangeProcessed.map(i => i.r)
        ),
        g: interpolate(
            value,
            inputRange,
            outputRangeProcessed.map(i => i.g)
        ),
        b: interpolate(
            value,
            inputRange,
            outputRangeProcessed.map(i => i.b)
        ),
        a: interpolate(
            value,
            inputRange,
            outputRangeProcessed.map(i => i.a)
        ),
    }
    return `rgba(${values.r},${values.g},${values.b}, ${values.a})`
}

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:17
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
AriaBaghericommented, Feb 1, 2022

Hi @sanborN93 @AriaBagheri

Could you please verify if what @mblarsen mentioned works for you and fixes your issue?

Unfortunately the problem is not caused by withTiming. The interpolateColor does not work sometimes even if the withTiming function is not used. It is unclear to me if underlay, the interpolateColor uses withTiming in any way shape or form. (I don’t think it is supposed to). The problem is within the interpolateColor. It is worth noting that interpolate works as expected. So in my quick fix I used interpolate and fit fixed the problem.

1reaction
jkadamczykcommented, Jan 28, 2022

BTW, if you could please follow the issue template, it would be very helpful.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reanimated - Expo Documentation
Reanimated uses React Native APIs that are incompatible with "Remote JS Debugging" for JavaScriptCore. In order to use a debugger with your app...
Read more >
interpolateColors | React Native Reanimated
This is documentation for React Native Reanimated 1.x.x, which is no longer actively maintained. For up-to-date documentation, see the latest version (2.5.x – ......
Read more >
Interpolate Colors like a pro with React Native Reanimated 2 ...
In this tutorial we'll learn the concept behind the interpolateColor function from React Native Reanimated. To improve the learning ...
Read more >
a module failed to load due to an error and appregistry ...
Describe the bug In our recently set up Expo app, we get a reference error as ... Being able to quickly create a...
Read more >
Interpolate Colors like a pro with React Native Reanimated 2
Today we are going to understand the concept behind the interpolateColor function from the react-native-reanimated (v2) package.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found