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

Allow animations on the d prop of the Path component. #908

Closed
reneeichhorn opened this issue Jan 22, 2019 · 11 comments
Closed

Allow animations on the d prop of the Path component. #908

reneeichhorn opened this issue Jan 22, 2019 · 11 comments

Comments

@reneeichhorn
Copy link

My use case is that I'm wrapping the Path component with createAnimatedComponent and then simply use react-native-reanimated (their createAnimatedComponent should be compatible to the react-native one)

I debugged the behavior a little bit and when using the wrapped component the app crashes because react-native-svg tries to render with _path = nil and then crashes. To be more detailed:
Elements/RNSVGPath.m::setD is never called and then inRNSVGRenderable.m::renderLayerToit basically calls CFAutorelease with nil and crashes.
I wonder if this related to a wrong or missing setNativeProps.

Anyone having a idea how to fix it.

@msand
Copy link
Collaborator

msand commented Jan 22, 2019

Can you provide a full replication?

@reneeichhorn
Copy link
Author

reneeichhorn commented Jan 23, 2019

Sure

import { Svg, Path } from 'react-native-svg';
import Animated from 'react-native-reanimated';

const { concat, multiply } = Animated;
const x = multiply(1, 2)
const y = multiply(2, 3)
const path = concat('M 0 0 L ', x, ' ', y)

const AnimatedPath = Animated.createAnimatedComponent(Path);

const DemoComponent = () => (
  <Svg viewport="0 0 10 10" width="100" height="100">
    <AnimatedPath d={path} />
  </Svg>
)

I would do an example without reanimated but there is no way of creating a string from an animated value in react-native animated. Anyway the createAnimatedComponent of reanimated behaves very similar.

This is also a static example without any animation involved but that shouldn't make any difference.

@msand
Copy link
Collaborator

msand commented Jan 23, 2019

A few minor changes needed, stroke was missing and viewport needs to be viewBox instead:

import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Svg, Path } from 'react-native-svg';
import Animated from 'react-native-reanimated';

const { concat, multiply } = Animated;
const x = multiply(1, 2);
const y = multiply(2, 3);
const path = concat('M 0 0 L ', x, ' ', y);

const AnimatedPath = Animated.createAnimatedComponent(Path);

const DemoComponent = () => (
  <Svg viewBox="0 0 10 10" width="100" height="100">
    <AnimatedPath d={path} stroke="black" />
  </Svg>
);

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <DemoComponent />
      </View>
    );
  }
}

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

But otherwise seems to work fine, with no changes needed to the library.

msand added a commit to msand/react-native-reanimated that referenced this issue Jan 23, 2019
software-mansion/react-native-svg#908

```jsx
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Svg, Path } from 'react-native-svg';
import Animated from 'react-native-reanimated';

const { concat, multiply } = Animated;
const x = multiply(1, 2);
const y = multiply(2, 3);
const path = concat('M 0 0 L ', x, ' ', y);

const AnimatedPath = Animated.createAnimatedComponent(Path);

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Svg viewBox="0 0 10 10" width="100" height="100">
          <AnimatedPath d={path} stroke="black" />
        </Svg>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
  },
});
```
@msand
Copy link
Collaborator

msand commented Jan 23, 2019

Android required a bit of modification in reanimated, check my pull request here: software-mansion/react-native-reanimated#176

@reneeichhorn
Copy link
Author

Wow! Thats amazing, thank you a lot!
So on iOS it was my bad, I was still on version 8 unfortunately, works for me now as well!

@msand
Copy link
Collaborator

msand commented Jan 23, 2019

Also, wrote a small tagged template literal function:

function animatedString(strings, ...values) {
  const arr = [];
  const n = values.length;
  for (let i = 0; i < n; i++) {
    arr.push(strings[i], values[i]);
  }
  const end = strings[n];
  if (end) {
    arr.push(end);
  }
  return concat(...arr);
}

const path = animatedString`M0,0 L${x},${y}`;

@reneeichhorn
Copy link
Author

Wow that was fast :D Creating a tagged template was exactly my idea as well 👍

I think there is lots of potential with animated paths especially for charts etc.

@wcandillon
Copy link
Contributor

@msand Haha amazing trick thks ;-)

@stackerine
Copy link

I'm new with react-native-reanimated but all my try to interpolate svg path were unsuccessful. Can you help me with a full example?

@wcandillon
Copy link
Contributor

I have a couple examples on my youtube channel, the most recent one is https://www.youtube.com/watch?v=gLopy2MCAqM

@stackerine
Copy link

Already saw that! Amazing work... Thank a lot @wcandillon.

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