Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to animate any SVG color on android #6080

Closed
noah-blanchard opened this issue Jun 5, 2024 · 5 comments
Closed

Impossible to animate any SVG color on android #6080

noah-blanchard opened this issue Jun 5, 2024 · 5 comments
Labels
Platform: Android This issue is specific to Android Platform: Web This issue is specific to web Repro provided A reproduction with a snippet of code, snack or repo is provided

Comments

@noah-blanchard
Copy link

noah-blanchard commented Jun 5, 2024

Description

Any color, fill color, stroke color... on an SVG don't get updated, on ANDROID specifically

Expected behavour

Update the color of the stroke or fill when pressing the button

Steps to reproduce

const AnimatedCircle = Animated.createAnimatedComponent(Circle);

export default function AnimCircle() {
  const sh = useSharedValue(10);

  const handlePress = () => {
    sh.value += 10;
  };

  const animatedProps = useAnimatedProps(() => {
    console.log(interpolateColor(sh.value % 30, [0, 10, 20], ['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)']));
    return { r: 50, stroke: interpolateColor(sh.value % 30, [0, 10, 20], ['blue', 'red', 'green']) };
  });

  return (
    <View style={styles.container}>
      <Svg style={styles.svg}>
        <AnimatedCircle cx="50%" cy="50%" strokeWidth={10} animatedProps={animatedProps} />
      </Svg>
      <Button onPress={handlePress}>Press me !</Button>
    </View>
  );
}

Here's the log result :

 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936
 LOG  -16776961
 LOG  -65536
 LOG  -16711936

Similar issues

I found some similar issues stating I should use RGB colors, I tried all I could try but I'm still having exactly the same problem unfortunately.

Everything's works perfectly on my web browser, but never on my phone.
I'm using storybook and expo.

Snack or a link to a repository

https://snack.expo.dev/4HWDed_sqs1LuhrMgL8aX

Reanimated version

3.6.2

React Native version

0.68.7

Platforms

Android, Web

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Repro provided A reproduction with a snippet of code, snack or repo is provided Platform: Android This issue is specific to Android Platform: Web This issue is specific to web Missing info The user didn't precise the problem enough and removed Missing info The user didn't precise the problem enough labels Jun 5, 2024
@Martinocom
Copy link

@szydlovsky
Copy link
Contributor

hey @noah-blanchard, just as @Martinocom mentioned, animated prop adapter is the way to go for you. I have added the adapter to your example to make it work:

import React from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { Svg, Circle } from 'react-native-svg';
import Animated, {
  interpolateColor,
  useSharedValue,
  useAnimatedProps,
  createAnimatedPropAdapter,
  processColor,
} from 'react-native-reanimated';

const AnimatedCircle = Animated.createAnimatedComponent(Circle);

const strokeAdapter = createAnimatedPropAdapter(
  (props) => {
    if (Object.keys(props).includes('stroke')) {
      props.stroke = { type: 0, payload: processColor(props.stroke) };
    }
  },
  ['stroke']
);

export default function AnimCircle() {
  const sh = useSharedValue(10);

  const handlePress = () => {
    sh.value += 10;
  };

  const animatedProps = useAnimatedProps(
    () => {
      return {
        r: 50,
        stroke: interpolateColor(
          sh.value % 30,
          [0, 10, 20],
          ['blue', 'red', 'green']
        ),
      };
    },
    null,
    strokeAdapter
  );

  return (
    <View style={styles.container}>
      <Svg style={styles.svg}>
        <AnimatedCircle
          cx="50%"
          cy="50%"
          strokeWidth={10}
          animatedProps={animatedProps}
        />
      </Svg>
      <Button title={'Press me!'} onPress={handlePress} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  svg: {
    width: 200,
    height: 200,
  },
});

@noah-blanchard
Copy link
Author

hey @szydlovsky
indeed it is working fine on android now, but not anymore on my browser !
This fixed the android issue, but now a new issue appeared on browser...

@szydlovsky
Copy link
Contributor

@noah-blanchard then it is strightforward: add a platform check when passing adapter argument; for web null, otherwise the adapter

@noah-blanchard
Copy link
Author

@noah-blanchard then it is strightforward: add a platform check when passing adapter argument; for web null, otherwise the adapter

I'll do this, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Android This issue is specific to Android Platform: Web This issue is specific to web Repro provided A reproduction with a snippet of code, snack or repo is provided
Projects
None yet
Development

No branches or pull requests

3 participants