GithubHelp home page GithubHelp logo

fram-x / fluidtransitions Goto Github PK

View Code? Open in Web Editor NEW
2.9K 41.0 194.0 9.12 MB

Fluid Transitions for React Navigation

License: MIT License

JavaScript 94.00% Python 1.32% Java 1.70% Objective-C 2.98%
react-native react-navigation animation transition shared-element-transition

fluidtransitions's Introduction

Fluid Transitions for React Navigation

Introduction

This project aims to implement a simple yet powerful set of constructs for building fluid transitions between elements when navigating with React Navigation.

The library is JavaScript only - no linking required.

Snack

The library implements a new navigator component called FluidNavigator with the same interface and routing configuration as the StackNavigator. The library has a component called Transition which can be used to build different types of transitions that will automatically be run when navigating between screens using the regular navigation actions.

The Navigator's API is identical to the StackNavigator except that it does not support a header component. It can easily be integrated with redux and your existing navigation setups.

Medium article
React Native Animation Challenge #1

Installation

To install the library into your project, run yarn or npm:

yarn add react-navigation-fluid-transitions

or

npm i -S react-navigation-fluid-transitions

Compatible versions with react-navigation:

react-navigation-fluid-transitions react-navigation
0.3.x 3.x
0.2.x 2.x
0.1.x 1.x

Future improvements and development will be on [email protected].

Examples

Examples are included in the project and should be runnable from the root of the project folder.

To start the example run the following commands from the terminal:

npm i or yarn

To start the project run

react-native run-ios or react-native run-android

Shared Element Transitions

This example shows how two elements can be set up to automatically transition between each other when navigating between screens. A more detailed edition of this example can be found in the file SharedElements.js.

Note that a shared transition happens between two elements that looks the same. The library animates position and scale between the two hence using different styles and content between the two elements will result in strange transitions.

const Screen1 = (props) => (
  <View style={styles.container}>
    <Text>Screen 1</Text>
    <View style={styles.screen1}>
      <Transition shared='circle'>
        <View style={styles.circle}/>
      </Transition>
    </View>
    <Button
      title='Next'
      onPress={() => props.navigation.navigate('screen2')}
    />
  </View>
);

const Screen2 = (props) => (
  <View style={styles.container}>
    <Text>Screen 2</Text>
    <View style={styles.screen2}>
      <Transition shared='circle'>
        <View style={styles.circle2}/>
      </Transition>
    </View>
    <Button
      title='Back'
      onPress={() => props.navigation.goBack()}
    />
  </View>
);

const Navigator = createFluidNavigator({
  screen1: { screen: Screen1 },
  screen2: { screen: Screen2 },
});

Transitions

The library also supports transitions for elements wrapped in the Transition component. You can provide appear/disappear transitions that will be animated during navigation.

The Transition element supports appear and disappear transitions (appear will be used if disappear is not set), and these can either be one of the predefined transitions - or functions where you provide your own transitions.

<Transition appear='scale' disappear='bottom'>
  <View style={styles.circle}/>
</Transition>

Transition Types

Name Description
scale Scales the element in and out
top Translates the element in/out from the top of the screen
bottom Translates the element in/out from the bottom of the screen
left Translates the element in/out from the left of the screen
right Translates the element in/out from the right of the screen
horizontal Translates the element in/out from the left/right of the screen
vertical Translates the element in/out from the top/bottom of the screen
flip Flips the element in/out

Custom transitions

It is easy to provide custom transitions - just add the transition function to your component's appear or disappear property. The following example creates a transition that will scale in from 88 times the original size of the wrapped component:

<Transition appear={myCustomTransitionFunction}>
  <View style={styles.circle}/>
</Transition>

myCustomTransitionFunction = (transitionInfo) => {
  const { progress, start, end } = transitionInfo;
  const scaleInterpolation = progress.interpolate({
    inputRange: [0, start, end, 1],
    outputRange: [88, 80, 1, 1],
  });
  return { transform: [{ scale: scaleInterpolation }] };
}

Read more about the parameters and functionality for building custom transitions.

Native driver support

