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

Not compatible with Reanimated 'color' #1241

Closed
michalpetrov opened this issue Jan 6, 2020 · 8 comments
Closed

Not compatible with Reanimated 'color' #1241

michalpetrov opened this issue Jan 6, 2020 · 8 comments

Comments

@michalpetrov
Copy link

Right now the library is not compatible with Reanimated 'color'. Trying to use it ends with error: "[object Object] is not valid color or brush"

import Animated from 'react-native-reanimated'
const { color, Value } = Animated
const anim = new Value(0.0)
const pathColor= color(47, 195, 215, anim)
...
<Svg>
  <Path fill={pathColor} ... />
</Svg>

Is there any quick workaround?

@msand
Copy link
Collaborator

msand commented Jan 6, 2020

I'd have to place some breakpoints and isolate the cause of the issue first, then i might be able to deduce various workarounds, and/or make a fix for react-native-svg, react-native-reanimated, or both.

@michalpetrov
Copy link
Author

michalpetrov commented Jan 6, 2020

Find out that I can use fill-opacity to animated only the opacity.

So the workaround for my case is:

import Animated from 'react-native-reanimated'
const { Value } = Animated
const AnimatedPath = Animated.createAnimatedComponent(Path)
const anim = new Value(0.0)
...
<Svg>
  <AnimatedPath fill="#ffffff: fill-opacity={anime} ... />
</Svg>

@jayu
Copy link
Contributor

jayu commented Jan 13, 2020

I'm facing similar issue also. I found a workaround to use Reanimated.concat
However, it is buggy on Android. Color is blinking instead of being animated. iOS works fine.
Support for Reanimated.color would be awesome.

import Animated from 'react-native-reanimated'
const { concat, Value } = Animated
const anim = new Value(0.0)
const pathColor= concat('rgb(', 47, ',', 195, ',', anim, ')')
...
<Svg>
  <Path fill={pathColor} ... />
</Svg>

@msand
Copy link
Collaborator

msand commented Jan 13, 2020

Seems to work, perhaps you forgot to wrap in createAnimatedComponent?
https://snack.expo.io/@msand/bold-soda

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Svg, Path, Circle } from 'react-native-svg';
import Constants from 'expo-constants';
import Animated, { Easing }  from 'react-native-reanimated';
const AnimatedPath = Animated.createAnimatedComponent(Path);
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

const {
  set,
  concat,
  cond,
  eq,
  and,
  startClock,
  clockRunning,
  block,
  timing,
  Value,
  Clock,
  interpolate,
} = Animated;

function runTiming(clock, value, dest) {
  const state = {
    finished: new Value(1),
    position: new Value(value),
    time: new Value(0),
    frameTime: new Value(0),
  };

  const config = {
    duration: 500,
    toValue: new Value(0),
    easing: Easing.inOut(Easing.ease),
  };

  const reset = [
    set(state.finished, 0),
    set(state.time, 0),
    set(state.frameTime, 0),
  ];

  return block([
    cond(and(state.finished, eq(state.position, value)), [
      ...reset,
      set(config.toValue, dest),
    ]),
    cond(and(state.finished, eq(state.position, dest)), [
      ...reset,
      set(config.toValue, value),
    ]),
    cond(clockRunning(clock), 0, startClock(clock)),
    timing(clock, state, config),
    state.position,
  ]);
}

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    const clock = new Clock();
    const base = runTiming(clock, -1, 1);
    this.anim = interpolate(base, {
      inputRange: [-1, 1],
      outputRange: [0, 255],
    });
  }
  render() {
    const pathColor = concat('rgb(', 47, ',', 195, ',', this.anim, ')'); 
    return (
      <View style={styles.container}>
        <Svg width="100%" height="100%" viewBox="0 0 100 100">
          <AnimatedPath stroke={pathColor} d="M0,0L100,100" />
          <AnimatedCircle r="50" fill={pathColor} />
        </Svg>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

@jayu
Copy link
Contributor

jayu commented Jan 14, 2020

I missed one detail. It is blinking when I'm trying to animate more than one rbg value. My goal was to go from only red, to only green. I forked your snack https://snack.expo.io/@jaysbytes/bold-soda

Circle fill works fine, but path stroke blinks

svg

@3luyka
Copy link

3luyka commented Jan 17, 2020

Same issue with color animation. But in my case, I want to animate between 3 different colors.

@msand
Copy link
Collaborator

msand commented Jan 18, 2020

Can you try with the latest commit from the develop branch?

import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Svg, Path, Circle } from 'react-native-svg';
import Animated, { Easing }  from 'react-native-reanimated';
const AnimatedPath = Animated.createAnimatedComponent(Path);
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

const {
    color,
    set,
    cond,
    eq,
    and,
    startClock,
    clockRunning,
    block,
    timing,
    Value,
    Clock,
    interpolate,
} = Animated;

function runTiming(clock, value, dest) {
    const state = {
        finished: new Value(1),
        position: new Value(value),
        time: new Value(0),
        frameTime: new Value(0),
    };

    const config = {
        duration: 500,
        toValue: new Value(0),
        easing: Easing.inOut(Easing.ease),
    };

    const reset = [
        set(state.finished, 0),
        set(state.time, 0),
        set(state.frameTime, 0),
    ];

    return block([
        cond(and(state.finished, eq(state.position, value)), [
            ...reset,
            set(config.toValue, dest),
        ]),
        cond(and(state.finished, eq(state.position, dest)), [
            ...reset,
            set(config.toValue, value),
        ]),
        cond(clockRunning(clock), 0, startClock(clock)),
        timing(clock, state, config),
        state.position,
    ]);
}

export default class App extends React.Component {
    constructor(props) {
        super(props);
        const clock = new Clock();
        const base = runTiming(clock, -1, 1);
        this.anim = interpolate(base, {
            inputRange: [-1, 1],
            outputRange: [0, 1],
        });
    }
    render() {
        const pathColor= color(47, 195, 215, this.anim)
        return (
            <View style={styles.container}>
                <Svg width="100%" height="100%" viewBox="0 0 100 100">
                    <AnimatedPath stroke={pathColor} d="M0,0L100,100" />
                    <AnimatedCircle r="50" fill={pathColor} />
                </Svg>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        backgroundColor: '#ecf0f1',
        padding: 8,
    },
});

@msand msand closed this as completed in 4983766 Jan 18, 2020
msand pushed a commit that referenced this issue Jan 18, 2020
# [11.0.0](v10.1.0...v11.0.0) (2020-01-18)

### Bug Fixes

* compatibility with reanimated color, fixes [#1241](#1241) ([4983766](4983766))
* **android:** NullPointerException when calling getBBox [#1215](#1215) ([3eb82a9](3eb82a9))
* **android:** support animating stroke color ([c5dd62f](c5dd62f))
* **android:** support setting path null ([2d34734](2d34734))
* **ios:** iOS 10.3 renders opaque background when drawRect is defined ([61bc9bd](61bc9bd)), closes [#1252](#1252)
* **web:** Allow createElement & unstable_createElement usage ([#1240](#1240)) ([7a23968](7a23968))

* fix(android)!: pivot point for RN transform array syntax ([db682f8](db682f8))

### BREAKING CHANGES

* Makes android specific transform origin adjustments
 unnecessary / broken. Renders exactly the same as web and ios instead.
@msand
Copy link
Collaborator

msand commented Jan 18, 2020

🎉 This issue has been resolved in version 11.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@msand msand added the released label Jan 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants