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

Shared element transition #941

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
185966e
Add transition files
lintonye Mar 31, 2017
f3ca1d0
Add transition Playground example
lintonye Mar 31, 2017
69e2e56
Transition-ify CardStack
lintonye Apr 1, 2017
8653f17
No need to use prevTransitionProps to create styleMap
lintonye Apr 1, 2017
e308188
Remove prevTransitionProps
lintonye Apr 2, 2017
1186320
Fix warning about keys
lintonye Apr 3, 2017
7884929
Enable transition for Card
lintonye Apr 3, 2017
1192b91
Merge branch 'master' into multi-transitions-rewrite
lintonye Apr 3, 2017
557ff88
Transition.SharedElement.Image
lintonye Apr 3, 2017
a9add5b
initTransition => bindTransition
lintonye Apr 3, 2017
2ce0f75
Merge branch 'multi-transitions-rewrite' into shared-element
lintonye Apr 3, 2017
85c6817
Add initial sharedElement transition
lintonye Apr 3, 2017
4a0c27d
Default transition
lintonye Apr 4, 2017
deca625
Use default transition if can't find matching one
lintonye Apr 4, 2017
b28a0c3
Update comments
lintonye Apr 4, 2017
46fa6ba
Add unit tests for transitions
lintonye Apr 4, 2017
f94f9bc
Merge branch 'multi-transitions-rewrite' into shared-element
lintonye Apr 4, 2017
e9af592
Use sharedElement transition if applicable
lintonye Apr 4, 2017
6f8ed4d
TransitionItem: pass a config param instead of individual fields
lintonye Apr 4, 2017
eb808f9
Transition.SharedElement.*
lintonye Apr 4, 2017
bd87bae
Restructure a bit _findTransitionContainer
lintonye Apr 4, 2017
243bf5b
Merge branch 'multi-transitions-rewrite' into shared-element
lintonye Apr 4, 2017
936224d
Fix error due to useNativeDriver=true
lintonye Apr 4, 2017
412fafc
Update playground root description
lintonye Apr 4, 2017
198148b
Switch back to Playground root
lintonye Apr 4, 2017
025a1a6
Add go back button on shared element example
lintonye Apr 4, 2017
eeff31b
Add some type annotations
lintonye Apr 4, 2017
4df9b89
Merge branch 'master' into shared-element
lintonye Apr 4, 2017
f4073c3
Remove transitionConfig hooks in StackNavigator
lintonye Apr 4, 2017
b861bfd
Clean up comments
lintonye Apr 4, 2017
4513041
Force update when moving to a new scene
lintonye Apr 6, 2017
4a6bea7
Only force update when getItemsToMeasure is undefined
lintonye Apr 6, 2017
e390e15
Remove outdated comments
lintonye Apr 6, 2017
5988e3b
Obtain transition configuration from component navigationOptions
lintonye Apr 6, 2017
61118c3
SharedElement.create => SharedElement.createComponent
lintonye Apr 6, 2017
0c90e6a
Code cleanup
lintonye Apr 6, 2017
73b39b7
Filter: every => some
lintonye Apr 6, 2017
ff2dacf
Comment out logging
lintonye Apr 6, 2017
fefc7f5
Add PhotoMoreDetail
lintonye Apr 6, 2017
77c5fa1
type => transitionType
lintonye Apr 6, 2017
080014a
Pass type of the original component as a prop
lintonye Apr 6, 2017
13aee6b
withType => withTransitionType
lintonye Apr 6, 2017
3e31586
SharedElement: animate front size and scale
lintonye Apr 6, 2017
1de7e3d
Fix typo: direction < 1 => direction < 0
lintonye Apr 6, 2017
05d3b02
Merge branch 'master' into shared-element
lintonye Apr 6, 2017
b1ac1e6
that => this
lintonye Apr 6, 2017
6d8d944
Fix flow errors
lintonye Apr 6, 2017
a1c311b
Fix flow errors
lintonye Apr 10, 2017
3b196e5
Only call transition methods during transition
lintonye Apr 10, 2017
b328d0a
Fix flow errors
lintonye Apr 10, 2017
ab410d6
Make defaults for getItemsToMeasure and getItemsToClone
lintonye Apr 10, 2017
ebf9e27
Fix Flow errors
lintonye Apr 10, 2017
d3ef6ec
Fix failing unit test
lintonye Apr 10, 2017
43e8fab
Fix flow errors
lintonye Apr 10, 2017
fe586bf
Merge branch 'master' into shared-element
lintonye Apr 10, 2017
2aae2ac
Create overlay only when requesting some items to clone
lintonye Apr 11, 2017
416ffe5
Use position to interpolate overlay style
lintonye Apr 11, 2017
5aa7ace
Use position to interpolate cloned items on scene
lintonye Apr 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/NavigationPlayground/js/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import StacksInTabs from './StacksInTabs';
import StacksOverTabs from './StacksOverTabs';
import SimpleStack from './SimpleStack';
import SimpleTabs from './SimpleTabs';
import Transitions from './Transitions';