For achieving the best experience it's vital to get rid of JS evaluation during animation run. React-native Animated API allows for scaling in both axis using native drivers, but it's not possible to resize width and height (which calls for a layout computation). Thus the native driver is used only when the ratio of source and target component are the same and it's recommended for the best quality of animations.

API

FluidNavigator

Transition

Credit

Some of the concepts in the library builds on ideas from @lintonye's pull request and suggestion found here: Shared element transition #941.

Contributors

Christian Falch (@chrfalch), Yuuki Arisawa (@uk-ar), Joe Goodall (@joegoodall1), sonaye, David Chavez, muhaimincs, KingTayTay, pedrobullo, Nathan James, Filip Engberg, DadImScared, fabriziogiordano, kelset, rewieer, Dan Alloway, Alexander Zizzo, Monica He, Avi Patel, Julian Hundeloh, Luong Dang Hai, Peter Henderson

Sponsors

Fram X - a cross platform app company from Norway.

fluidtransitions's People

Contributors

avipatel91 avatar chrfalch avatar dadimscared avatar danalloway avatar dcvz avatar ehacinom avatar elzii avatar fabriziogiordano avatar filipengberg avatar jarvisluong avatar jaulz avatar joegoodall1 avatar kelset avatar kingtaytay avatar muhaimincs avatar nsjames avatar osdnk avatar sonaye avatar uk-ar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluidtransitions's Issues

FlatList example

Firstly thank you for putting together such a neat library.

I imagine it's because this example is outdated, but see the video below for what happens when you run the code in Examples/src/FlatList.js. The image appears to revert back to its original size.

Any help would be gratefully received!

Video showing bug

White transition screen.

I dont know if this is bug or just not implemented (future request)?
But if you use fluid navigator and inside it you want to pass other stacknavigator ->
navigation transition beetween these screens is white.

Simply put:
Navigate from fluidNavigator to Stacknavigator -> whole transition is white -> after transition ends -> resolve new screen and white disappear. :)

Feature: Opacity/Fade-in/out transitions

Hi, thanks for the awesome library!

I'm testing it out, and I'm having difficult animating components that require nested Transition elements.

Is this behaviour possible?

What Im trying to achive:
Moving a container down and an element inside of it, up :P

If I dont nest the elements, I would have to track sizes and positions of absolutely positioned elements, and I'm trying no to go down that road.

Here's a snack with some sample code:
https://snack.expo.io/@arielwb/nested-fluid-transitions-

Screen 1 to 2
transitions are ok, no nested Transitions

Screen 3 to 4
Only in the the first run of the animation behaves correctly.

I tried different combinations of style props (transform, top, position), and it seems that this is not the problem.

Any suggestion it would be much appreciated!
Thanks ;)

Shared element morphing

Hi, would it be possible to morph images between a shared transition. I have a use case where images are different on 2 screens but the implementation requires shared transition between them. As of now, when transitioning from first screen to second, the image on second screen abruptly appears at the end of transition.

Screens under FluidNavigator don't respect navigationOptions hence i can't customise header?

Header couldn't be customise under FluidNavigator as it doesn't respects navigationOptions, can't find any relevant example also.

navigationOptions:({navigation,screenProps}) =>{ return{ headerStyle:StackNavigationHeader.headerStyle({navigation}), headerLeft:StackNavigationHeader.headerLeftDrawer({navigation,screenProps}), headerRight:StackNavigationHeader.courseHeaderRight({navigation,screenProps}), headerTitle:StackNavigationHeader.headerTitle({navigation}) } },

componentWillUnmount - Warning: Can't call setState ...

Once we leave the Fluid navigator to different router we get a componentWillUnmount warning.
This is not a problem yet, and its only a warning but better to be prepared.
The entire warning log

ExceptionsManager.js:71 Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in TransitionItemsView (at FluidTransitioner.js:204)
in RCTView (at View.js:60)
in View (at Transitioner.js:169)
in Transitioner (at FluidTransitioner.js:69)
in FluidTransitioner (at createFluidNavigator.js:35)
in FluidNavigationView (at createNavigator.js:57)
in Navigator (at createNavigationContainer.js:368)
in NavigationContainer (at SceneView.js:9)
in SceneView (at StackViewLayout.js:516)
in RCTView (at View.js:60)
in View (at createAnimatedComponent.js:154)
in AnimatedComponent (at StackViewCard.js:12)
in Card (at createPointerEventsContainer.js:28)
in Container (at StackViewLayout.js:554)

