Skip to content

trabian/react-native-magic-move

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

react-native-magic-move

Create magical move transitions between scenes in react-native 🐰🎩✨

MagicMoveGif

Usage

Installation

$ yarn add react-native-magic-move

Link the native extensions (* recommended but not required)

$ react-native link react-native-magic-move 

* The native extensions are recommended to get the best performance, but they are not required. This makes it possible to use react-native-magic-move with expo or react-native-web. If you're having trouble installing the native extensions, please see this guide on how to install them manually.

Wrap your app with the <MagicMove.Provider> context.

import * as MagicMove from 'react-native-magic-move';

const App = () => (
  <MagicMove.Provider>
    {...}
  </MagicMove.Provider>
);

Add the <MagicMove.{View|Image|Text}> component to your views. Whenever the Magic Move component is mounted while another Magic Move component with the same id is already mounted, then a magic transition between the components is performed.

import * as MagicMove from 'react-native-magic-move';

const Scene1 = () => (
  <MagicMove.Scene>
    <MagicMove.View id="logo" style={{
        width: 100,
        height: 100,
        backgroundColor: "green",
        borderRadius: 50
      }} />
  </MagicMove.Scene>
);

const Scene2 = () => (
  <MagicMove.Scene>
    <MagicMove.View id="logo" style={{
        width: 200,
        height: 200,
        backgroundColor: "purple",
        borderRadius: 0
      }} />
  </MagicMove.Scene>
);

react-navigation

When you are using react-navigation (or react-native-router-flux), then also install the following binding:

Documentation

Components

The following magic-move components are supported out of the box.

  • MagicMove.View
  • MagicMove.Text
  • MagicMove.Image

You can also create your own custom MagicMove components.

const MyMagicMoveComponent = MagicMove.createMagicMoveComponent(MyComponent);

// When creating a custom image component (e.g. FastImage) also specify the `image` attribute
// so that the `move` transition treats this as an image.
const MagicMoveFastImage = MagicMove.createMagicMoveComponent(FastImage, {ComponentType: 'image'});

// Full signature
/* MagicMove.createMagicMoveComponent(Component, {
  AnimatedComponent,
  ComponentType,
  ...props
});*/

Props

Property Type Default Description
id string (required) Unique id of the magic-move instance
transition function MagicMove.Transition.move Transition effect, see below
duration number 400 Length of the animation (milliseconds)
delay number 0 Amount of msec to wait before starting the animation
easing function Easing.inOut(Easing.ease) Easing function to define the curve
disabled bool false Disables transitions to this component
zIndex number 0 Z-index to control the drawing order of the rendered animation. A component with a greater z-index is always drawn in front of a component with a lower z-index.
useNativeDriver boolean true Use the native-driver
debug boolean false Enables debug-mode to analyze animations

Transitions

The following transition functions are available out of the box.

Transition Description
MagicMove.Transition.move (default) Moves the component while adjusting for border-radii and size. Takes the image resizeMode into account to create a seamless image transition without any stretching.
MagicMove.Transition.morph Morphs the shape, size and colours of the target to look like the source
MagicMove.Transition.dissolve Cross fade the source into the target
MagicMove.Transition.flip Flip the source to reveal the target on the backside (auto choose axis)
MagicMove.Transition.flip.x Flip the source to reveal the target on the backside (over x-axis)
MagicMove.Transition.flip.y Flip the source to reveal the target on the backside (over y-axis)
MagicMove.Transition.flip.xy Flip the source to reveal the target on the backside (over x- and y-axes)
MagicMove.Transition.shrinkAndGrow Shrink and let the source disappear while letting the target appear and grow
MagicMove.Transition.squashAndStretch Scale the target to the size of the source and squash and stretch to give it the illusion of momentum and mass

You can also create your own transition functions, see src/transitions for examples.

Scenes

Use <MagicMove.Scene> to mark the start of a scene within the rendering hierarchy. This is important so that Magic Move can correctly assess the destination-position of an animation. MagicMove.Scene is implemented using a regular View and supports all its properties.

Property Type Default Description
disabled bool false Disable transitions to this scene.
active bool This special prop is intended for integrating magic-move with 3rd party navigators such as react-navigation. Do not use it unless you know what you are doing. By setting it to true or false the navigation package can control which scene is active and which is no longer active. See react-navigation-magic-move for an example on how to use it.
debug boolean false Enables debug-mode to analyze animations

Context

When a magic-move is performend, a temporary clone of the source and/or target component is rendered onto the screen. Now imagine you have some animations that run when your component is mounted (e.g. Animatable.View), that would also mean these animations are run on the cloned component. This is probably not what you want and you might want to hide those components entirely in the cloned component. To do so you can use the <MagicMove.Context> API. It allows you to detect whether the component is rendered as a clone and whether it is the source or target of a magic move animation.

Example

<MagicMove.View>
  <MagicMove.Context>
    {({isClone, isTarget}) => (
      <Animatable.View animation={isClone ? undefined : 'zoomIn'} />
    )}
  </MagicMove.Context>
</MagicMove.View>

Examples

Example with scene transitions using react-native-router-flux.

import React from "react";
import { View, TouchableOpacity } from "react-native";
import { Router, Stack, Scene, Actions } from "react-native-router-flux";
import * as MagicMove from "react-native-magic-move";

const Scene1 = () => (
  <MagicMove.Scene>
    <TouchableOpacity onPress={() => Actions.scene2()}>
      <MagicMove.View id="myView" style={{
        alignSelf: "center",
        width: 100,
        height: 100,
        backgroundColor: "green",
        borderRadius: 20
      }} />
    </TouchableOpacity>
  </MagicMove.Scene>
);

const Scene2 = () => (
  <MagicMove.Scene>
    <MagicMove.View id="myView" style={{
      height: 300,
      backgroundColor: "purple"
    }} />
  </MagicMove.Scene>
);

const App = () => (
  <MagicMove.Provider>
    <Router>
      <Stack key="root">
        <Scene key="scene1" component={Scene1} />
        <Scene key="scene2" component={Scene2} />
      </Stack>
    </Router>
  </MagicMove.Provider>
);

See examples/src for more code examples.

Disclaimer 🐰🎩

Magic-move creates the illusion of transitioning/morphing components from one scene to another. It however doesn't actually move components to different scenes. As with real magic tricks, there will be situations where the illusion will not work for you. And as with magic tricks, you may need to "set the stage" (e.g. change some stuff in your app) to create the transition that you want. So now that you've received this reality check βœ…, go forth and create some bad-ass illusions. Drop me a note of the cool stuff you've built with it. Grand wizard, IjzerenHein

License

MIT

Cool?

Do you think this cool and useful? Consider buying me a coffee!
Buy Me A Coffee

About

Create magical move transitions between scenes in react-native 🐰🎩✨

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 68.6%
  • Java 16.2%
  • Objective-C 14.7%
  • Ruby 0.5%