const ExampleRoutes = {
SimpleStack: {
Expand Down Expand Up @@ -75,6 +76,12 @@ const ExampleRoutes = {
screen: SimpleTabs,
path: 'settings',
},
Transitions: {
name: 'Shared Element Transition',
description: 'Shared element transition',
screen: Transitions,
path: 'transitions',
},
};

const MainScreen = ({ navigation }) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// @flow
import React, { Component } from 'react';
import {
View,
ScrollView,
Image,
StyleSheet,
Animated,
Dimensions,
Text,
Easing,
ListView,
} from 'react-native';

import { Transition } from 'react-navigation';

import Touchable from './Touchable';

const { width: windowWidth } = Dimensions.get("window");

const PhotoDetail = (props) => {
const { photo } = props.navigation.state.params;
const { url, title, description, image, comments } = photo;
const openMoreDetails = photo => props.navigation.navigate('PhotoMoreDetail', { photo });
const renderHeader = () => (
<View>
<Touchable onPress={() => openMoreDetails(photo)}>
<Transition.SharedElement.Image id={`image-${url}`} source={image} style={styles.image} />
</Touchable>
<View style={styles.titleContainer} onLayout={this._onLayout}>
<Transition.SharedElement.Text id={`title-${url}`}
style={[styles.text, styles.title]}>{title}</Transition.SharedElement.Text>
</View>
<Text style={[styles.text]}>{description}</Text>
</View>
);
return (
<View>
<ListView dataSource={dsComments.cloneWithRows(comments)}

This comment was marked as abuse.

renderRow={renderComment}
renderHeader={renderHeader}
/>
</View>
)
};

PhotoDetail.navigationOptions = {
title: 'Photo Detail'
}

const renderComment = ({ author, comment, avatar, time }) => (
<View style={commentStyles.container}>
<View style={commentStyles.textContainer}>
<View style={commentStyles.authorContainer}>
<Text>{author}</Text>
<Text>{time}</Text>
</View>
<Text style={commentStyles.text}>{comment}</Text>
</View>
</View>
);

const dsComments = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});


const styles = StyleSheet.create({
image: {
width: windowWidth,
height: windowWidth / 2,
},
title: {
fontSize: 35,
fontWeight: 'bold',
},
text: {
margin: 15,
}
});

const commentStyles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
marginLeft: 16,
marginRight: 16,
height: 72,
},
textContainer: {
flex: 1,
},
text: {
},
authorContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
}
});

export default PhotoDetail;
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// @flow
import React, { Component } from 'react';
import {
ListView,
Image,
View,
Text,
Dimensions,
StyleSheet,
Button,
} from 'react-native';
import faker from 'faker';
import _ from 'lodash';

import { Transition } from 'react-navigation';
import Touchable from './Touchable';

const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});

const images = [
require('./images/img1.jpg'),
require('./images/img2.jpg'),
require('./images/img3.jpg'),
require('./images/img4.jpg'),
require('./images/img5.jpg'),
require('./images/img6.jpg'),
require('./images/img7.jpg'),
require('./images/img8.jpg'),
require('./images/img9.jpg'),
require('./images/img10.jpg'),
require('./images/img11.jpg'),
require('./images/img12.jpg'),
]