Make examples Expo compatible?

Hi,

I wanted to try the examples of this lib, but unfortunately they are not published on Expo. I found some snacks but they did not work very well (mostly found in issues) so I want to see the official examples to see what can be achieved by this lib. Unfortunately this requires me to clone the repo, read the example readme etc...

Finally I was not able to run it on my phone. I think it requires react-native link in the readme for vector icons (which are actually available in Expo), and even after it didn't work with a strange error related to vector icon overriding something...

So in the end I don't know how to test this library at a glance to see if it's worth using in my apps.

I think publishing an example on Expo would help increase adoption. I am ok to submit a PR if this is approved.

Transition speed decreases with multiple "shared" elements

So I'm using shared element transition to achieve something like the App Store in iOS: https://vimeo.com/272028619

So as the animation (and title) suggests, I have 3-4 shared elements from the ThumbnailScreen to the DetailsScreen and the transition takes about 2.5 seconds. When I only have one element, the transition takes about 0.9-1.1 seconds, with 2 elements around 1.6-1.9 seconds and so on.

I assume this is due to the time it takes to calculate the position and other props of the Destination screen's shared elements...

Is this something expected or something that shouldn't happen?
Is there any way to improve the performance if I HAVE TO use 4 shared elements?

Snack Expo Demo

Thanks!

How to pass animated property to other elements

As far as I see, animated property is used with shared

What I want to do is pass the animated property to other components so I can customize their transition.
Is there a way to do is like:

<Transition animated="progress" anchor="blaBla">
    <MyComponent />
</Transition>

Missing support for passing props with ScreenProps

Hello there,

First I wanted to thank you for the work you're doing on FluidTransitions which is really amazing.

I'm having an issue which I think is related to FluidNavigator being not as "complete" as createStackNavigator, nor as the (deprecated) StackNavigator which currently supports screenProps.

The issue

You should be able to pass the prop ScreenProps to FluidNavigator so that every children have access to it, like this (adapted from the docs of createStackNavigator) :

const SomeStack = FluidNavigator({
  // config
});

<SomeStack
    screenProps={{name: 'John'}}
    // this prop will get passed to the screen components as this.props.screenProps
  />

// In your children component :
return <Text> Hello {this.props.screenProps.name} ! </Text>

Current behavior

Currently this code generate an error because screenProps is undefined in the children component.
It should instead refer to the object we passed into FluidNavigator as "screenProps".

This was my first issue on GitHub so apologizes if I'm doing something wrong 😺

Thanks again,
Benjamin

Can I use this project inside FlatList's item?

I write ItemList component and when select item, navigator will push to Detail component and show selected image in full size
this is my code

ItemList

class ItemList extends Component {
  renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        style={styles.cell}
        onPress={() => { this.props.navigation.navigate('DETAIL', { item, index }) }}
      >
          <Transition shared={`image_${index}`}>
            <Image
              style={styles.image}
              source={{ uri: item.uri }}
            />
          </Transition>
      </TouchableOpacity>
    )
  }

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={itemData}
          renderItem={this.renderItem}
          keyExtractor={(_, index) => `${index}`}
          numColumns={3}
        />
      </View>
    )
  }
}

Detail

const Detail = (props) => (
  <View style={styles.container} >
    <Transition shared={`image_${props.navigation.state.params.index}`}>
      <Image
        style={styles.image}
        source={{ uri: props.navigation.state.params.item.uri }}
      />
    </Transition>
  </View>
)

screen shot 2561-04-16 at 10 48 51

but when I run my project, the animations works great but my image not appear after I provide it with Transition

out

How to know when transitions are finished?

I have a screen with a TextInput that I want to call .focus() on, but only after the transition animations have finished. Is there a way to do that? I tried using didFocus, but that doesn't get called (possibly related to #9). willFocus gets called, but it happens too early. react-navigation's .isFocused() returns true too early.

Use transitions in a swiper of images

I'm using the FluidTransitions in a swiper of images, so I only see one image at a time. This first image is working very well making the transition of the image to another screen, the problem is when I pass to the next image in the deck, then the transition animation is not working, I don't know why because I'm rendering the card one by one:

