• Stars
    star
    2,190
  • Rank 21,064 (Top 0.5 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Native shared element transition "primitives" for react-native 💫

react-native-shared-element

Native shared element transition "primitives" for react-native 💫

This library in itself is not a Navigation- or Router library. Instead, it provides a set of comprehensive full native building blocks for performing shared element transitions in Router- or Transition libraries. If you are looking for the React Navigation binding, you can find it here.

MagicMoveGif-iOS MagicMoveGif-Android

Motivation

Shared-element transitions add shine to your app but can be hard to do in practise. It's possible to achieve some nice transitions by building custom modals and using the core react-native API, But this also brings with it many restrictions. Things like resizing an image or making sure no "flicker" occurs even an older Android devices can be a real challenge.

This library solves that problem through an all native implementation which is very close to the metal of the OS. It solves the problem by providing a set of "primitives", which don't require any back and forth passes over the react-native bridge. This way, the best possible performance is achieved and better image transitions can be accomplished. The following list is an impression of the kinds of problems that are solved through the native implementation.

  • No flickering
  • CPU & GPU friendly
  • Image resizeMode transitions
  • Scrollview clipping
  • Border (radius, color, width) transitions
  • Background color transitions
  • Shadow transitions
  • Cross-fade transitions
  • Clipping reveal transitions

Under development

This library is under active development. The iOS and Android implementations are mostly done, which exception of some edge cases. The library also aims to support the web platform with an optimized DOM implementation. That development is about 60% done.

Index

Installation

yarn add react-native-shared-element

And when using React Native 0.59 or lower, link the library. This is not needed when using React Native 0.60 or higher, where linking happens automatically.

react-native link react-native-shared-element

Basic usage

import {
  SharedElement,
  SharedElementTransition,
  nodeFromRef
} from 'react-native-shared-element';

// Scene 1
let startAncestor;
let startNode;
<View ref={ref => startAncestor = nodeFromRef(ref)}>
  ...
  <SharedElement onNode={node => startNode = node}>
    <Image style={styles.image} source={...} />
  </SharedElement>
  ...
</View>


// Scene2
let endAncestor;
let endNode;
<View ref={ref => endAncestor = nodeFromRef(ref)}>
  ...
  <SharedElement onNode={node => endNode = node}>
    <Image style={styles.image} source={...} />
  </SharedElement>
  ...
</View>

// Render overlay in front of screen
const position = new Animated.Value(0);
<View style={StyleSheet.absoluteFill}>
  <SharedElementTransition
    start={{
      node: startNode,
      ancestor: startAncestor
    }}
    end={{
      node: endNode,
      ancestor: endAncestor
    }}
    position={position}
    animation='move'
    resize='auto'
    align='auto'
     />
</View>

How it works

react-native-shared-element is a "primitive" that runs shared element transitions entirely native without requiring any passes over the JavaScript bridge. It works by taking in a start- and end node, which are obtained using the <SharedElement> component.

Whenever a transition between screens occurs (e.g. performed by a router/navigator), a view in front of the app should be rendered to host the shared element transition. The position prop is used to interpolate between the start- and end nodes, 0 meaning "Show the start node" and 1 meaning "Show the end node".

Whenever the <SharedElementTransition> component is rendered, it performs the following tasks:

  • Measure the size and position of the provided element
  • Obtain the styles of the elements
  • Obtain the visual content of the elements (e.g. an image or a view snapshot)
  • Render a visual copy of the start element at its current position
  • Hide the original elements whenever the visual copy are on the screen
  • Monitor the position prop and render the shared element transition accordingly
  • Upon unmount, unhide the original elements

You typically do not use this component directly, but instead use a Router or Transition-engine which provides a higher-level API. See ./example/src/components/Router.tsx for an example implementation of a simple stack router using shared element transitions.

API Documentation

SharedElement

The <SharedElement> component accepts a single child and returns a node to it through the onNode event handler. The child must correspond to a "real" View which exists in the native view hierarchy.

Props

Property Type Description
children element A single child component, which must map to a real view in the native view hierarchy
onNode function Event handler that sets or unsets the node-handle
View props... Other props supported by View

SharedElementTransition

The <SharedElementTransition> component executes a shared element transition natively. It natively performs the following tasks: measure, clone, hide, animate and unhide, to achieve the best results.

Props

Property Type Description
start { node: SharedElementNode, ancestor: SharedElementNode } Start node- and ancestor
end { node: SharedElementNode, ancestor: SharedElementNode } End node- and ancestor
position number | Animated.Value | Reanimated.Value Interpolated position (0..1), between the start- and end nodes
animation SharedElementAnimation Type of animation, e.g move start element or cross-fade between start- and end elements (default = move)
resize SharedElementResize Resize behavior (default = auto)
align SharedElementAlign Alignment behavior (default = auto)
debug boolean Renders debug overlays for diagnosing measuring and animations
onMeasure function Event handler that is called when nodes have been measured and snapshotted

Transitions effects

The transition effect can be controlled using the animation, resize and align props. In most cases you should leave these to their default values for the best possible results.

If however the start- element and end elements are visually different, then it can make sense to choose different values. For instance, if you are transitioning from a <Text> with a white color to a <Text> with a black color, then using animation="fade" will create a cross-fade between them.

Another case is when you have a single-line of <Text> in the start- view and a full description in the end- view. A stretch effect would in this case not look good, because the end- element is much larger in size compared the start- element. In this case you can use resize="clip" and align="left-top" to create a text reveal effect.

SharedElementAnimation

Animation Description
move Moves the start- element to the end position
fade Cross-fades between the start- and end elements
fade-in Fade-in the end element coming from the start position (start-element is not visible)
fade-out Fade-out the start element to the end position (end-element is not visible)

SharedElementResize

Resize Description
auto Automatically selects the default resize behavior. For images this will perform the best possible transition based on the resizeMode of the image. For other kinds of views, this will default to stretch.
stretch Stretches the element to the same shape and size of the other element. If the aspect-ratio of the content differs, you may see stretching. In that case consider the clip or none resize options.
clip Do not resize, but clip the content to the size of the other content. This option is for instance useful in combination with <Text> components, where you want to reveal more text.
none Do not resize the content. When combined with fade, this creates a plain cross-fade effect without any resizing or clipping

SharedElementAlign

auto, left-center, left-top, left-right, right-center, right-top, right-right, center-top center-center, center-bottom

When auto is selected, the default alignment strategy is used, which is center-center.

Example apps

License

Shared element transition library is licensed under The MIT License.

Credits

This project is supported by amazing people from Expo.io

expo

Changes in maintenance

Both react-native-shared-element and react-navigation-shared-element are always looking for new Maintainers. It is no longer possible for me (@author) to maintain these repositories. Please reach out to me personally if you have ideas or suggestions. You can also reach out to Aleks who is currently the main maintainer of this library.

Read the full statement here.

More Repositories

1

react-native-bundle-visualizer

See what packages are increasing your react-native bundle size 📦
TypeScript
1,466
star
2

react-navigation-shared-element

React Navigation bindings for react-native-shared-element 💫
TypeScript
1,266
star
3

autolayout.js

Apple's Auto Layout and Visual Format Language for javascript (using cassowary constraints)
JavaScript
1,034
star
4

react-native-magic-move

Create magical move transitions between scenes in react-native 🐰🎩✨
JavaScript
973
star
5

firestorter

Use Google Firestore in React with zero effort, using MobX 🤘
TypeScript
378
star
6

famous-flex

Animatable layouts, FlexScrollView & widgets for famo.us.
JavaScript
279
star
7

kiwi.js

Fast TypeScript implementation of the Cassowary constraint solving algorithm 🖖
JavaScript
250
star
8

react-navigation-magic-move

Bindings for using react-navigation with react-native-magic-move 🐰🎩✨
JavaScript
135
star
9

react-tag-cloud

Create beautiful tag/word clouds using React ☁️
TypeScript
118
star
10

famous-map

Map integration for famo.us (Google Maps, Leaflet, Open Layers 3 & Mapbox GL)
JavaScript
109
star
11

visualformat-editor

Editor & previewer for Apple's Visual Format Language (built with autolayout.js)
JavaScript
90
star
12

node-web-bluetooth

Web Bluetooth API and interactive device picker for node.js
JavaScript
75
star
13

react-navigation-shared-element-demo

A simple app that demonstrates how to use react-navigation-shared-element in react-native
JavaScript
65
star
14

famous-autolayout

Apple's Auto Layout and Visual Format language for famo.us
JavaScript
55
star
15

famous-flex-chat

Chat-demo for famo.us using true-size chat bubbles, snap to bottom, sticky headers & pull-to-refresh
JavaScript
52
star
16

pnglib-es6

Create png images in pure javascript (modern & fast ES6 version using typed Arrays)
JavaScript
45
star
17

famous-boxlayout

Layout-view for quickly setting margins or creating flexible layouts
JavaScript
28
star
18

famous-animatedIcon

Material design'ish button-animation using famo.us
JavaScript
27
star
19

famous-flex-datepicker

Date/time picker demo for famo.us
JavaScript
26
star
20

rtfToHtml

Parse RTF and write output as an HTML file (written specifically for InDesign generated RTF, but works for any source)
JavaScript
21
star
21

android-tv-browser-autolaunch

Android TV App (react-native) that auto-launches on boot and shows a browser with a hard-coded URL
Objective-C
20
star
22

famous-sizeconstraint

SizeConstraint makes it possible to set the scale, padding, max-size, min-size and aspect-ratio for famo.us renderables
JavaScript
20
star
23

famous-kenburnscontainer

Famo.us view for performing ken-burns style zooming and panning
JavaScript
19
star
24

famous-listview

famous-listview extends famo.us ScrollContainer with insert/remove animations, selection (single/multiple) and support for a placeholder.
JavaScript
18
star
25

famous-lagometer

Lagometer for famo.us showing the FPS, animation-frames times and script times
JavaScript
18
star
26

famous-bkimagesurface

Drop-in replacement for ImageSurface supporting AspectFit & AspectFill
JavaScript
18
star
27

famous-flex-tabbar

TabBar widget demo for famo.us
JavaScript
18
star
28

famous-flex-tabbarcontroller

TabBarController widget demo for famo.us
JavaScript
17
star
29

famous-white-tile-firebase

Popular white tile (piano tiles) game implemention using famo.us and firebase
JavaScript
17
star
30

famous-refresh-loader

Spinning pull to refresh loader for famo.us
JavaScript
15
star
31

famous-autosizetextarea

Auto-sizing TextareaSurface for famo.us
JavaScript
14
star
32

famous-components

Overview of famo.us components
14
star
33

famous-flex-demo

Demo for showcasing famous-flex layout technology
JavaScript
9
star
34

react-native-magic-move-presentation

Presentation App/Slides for the react-native-magic-move presentation given at ReactEurope 2019
JavaScript
9
star
35

react-native-clipped

Clipping effects and animations for react-native 🍠🥒🍕
JavaScript
7
star
36

famous-flex-tablelayout

iOS inspired table-layout for famo.us
JavaScript
7
star
37

expo-firebase-demo

Firebase Demo running on Expo
TypeScript
6
star
38

famous-white-tile

Popular white tile (piano tiles) game implemention using famo.us
JavaScript
5
star
39

famous-autofontsizesurface

Surface that automatically scales the font-size based on the content.
JavaScript
5
star
40

famous-flex-animationcontroller

Animating from one famo.us view to another in awesome ways
JavaScript
5
star
41

ttvflash

TTV Flash Presentatie App
JavaScript
4
star
42

famous-Starterkit

Starterkit for famo.us (app + web) containing examples, instructions & best practises
JavaScript
4
star
43

famous-resizableImage

Resizable image for famo.us
JavaScript
4
star
44

top2000-stemlijst

Importeer jouw Top 2000 stemlijst eenvoudig naar Spotify, Apple Music of Deezer
TypeScript
4
star
45

firestore-cms

A free, flexible and easy to use CMS for Google Firestore 🎉
JavaScript
4
star
46

famous-sizemodifier

Deprecated - Use famous-sizeconstraint instead
JavaScript
3
star
47

famous-resources

Unofficial list of famo.us resources
2
star
48

expo-git-import-main

TypeScript
2
star
49

wkwebview-crash

Project to intentionally crash WkWebView for testing purposes
Objective-C
2
star
50

famous-lib-tester

Project for testing whether my libraries and famo.us can be build successfully using webpack, browserify, etc...
JavaScript
1
star
51

famous-test-positionabsolute

Test for absolute positioning issue when showing keyboard on mobile (iOS & android)
JavaScript
1
star
52

expo-av-9596-repro

JavaScript
1
star
53

famous-zindex

JavaScript
1
star
54

famous-bling

View templates (with animations) to jumpstart your project or for production use
JavaScript
1
star
55

famous-flex-scrollview-linking

Demo for showcasing FlexScrollView leading & trailing scrollview linking
1
star
56

ijzerenhein-website

My personal public website
JavaScript
1
star
57

famous-physics-playground

Playground for experimenting with physics based animation effects
JavaScript
1
star
58

contributors-code

Life as an open source contributor
1
star
59

expo-av-music-control

Java
1
star
60

famous-flex-truesize-layoutcontroller-demo

JavaScript
1
star
61

scrollview.js

Lightweight & fast javascript scrollview, look no further
JavaScript
1
star
62

famous-playground

General purpose playground repo for famo.us
JavaScript
1
star