const photos = Array(50).fill(0).map(_ => ({
url: faker.image.animals(500, 500, true),
image: images[faker.random.number(images.length - 1)],
title: faker.name.findName(),
description: faker.lorem.paragraphs(10),
comments: Array(20).fill(0).map(_ => (
{
author: faker.name.findName(),
// avatar: avatars[faker.random.number(4)],
comment: faker.lorem.sentence(),
time: '12/21/2017',
}
))
}));

const colCount = 3;

const { width: windowWidth } = Dimensions.get("window");
const margin = 2;
const photoWidth = (windowWidth - margin * colCount * 2) / colCount;

const photoRows = _.chunk(photos, colCount);

class PhotoGrid extends Component {
static navigationOptions = {
title: 'Photo Grid'
}
render() {
return (
<View>
<ListView
dataSource={ds.cloneWithRows(photoRows)}
renderRow={this.renderRow.bind(this)}
/>
<Button title="Go back" onPress={() => this.props.navigation.goBack(null)} style={styles.goBack} />
</View>
);
}
renderRow(photos) {
return (
<View style={styles.row}>
{photos.map(this.renderCell.bind(this))}
</View>
)
}
renderCell(photo) {
const onPhotoPressed = photo => this.props.navigation.navigate('PhotoDetail', { photo });
return (
<Touchable onPress={() => onPhotoPressed(photo)} key={photo.url}>
<View style={styles.cell}>
<Transition.SharedElement.Image id={`image-${photo.url}`}
source={photo.image} style={styles.image} />
</View>
</Touchable>
)
}
}

const styles = StyleSheet.create({
row: {
flexDirection: 'row',
},
cell: {
margin: 2,
},
image: {
width: photoWidth,
height: photoWidth,
},
goBack: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
}
})

export default PhotoGrid;
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// @flow
import React, { Component } from 'react';
import {
View,
ScrollView,
Image,
StyleSheet,
Animated,
Dimensions,
Text,
Easing,
TouchableNativeFeedback,
} from 'react-native';

import { Transition } from 'react-navigation';

const { width: windowWidth } = Dimensions.get("window");

const PhotoMoreDetail = (props) => {
const { photo: { url, title, description, image } } = props.navigation.state.params;
return (
<View>
<ScrollView>
<View>
<View style={styles.container}>
<Transition.SharedElement.Text id={`title-${url}`} style={[styles.text, styles.title]}>{title}</Transition.SharedElement.Text>
<Transition.SharedElement.Image id={`image-${url}`} source={image} style={styles.image} />
</View>
<Text style={[styles.text]}>{description}</Text>
</View>
</ScrollView>
</View>
)
};

PhotoMoreDetail.navigationOptions = {
title: 'Photo More Detail',
}

const styles = StyleSheet.create({
image: {
width: 160,
height: 160,
},
title: {
fontSize: 25,
fontWeight: 'bold',
},
text: {
margin: 15,
},
container: {
flexDirection: 'row',
}
})

export default PhotoMoreDetail;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import {
TouchableNativeFeedback,
TouchableOpacity,
Platform,
} from 'react-native';

const Touchable = props => {
const Comp = (Platform.OS === 'android'
? TouchableNativeFeedback
: TouchableOpacity);
return <Comp {...props} />
}

export default Touchable;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
StackNavigator,
} from 'react-navigation';

import PhotoGrid from './PhotoGrid';
import PhotoDetail from './PhotoDetail';
import PhotoMoreDetail from './PhotoMoreDetail';
import { Transition } from 'react-navigation';
import _ from 'lodash';
import faker from 'faker';

const App = StackNavigator({
PhotoGrid: {
screen: PhotoGrid,
},
PhotoDetail: {
screen: PhotoDetail,
},
PhotoMoreDetail: {
screen: PhotoMoreDetail,
}
});

export default App;
4 changes: 4 additions & 0 deletions examples/NavigationPlayground/js/Transitions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import SharedElements from './SharedElements';

// TODO export a navigator
export default SharedElements;
Loading