renderCard = (card, index) => { return ( <TouchableHighlight onPress={() => navigate(DETAIL)}> <Transition shared="image"> <Image source={card.image} /> </Transition> </TouchableHighlight> ) };

Do you know why is only working with the first card in the deck? The next card is rendered below the previous. I made my own swiper and with other libraries and the result is the same. Probably is not fault of your library but I wasted all my ideas.
Thanks.

transitionConfig not working in FluidNavigator 2.0

Hi, I tried to implement transitionConfig as mentioned in the readme. But I am not able to get it to work for me. Can you please check it.

My config looks like this:

{
  mode: 'card',
  navigationOptions: {
    gesturesEnabled: true,
    gestureResponseDistance: {
      horizontal: 100,
      vertical: 100,
    },
  },
  transitionConfig: {
    duration: 1500,
    timing: Animated.timing,
    easing: Easing.linear(),
    useNativeDriver: true,
  },
}

Thanks

Scaling Issue

Hello, I'm opening this issue because I couldn't find any related issue to this one.

So here's the thing: I have a Horizontal ScrollView with elements within it and I'm transitioning the Image within it and also a Text, when I apply the transitions, happens a slightly weird scale effect and I'm not sure how to approach to fix it or what's going on with it.

Here's a screen record of the visual "bug" that's happening to me.

https://drive.google.com/open?id=1LKhjGJR_7L4oG0DXYwsqK9OiB1y5Zd_B

As you can see by the screen record, it seems to be somehow related to some scale issues but... I'm not sure how this could be fixed.

Transition From

<TouchableHighlight
  style={{ flex: 1 }}
  onPress={() => navigation.navigate("PlanetDetails", { planet: planet })}
  underlayColor="rgba(255, 255, 255, 0.2)"
>
  <Transition shared={planet.key}>
   <Image
      style={[styles.planetPicture, { width: cardWidth }]}
      source={{ uri: `http://192.168.0.102:3000/images/${planet.picture}.jpg` }}
    >
  </Transition>
</TouchableHighlight>

Transition To

const PlanetDetails = ({ navigation }) => {
  const planet = navigation.getParam("planet", "");
  const uri = `http://192.168.0.102:3000/images/${planet.picture}.jpg`;
  return (
    <View style={styles.container}>
      <View style={styles.content}>
        <Transition shared={planet.key}>
          <Image style={styles.planetPicture} source={{ uri }} />
        </Transition>
      </View>
      <Transition shared={`${planet.key}-name`}>
        <View style={styles.titleHolder}>
          <Text style={styles.title}>{uppercase(planet.name)}</Text>
        </View>
      </Transition>
    </View>
  );
};

Thanks :)

Findings on the performance

I went through the code and it's some really good implementation by @chrfalch :)

I extended the example mentioned here and simulated it to make a busy app to test out how smooth SET would be.

Here are the screen recording of 2 instance.

  1. using useNativeDriver (https://media.giphy.com/media/AS4NAijk6WVGaslJOW/giphy.gif) This doesn't not support layout properties.

  2. Using the clever trick where the native driver drivers a non-native animation through an Animated.event (https://media.giphy.com/media/4KFGU2gkedfsxsQ62d/giphy.gif) This supports layout properties.

So how did I make it a busy app? Just added the below code on next button click handler.

setInterval(() => {
  for (let i = 0; i < 5e8; i++) {}
}, 1000);

Correct me if I am wrong, so what I think is happening here is that even though native driver is driving the non-native animation it has to still go through the bridge on every frame to update Animated.event.

Let me know what you think about it.

Feature: Support TabRouter in Fluid Navigation

Currently, I have a tutorial screen with a shared element between them which moves into the correct position depending on the screen with this awesome library! Currently, I have the user tap to navigate horizontally to the next screen (text comes in horizontally, shared element slides to the left). With gestures enabled, I am able to easily swipe back and the text and shared element begins to go back with the movement of my finger. I would like to also be able to do this from the other side of the navigator. Essentially, it'd be awesome to handle swiping forward into the next screen, rather than just back to the previous screen in this use case. Do you know I could approach this if it's not possible with the library right now? I don't want to look too much into other components, because I don't want to loose my shared element transition!

several react-native

actually this is not Issue , but maybe be an issue
because i am new in react native

myQ : i want run Example code from repo

this is my way for implement
1- clone repo
2- cd Example
3- npm i

after run "react-native run-android" command , i give the error about undefined and cant resolve 'react' in this path ( src/utils/createAnimatedWrapper.js ) , after this error

im back to root folder
cd ..
and then
npm i
for install dependency in package.json in root folder not in example folder

after that i give error again and this is the error

image

please help me

Note : i run " react-native run-android " this command in Example folder not in root

Position custom path (bezier/pop/bounce effect) in Shared Element Transition

I'm trying to create a Shared Element Transition somewhat like in iOS for my components using this library.

I'm unable to give the bounce/pop effect as you can see the iOS library.

I came across transitionConfig that I might be able to achieve the bounce effect this with. Here's my transitionConfig:

transitionConfig: {
  duration: 500,
  timing: Animated.timing,
  easing: Easing.easing,
  useNativeDriver: true
},

Now I've come up with a bezier curve path that I want the animation to position in from source to destination: (1, 0.5, 0.5, -0.2) (in order x1, y1, x2, y2)

I'm not sure how to add this custom curve path to the current animation. Can anyone help me with this?

noob question - failed to load bundle

yarn install v1.6.0

brew install yarn
clone repo
cd Examples
yarn
react-native run-ios

screen shot 2018-05-02 at 14 54 52

screen shot 2018-05-02 at 14 56 02

I end up with
node_modules in the root folder
and node_modules in the Example folder.
NB - I only cd straight into Examples folder
I tried yarn cache clean to no avail.

willBlur, didBlur listener not call

Thanks for your great work,

Please help me with this issue, note that: it works when I changed to use StackNavigator.

Also the function "this.props.navigation.isFocused" in the list page return not correct, step:

  1. Open list page : isFocused = true -> correct
  2. Select an item to go to detail page: isFocused of list page = false -> correct
  3. Go back to list page: isFocused now always false -> wrong

Many Thanks,

Undefined is not a function ... for iOS on fresh RN install.

First, great work on this project, very excited to use it.

I am running into an issue getting started on a brand new install.

Error

undefined is not a function (near '...(0,_reactNavigationFluidTransitions.createFluidNavigator)...')

Config

  • React 16.3.1
  • React Native 0.55.4
  • React Navigation 2.3.1
  • React Navigation Fluid Transitions 0.2.0

Steps to Reproduce

  1. create-react-native-app MyApp
  2. yarn add react-navigation
  3. yarn add react-navigation-fluid-transitions
  4. Replace App.js with code below
  5. yarn run ios

App.js

import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { Transition, createFluidNavigator } from 'react-navigation-fluid-transitions';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  screen1: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'flex-start',
    justifyContent: 'center',
    alignSelf: 'stretch',
    padding: 20,
  },
  screen2: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'flex-end',
    alignSelf: 'stretch',
    justifyContent: 'center',
    padding: 20,
  },
  screen3: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    alignSelf: 'stretch',
    justifyContent: 'center',
    padding: 20,
  },
  buttons: {
    flexDirection: 'row',
    padding: 20,
  },
});

const Circle = (props) => (
  <View
    style={{
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: props.background,
      width: props.size,
      height: props.size,
      borderRadius: props.size / 2,
    }}
  />
);

const Shape = (props) => (
  <View
    style={{
      backgroundColor: props.background || '#EE0000',
      width: props.size,
      height: props.size,
      borderRadius: props.borderRadius || 0,
    }}
  />
);

const Screen1 = (props) => (
  <View style={styles.container}>
    <Transition appear="flip">
      <Text>1.Screen</Text>
    </Transition>
    <View style={styles.screen1}>
      <Transition shared="circle">
        <Shape size={50} borderRadius={4} background="#EE0000" />
      </Transition>
    </View>
    <View style={{ flexDirection: 'row' }}>
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
    </View>
    <Transition appear="horizontal">
      <View style={styles.buttons}>
        <Button title="Next" onPress={() => props.navigation.navigate('screen2')} />
      </View>
    </Transition>
  </View>
);

const Screen2 = (props) => (
  <View style={styles.container}>
    <Transition appear="flip">
      <Text>2.Screen</Text>
    </Transition>
    <View style={styles.screen2}>
      <Transition shared="circle">
        <Shape size={50} borderRadius={25} background="#EE0000" />
      </Transition>
    </View>
    <View style={{ flexDirection: 'row' }}>
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
    </View>
    <Transition appear="horizontal">
      <View style={styles.buttons}>
        <Button title="Back" onPress={() => props.navigation.goBack()} />
        <View style={{ width: 20 }} />
        <Button title="Next" onPress={() => props.navigation.navigate('screen3')} />
      </View>
    </Transition>
  </View>
);

const Screen3 = (props) => (
  <View style={styles.container}>
    <Transition appear="flip">
      <Text>3.Screen</Text>
    </Transition>
    <View style={styles.screen3}>
      <Transition shared="circle">
        <Shape size={140} borderRadius={4} background="#EE0000" />
      </Transition>
    </View>
    <View style={{ flexDirection: 'row' }}>
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
      <View style={{ width: 20 }} />
      <Transition appear="horizontal" delay>
        <Circle background="#55AA55" size={20} />
      </Transition>
    </View>
    <Transition appear="horizontal">
      <View style={styles.buttons}>
        <Button title="Back" onPress={() => props.navigation.goBack()} />
      </View>
    </Transition>
  </View>
);

const Navigator = createFluidNavigator({
  screen1: { screen: Screen1 },
  screen2: { screen: Screen2 },
  screen3: { screen: Screen3 },
}, {
  navigationOptions: { gesturesEnabled: true },
});

class SharedElements extends React.Component {
  static router = Navigator.router;
  render() {
    return (
      <Navigator navigation={this.props.navigation} />
    );
  }
}

export default class App extends React.Component {
  render() {
    return (
     <SharedElements/> 
    );
  }
}

Thanks again for your work on this.

Cancellability / External Animation Driver Questions

Hi, thanks for sharing this work. I found my way here via react-navigation/rfcs#17.

I haven't taken a super close look at the code here, but I am curious whether you designed this implementation with the following use cases in mind:

  1. Cancelling a transition (e.g. if your app may programmatically trigger navigation events.. possible to different places within a short period of time)
  2. Driving a transition via user touch events (e.g. a PanResponder) or by some other Animated.Value or Animated.SrollView

I hope these questions are sensible!

Screen is transparent on app load when using redux and redux-persist

My app uses a FluidNavigator as one route within a react-navigation TabNavigator. I'm storing nav state in redux and persisting with redux-persist. The initial route the FluidNavigator renders is a list, and when an item is tapped it becomes the header in the following screen. I'll call the two screens ListScreen and ItemScreen.

All works well initially when navigating from ListScreen to ItemScreen, however, if I then refresh the app and it rehydrates from saved nav state, I see the underlying ListScreen even though I was previously on ItemScreen. Then the header item fromItemScreen transitions in, and then it disappears.

Even though I appear to be back on ListScreen, I still have two screens on the stack and according to my nav state I'm still on ItemScreen. I can click buttons that are on ItemScreen even though I can't see them, so I believe the screen is there but at 0 opacity.

RN 0.56 - element.type is not a function

[x] bug

"dependencies": {
    "react": "16.4.1",
    "react-native": "0.56.0",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^2.6.2",
    "react-navigation-fluid-transitions": "^0.2.2"
  },

node: v8.11.3
npm: 5.6.0
yarn: 1.7.0

ISSUE:
Simple Transition fails with error: element.type is not function. Without the Transition, navigation works fine. Adding the Transition throws the error.

class Screen1 extends Component {
  render() {
    return (
      <TouchableOpacity
        activeOpacity={1}
        style={s1Styles.container}
        onPress={() => this.props.navigation.navigate('screen2')}
        >
        <Transition appear="horizontal">
          <View style={s1Styles.paper}/>
        </Transition>
        <View style={s1Styles.headerContainer}>
          <Text style={s1Styles.header}>WARBUNNY</Text>
          <Text style={s1Styles.subheader}>Snuggles</Text>
        </View>
        <Image style={s1Styles.shoe} source={require('../../../assets/warbunny.png')} />
      </TouchableOpacity>
    );
  }
}

Error is thrown at: ShallowRenderer.render (66:34).

image

output from console.log(element):
image

Swiping down from second screen reveals the first

const Navigator = FluidNavigator({
  screen1: {screen: Screen1},
  screen2: {screen: Screen2},
})

Just running this...navigating to screen2, if I slowly swipe down, screen2's interpolates the opacity on the drag. If I swipe all the way down, it navigates to screen1, if I continue going back up, it stays on screen2.

It only happens when swiping from top to bottom, not bottom up or left-right/right-left.

Was there a prop to disable swiping?

Feature: Add zIndex as a prop for ordering multiple shared element transitions

Hello!

Just wanted to say this library is amazing! Been able to put together some absolutely dope transitions because of it so thanks for all the hard work!

I had a problem where I was using 2 shared element transitions on the one page and wanted to customise their flow order. I am not sure exactly how they are getting laid out by your framework, but I wanted one to specifically appear above the other. Managed to get it to work with a tiny change to your code by adding zIndex as a property to the TransitionView class.

Just had to change the constructor to accept a prop or use the current zIndex method.

// Line 59 - TransitionView.js
this.props.zIndex || zIndex++, this.props.anchor, this.props.animated

Link to the code line here ->

Just thought this might be useful to others if they are having problems ordering their shared elements.

Doesn't play nice with styled components

I found that this library renders glitchy animations when using styled-components, glamorous-native or a custom styled components API, switching to the typical way of writing styles in RN fixes things. I wrote a light custom styled-components-like function to do some debugging.

kapture 2018-05-11 at 14 21 48

Top: Not using styled components.
Bottom: Using styled components.

Code to reproduce available here.

Not working in real device Android

I integrated the Fluidnavigator between two screens and it is working fine in Genymotion (emulator). But when i test it in a real Android device it is not working at all. It is simply cross fades.

Error on android caused by using the exponentiation operator

Hi @chrfalch,

I've been getting this RSOD when building to android.

screenshot_20180424-153146

It appears to be because FluidTransitions is using the exponentiation operator in rotation.js.

Support for the exponentiation operator in Babel was supposed to go out with RN 0.51 (see here) but we're using RN 0.54.1 and were still getting the above error.

I've made a pull request which fixes this issue #17, unless you'd prefer to fix this error another way.

Expect nav state....

When i use FluidNavigator to replace StackNavigator, i created a nested navigation(Tab in Stack, Stack in Drawer) and got a issue:

  • Expect nav state to have routes and index, {"routeName":"Main","key":"Init"}

If i change Tab to a screen, it work fine. :) with FluidNavigator.

Any help? Thanks

Transitioning Text Changes

I have a <Text /> and a <Button /> that are present across two screens. The animation between the two positions works well. However these two components also have text that changes.. and the change in text doesn't happen until the animation is complete, which makes it look a bit odd (jumpy). Is there any way to allow the texts to fade in and out as the position translation happens?

Error on nested elements

Hi
When trying to add your plugin to my navigation system i get the following error:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
in Unknown (at createNavigationContainer.js:226)
in NavigationContainer (at SceneView.js:17)
in SceneView (at ResourceSavingSceneView.js:55)
in RCTView (at View.js:60)
in View (at ResourceSavingSceneView.js:48)
in RCTView (at View.js:60)
in View (at ResourceSavingSceneView.js:39)
in ResourceSavingSceneView (at TabView.js:35)
in RCTView (at View.js:60)
in View (at TabViewPagerPan.js:251)

My structure is different then the regular example so maybe it has something to do with it.
StackNavigator (parent)=>TabNavigator (First child) => StackNavigator(second child)

The screens that i want to "fluid" are inside the second child stack.
When I change just the second StackNavigator to FluidNavigator i get the error above.

If im changing both StackNavigator to FluidNavigator i get a different error:

ExceptionsManager.js:71 Unhandled JS Exception: TypeError: Cannot read property 'getStateForAction' of undefined

This error is located at:
in NavigationContainer (at edocate.js:68)
in Provider (at edocate.js:64)
in RCTSafeAreaView (at SafeAreaView.ios.js:34)
in SafeAreaView (at edocate.js:56)
in Edocate (at renderApplication.js:33)
in RCTView (at View.js:60)
in View (at AppContainer.js:102)
in RCTView (at View.js:60)
in View (at AppContainer.js:122)
in AppContainer (at renderApplication.js:32)

Thanks

TypeError: expected dynamic type 'double', but had type 'null'

I am getting the following error when I use Shared Element Transition:

TypeError: expected dynamic type 'double', but had type 'null'

Here's an example of what my two screens look like:

class FirstScreen extends Component {
  render() {
    return (
      <View>
        <FlatList 
          style={styles.fragmentContainer}
          data={this.state.homePolls}
          keyExtractor={(item, index) => index.toString()}
          renderItem={({item}) => (
          <FirstScreenComponent
            data={item}  />
        )}/>
      </View>
    )
  }
}

class FirstScreenComponent extends Component {
  render() {
    let imageHeight = (9*(Values.ScreenWidth))/16;
    return (
      <Transition shared="cover-photo">
          <View style={{ marginTop: -10, marginRight: -10, marginLeft: -10, height: imageHeight, backgroundColor: '#37474F' }}>
              <Image resizeMode={'cover'} source={{ uri : attachment_url }} style={{ flex: 1, height: imageHeight }} />
              <TouchableOpacity onPress={ () => this._goBack() } style={{ padding: 10, position: 'absolute', top: 0, left: 0 }}>
                  <View style={{ justifyContent: 'center', alignItems: 'center', width: 30, height: 30, borderRadius: 20, backgroundColor: '#00000044' }}>
                      <Icon color={'#ffffff'} name={'md-close'} size={25}/>
                  </View>
              </TouchableOpacity>
          </View>
      </Transition>
    )
  }
}

class SecondScreen extends Component {
  render() {
    let imageHeight = (9*(Values.ScreenWidth))/16;
    return (
      <Transition shared="cover-photo">
          <View style={{ marginTop: -10, marginRight: -10, marginLeft: -10, height: imageHeight, backgroundColor: '#37474F' }}>
              <Image resizeMode={'cover'} source={{ uri : attachment_url }} style={{ flex: 1, height: imageHeight }} />
              <TouchableOpacity onPress={ () => this._goBack() } style={{ padding: 10, position: 'absolute', top: 0, left: 0 }}>
                  <View style={{ justifyContent: 'center', alignItems: 'center', width: 30, height: 30, borderRadius: 20, backgroundColor: '#00000044' }}>
                      <Icon color={'#ffffff'} name={'md-close'} size={25}/>
                  </View>
              </TouchableOpacity>
          </View>
      </Transition>
    )
  }
}

How my Fluid Navigator is defined:

const RootStack = createFluidNavigator(
    {
        First: FirstScreen,
        Second: SecondScreen,
    },
    {
        initialRouteName: 'Splash',
        headerMode: 'none',
        navigationOptions: {
            header: null
        },
    }
);

Can anyone explain why this error might be occuring? It was working fine at first, but suddenly it started giving me this error out of the blue? Removing Shared Transition element code fixed it for me, so I think that it's the source of the error. How do I fix this?

Note: this error only occurs when using the "shared" attribute of Transition view

Splash screen appears for a moment when transitioning on android

Hello everyone, I've made a little demo app that is composed os two screens, the first with just a text a a button, and the second with a header and a camera view.
I'm using the FluidNavigator to fade through the screens, but when the transition happens, I can see for a moment the app's splashscreen on the background. This happens only on android, on ios it works fine.

My package.json is as follows:

"dependencies": {
    "react": "16.3.1",
    "react-native": "0.55.4",
    "react-native-camera": "^1.1.4",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^2.0.1",
    "react-navigation-fluid-transitions": "^0.2.0"
  },

I'm using Animated to create interpolations of color and scale at the button. I've also tried to set a background color on the second screen, but had no effect.
Here are two videos of the app:

Android: https://www.youtube.com/watch?v=FGAHmNoABfo&feature=youtu.be

iOS: https://www.youtube.com/watch?v=aR2QCpS0OJ0&feature=youtu.be

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.