├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── .prettierrc ├── Example ├── .gitignore ├── .vscode │ ├── launch.json │ └── settings.json ├── .watchmanconfig ├── App.js ├── app.json ├── assets │ ├── icon.png │ └── splash.png ├── babel.config.js ├── components │ ├── Button │ │ ├── Button.js │ │ └── styles.js │ ├── ListItem │ │ ├── ListItem.js │ │ └── styles.js │ ├── Separator │ │ ├── Separator.js │ │ └── styles.js │ └── index.js ├── navigation │ ├── AppNavigator.js │ └── screens.js ├── package.json ├── rn-cli.config.js ├── screens │ ├── DelegateScroll │ │ ├── DelegateScroll.js │ │ ├── components │ │ │ ├── Header │ │ │ │ ├── Header.js │ │ │ │ ├── constants.js │ │ │ │ └── styles.js │ │ │ ├── Placeholder │ │ │ │ ├── Placeholder.js │ │ │ │ └── styles.js │ │ │ ├── SearchBox │ │ │ │ ├── SearchBox.js │ │ │ │ └── styles.js │ │ │ └── index.js │ │ └── styles.js │ ├── Examples │ │ └── Examples.js │ ├── InterpolationTransition │ │ └── InterpolationTransition.js │ ├── Keyframes │ │ └── Keyframes.js │ └── TransitionBase │ │ └── TransitionBase.js ├── services │ ├── NavigationService.js │ └── index.js ├── styles │ ├── colors.js │ └── index.js └── utils │ ├── createKeys.js │ └── index.js ├── LICENSE ├── README.md ├── lib ├── components │ ├── DelegateAnimation.js │ ├── InterpolationTransitionAnimation.js │ ├── KeyframesAnimation.js │ ├── LoopAnimation.js │ ├── Reanimatable.js │ ├── ScrollView.js │ ├── TransitionAnimation.js │ ├── index.js │ └── propTypes.js ├── core │ ├── animations.js │ ├── constants.js │ ├── createConfig.js │ ├── createDelegate.js │ ├── createDelegateAnimation.js │ ├── createInterpolationTransitionAnimation.js │ ├── createKeyframesAnimation.js │ └── createTransitionAnimation.js ├── index.js └── utils │ ├── createKeys.js │ ├── index.js │ └── objectPath.js └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["module:metro-react-native-babel-preset"], 3 | "plugins": [ 4 | "@babel/plugin-proposal-export-namespace-from" 5 | ] 6 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "globals": { "fetch": false }, 5 | "env": { 6 | "jest": true 7 | }, 8 | "plugins": ["react", "react-native"], 9 | "settings": { 10 | "import/resolver": { 11 | "node": { 12 | "extensions": [".js", ".android.js", ".ios.js"] 13 | } 14 | } 15 | }, 16 | "rules": { 17 | "jsx-a11y/href-no-hash": "off", 18 | "max-len": [2, 100, 2], 19 | "import/no-extraneous-dependencies": [ 20 | "error", 21 | { 22 | "devDependencies": true, 23 | "optionalDependencies": false, 24 | "peerDependencies": false 25 | } 26 | ], 27 | "function-paren-newline": 0, 28 | "import/prefer-default-export": 0, 29 | "no-trailing-spaces": ["error", { "skipBlankLines": true }], 30 | "no-underscore-dangle": 0, 31 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 32 | "react/forbid-prop-types": 0, 33 | "react/require-default-props": 0, 34 | "react-native/no-unused-styles": 2, 35 | "react-native/split-platform-components": 2, 36 | "react-native/no-inline-styles": 2, 37 | "react-native/no-color-literals": 2, 38 | "class-methods-use-this": "off", 39 | "arrow-parens": "off", 40 | "import/no-unresolved": ["error", { "ignore": ["^react$", "^react-native$", "^react-native-reanimated$"] }], 41 | "import/extensions": ["error", "never", {"ignorePackages": true, "js": "never"} ], 42 | "react/no-multi-comp": 0 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | **/.DS_Store 5 | 6 | node_modules/**/* 7 | dest/ 8 | npm-debug.* 9 | package-lock.json -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "printWidth": 70, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "trailingComma": "all", 7 | "jsxBracketSameLine": false, 8 | "parser": "babylon", 9 | "noSemi": false, 10 | "rcVerbose": true, 11 | "arrowParens": "always" 12 | } -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | package-lock.json 5 | *.jks 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | .vscode/.react -------------------------------------------------------------------------------- /Example/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug Android", 9 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 10 | "type": "reactnative", 11 | "request": "launch", 12 | "platform": "android", 13 | "sourceMaps": true, 14 | "outDir": "${workspaceRoot}/.vscode/.react" 15 | }, 16 | { 17 | "name": "Debug iOS", 18 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 19 | "type": "reactnative", 20 | "request": "launch", 21 | "platform": "ios", 22 | "sourceMaps": true, 23 | "outDir": "${workspaceRoot}/.vscode/.react" 24 | }, 25 | { 26 | "name": "Attach to packager", 27 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 28 | "type": "reactnative", 29 | "request": "attach", 30 | "platform": "exponent", 31 | "sourceMaps": true, 32 | "outDir": "${workspaceRoot}/.vscode/.react" 33 | }, 34 | { 35 | "name": "Debug in Exponent", 36 | "program": "${workspaceRoot}/.vscode/launchReactNative.js", 37 | "type": "reactnative", 38 | "request": "launch", 39 | "platform": "exponent", 40 | "sourceMaps": true, 41 | "outDir": "${workspaceRoot}/.vscode/.react" 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /Example/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "disabled" 3 | } -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Example/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StatusBar } from 'react-native'; 3 | import AppNavigator from './navigation/AppNavigator'; 4 | import { NavigationService } from './services'; 5 | // import screens from './navigation/screens'; 6 | 7 | class App extends React.PureComponent { 8 | componentDidMount() { 9 | // use it to navigate to proper screen on mount 10 | // useful for developing 11 | // NavigationService.navigate(screens.DelegateScroll); 12 | } 13 | 14 | render() { 15 | return ( 16 | 17 | 22 | NavigationService.init(ref)} /> 23 | 24 | ); 25 | } 26 | } 27 | 28 | export default App; 29 | -------------------------------------------------------------------------------- /Example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "Example", 4 | "slug": "Example", 5 | "privacy": "public", 6 | "sdkVersion": "32.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android" 10 | ], 11 | "version": "1.0.0", 12 | "orientation": "portrait", 13 | "icon": "./assets/icon.png", 14 | "splash": { 15 | "image": "./assets/splash.png", 16 | "resizeMode": "contain", 17 | "backgroundColor": "#ffffff" 18 | }, 19 | "updates": { 20 | "fallbackToCacheTimeout": 0 21 | }, 22 | "assetBundlePatterns": [ 23 | "**/*" 24 | ], 25 | "ios": { 26 | "supportsTablet": true 27 | }, 28 | "androidStatusBar": { 29 | "barStyle": "dark-content" 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terrysahaidak/react-native-reanimatable/f4e26e27a785c6c6d38024ff71c55be527a8794b/Example/assets/icon.png -------------------------------------------------------------------------------- /Example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terrysahaidak/react-native-reanimatable/f4e26e27a785c6c6d38024ff71c55be527a8794b/Example/assets/splash.png -------------------------------------------------------------------------------- /Example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /Example/components/Button/Button.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import T from 'prop-types'; 3 | import { View, TouchableOpacity, Text } from 'react-native'; 4 | import s from './styles'; 5 | 6 | const Button = ({ onPress, text }) => ( 7 | 8 | 9 | {text} 10 | 11 | 12 | ); 13 | 14 | Button.propTypes = { 15 | text: T.string, 16 | onPress: T.func, 17 | }; 18 | 19 | export default Button; 20 | -------------------------------------------------------------------------------- /Example/components/Button/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../styles'; 3 | 4 | const styles = StyleSheet.create({ 5 | container: { 6 | padding: 8, 7 | backgroundColor: colors.green, 8 | borderRadius: 6, 9 | margin: 8, 10 | }, 11 | text: { 12 | color: colors.white, 13 | }, 14 | }); 15 | 16 | export default styles; 17 | -------------------------------------------------------------------------------- /Example/components/ListItem/ListItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import T from 'prop-types'; 3 | import { View, TouchableWithoutFeedback, Text } from 'react-native'; 4 | import { Feather } from '@expo/vector-icons'; 5 | import { colors } from '../../styles'; 6 | import s from './styles'; 7 | 8 | const ListItem = ({ onPress, title }) => ( 9 | 10 | 11 | {title} 12 | 13 | 18 | 19 | 20 | ); 21 | 22 | ListItem.propTypes = { 23 | onPress: T.func, 24 | title: T.string, 25 | }; 26 | 27 | export default ListItem; 28 | -------------------------------------------------------------------------------- /Example/components/ListItem/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../styles'; 3 | 4 | const styles = StyleSheet.create({ 5 | container: { 6 | height: 52, 7 | flex: 1, 8 | flexDirection: 'row', 9 | alignItems: 'center', 10 | justifyContent: 'space-between', 11 | paddingHorizontal: 16, 12 | }, 13 | title: { 14 | fontSize: 17, 15 | color: colors.text, 16 | }, 17 | }); 18 | 19 | export default styles; 20 | -------------------------------------------------------------------------------- /Example/components/Separator/Separator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import T from 'prop-types'; 3 | import { View } from 'react-native'; 4 | import s from './styles'; 5 | 6 | const Separator = () => ( 7 | 8 | ); 9 | 10 | Separator.propTypes = { 11 | 12 | }; 13 | 14 | export default Separator; 15 | -------------------------------------------------------------------------------- /Example/components/Separator/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../styles'; 3 | 4 | const styles = StyleSheet.create({ 5 | container: { 6 | height: StyleSheet.hairlineWidth, 7 | flex: 1, 8 | backgroundColor: colors.border, 9 | }, 10 | }); 11 | 12 | export default styles; 13 | -------------------------------------------------------------------------------- /Example/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Separator } from './Separator/Separator'; 2 | export { default as ListItem } from './ListItem/ListItem'; 3 | export { default as Button } from './Button/Button'; 4 | -------------------------------------------------------------------------------- /Example/navigation/AppNavigator.js: -------------------------------------------------------------------------------- 1 | import { 2 | createStackNavigator, 3 | createAppContainer, 4 | } from 'react-navigation'; 5 | import screens from './screens'; 6 | import Examples from '../screens/Examples/Examples'; 7 | import TransitionBase from '../screens/TransitionBase/TransitionBase'; 8 | import InterpolationTransition from '../screens/InterpolationTransition/InterpolationTransition'; 9 | import Keyframes from '../screens/Keyframes/Keyframes'; 10 | import DelegateScroll from '../screens/DelegateScroll/DelegateScroll'; 11 | 12 | const AppNavigator = createStackNavigator( 13 | { 14 | [screens.Examples]: Examples, 15 | [screens.TransitionBase]: TransitionBase, 16 | [screens.InterpolationTransition]: InterpolationTransition, 17 | [screens.Keyframes]: Keyframes, 18 | [screens.DelegateScroll]: DelegateScroll, 19 | }, 20 | { 21 | defaultNavigationOptions: ({ navigation }) => ({ 22 | title: navigation.getParam('title'), 23 | }), 24 | }, 25 | ); 26 | 27 | export default createAppContainer(AppNavigator); 28 | -------------------------------------------------------------------------------- /Example/navigation/screens.js: -------------------------------------------------------------------------------- 1 | import { createKeys } from '../utils'; 2 | 3 | const screens = createKeys([ 4 | 'Examples', 5 | 'TransitionBase', 6 | 'InterpolationTransition', 7 | 'Keyframes', 8 | 'DelegateScroll', 9 | ]); 10 | 11 | export default screens; 12 | -------------------------------------------------------------------------------- /Example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "eject": "expo eject" 8 | }, 9 | "dependencies": { 10 | "@expo/vector-icons": "^9.0.0", 11 | "expo": "^32.0.0", 12 | "prop-types": "^15.7.1", 13 | "react": "16.5.0", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz", 15 | "react-native-reanimatable": "*", 16 | "react-native-reanimated": "^1.0.0-alpha.12", 17 | "react-navigation": "^3.2.1" 18 | }, 19 | "devDependencies": { 20 | "babel-preset-expo": "^5.0.0" 21 | }, 22 | "private": true 23 | } 24 | -------------------------------------------------------------------------------- /Example/rn-cli.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | const path = require('path'); 4 | 5 | const extraNodeModules = { 6 | 'react-native': path.resolve( 7 | __dirname, 8 | 'node_modules/react-native', 9 | ), 10 | react: path.resolve(__dirname, 'node_modules/react'), 11 | 'react-native-reanimated': path.resolve( 12 | __dirname, 13 | 'node_modules/react-native-reanimated', 14 | ), 15 | }; 16 | const blacklistRegexes = [ 17 | /react-native-reanimatable[/\\]node_modules[/\\]react-native[/\\].*/, 18 | ]; 19 | const watchFolders = [path.resolve('../')]; 20 | 21 | const metroVersion = require('metro/package.json').version; 22 | 23 | const metroVersionComponents = metroVersion.match( 24 | /^(\d+)\.(\d+)\.(\d+)/, 25 | ); 26 | if ( 27 | metroVersionComponents[1] === '0' && 28 | parseInt(metroVersionComponents[2], 10) >= 43 29 | ) { 30 | module.exports = { 31 | resolver: { 32 | extraNodeModules, 33 | blacklistRE: require('metro-config/src/defaults/blacklist')( 34 | blacklistRegexes, 35 | ), 36 | }, 37 | watchFolders, 38 | }; 39 | } else { 40 | module.exports = { 41 | extraNodeModules, 42 | getBlacklistRE: () => 43 | require('metro/src/blacklist')(blacklistRegexes), 44 | getProjectRoots: () => 45 | [path.resolve(__dirname)].concat(watchFolders), 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/DelegateScroll.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import { ScrollView } from 'react-native-reanimatable'; 4 | import s from './styles'; 5 | import { Placeholder, Header } from './components'; 6 | import { 7 | MAX_HEADER_HEIGHT, 8 | delegate, 9 | } from './components/Header/constants'; 10 | 11 | const snapPoints = [ 12 | { from: 0, to: 28, snap: 0 }, 13 | { from: 28, to: 51, snap: 51 }, 14 | ]; 15 | 16 | const App = () => ( 17 | 18 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | ); 37 | 38 | App.navigationOptions = { 39 | header: null, 40 | }; 41 | 42 | export default App; 43 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/Header/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import Animated from 'react-native-reanimated'; 4 | import { 5 | createAnimationConfig, 6 | Reanimatable, 7 | } from 'react-native-reanimatable'; 8 | import s from './styles'; 9 | import { MAX_HEADER_HEIGHT, delegate } from './constants'; 10 | import { SearchBox } from '../'; 11 | 12 | const animation = createAnimationConfig({ 13 | animation: { 14 | delegate, 15 | }, 16 | keyframes: { 17 | '-100': { 18 | fontSize: 36, 19 | height: MAX_HEADER_HEIGHT + 100, 20 | }, 21 | 0: { 22 | fontSize: 34, 23 | height: MAX_HEADER_HEIGHT, 24 | }, 25 | 88: { 26 | headingOpacity: 1, 27 | opacity: 0, 28 | }, 29 | 90: { 30 | headingOpacity: 0, 31 | opacity: 1, 32 | }, 33 | 103: { 34 | height: MAX_HEADER_HEIGHT - 103, 35 | }, 36 | }, 37 | }); 38 | 39 | const Header = () => ( 40 | 41 | {({ 42 | height, 43 | fontSize, 44 | paddingBottom, 45 | opacity, 46 | headingOpacity, 47 | }) => ( 48 | 49 | 50 | 56 | Delegation 57 | 58 | 59 | 60 | 61 | 62 | 63 | Delegation 64 | 65 | 66 | 67 | )} 68 | 69 | ); 70 | 71 | export default Header; 72 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/Header/constants.js: -------------------------------------------------------------------------------- 1 | import { createDelegate } from 'react-native-reanimatable'; 2 | 3 | export const MAX_HEADER_HEIGHT = 168; 4 | export const delegate = createDelegate('scroll', [ 5 | 'contentOffset', 6 | 'y', 7 | ]); 8 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/Header/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../../../styles'; 3 | 4 | const styles = StyleSheet.create({ 5 | container: { 6 | flex: 1, 7 | borderBottomColor: colors.border, 8 | borderBottomWidth: StyleSheet.hairlineWidth, 9 | position: 'absolute', 10 | left: 0, 11 | right: 0, 12 | backgroundColor: colors.background, 13 | }, 14 | bottomContainer: { 15 | paddingHorizontal: 16, 16 | position: 'absolute', 17 | bottom: 0, 18 | left: 0, 19 | right: 0, 20 | }, 21 | topContainer: { 22 | paddingHorizontal: 16, 23 | position: 'absolute', 24 | alignItems: 'center', 25 | justifyContent: 'center', 26 | backgroundColor: colors.background, 27 | top: 20, // status bar height 28 | left: 0, 29 | right: 0, 30 | height: 44, 31 | }, 32 | bigHeader: { 33 | color: colors.text, 34 | fontWeight: '700', 35 | marginBottom: 8, 36 | }, 37 | smallHeader: { 38 | color: colors.text, 39 | fontWeight: '600', 40 | fontSize: 17, 41 | }, 42 | searchContainer: { 43 | justifyContent: 'center', 44 | backgroundColor: colors.backgroundSecondary, 45 | flex: 1, 46 | borderRadius: 11, 47 | paddingLeft: 16, 48 | }, 49 | searchText: { 50 | color: colors.textSecondary, 51 | fontSize: 17, 52 | }, 53 | }); 54 | 55 | export default styles; 56 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/Placeholder/Placeholder.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text } from 'react-native'; 3 | import s from './styles'; 4 | 5 | const Placeholder = () => ( 6 | 7 | Placeholder 8 | 9 | ); 10 | 11 | export default Placeholder; 12 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/Placeholder/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | 3 | const styles = StyleSheet.create({ 4 | container: { 5 | height: 200, 6 | }, 7 | }); 8 | 9 | export default styles; 10 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/SearchBox/SearchBox.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Animated from 'react-native-reanimated'; 3 | import { 4 | createAnimationConfig, 5 | Reanimatable, 6 | } from 'react-native-reanimatable'; 7 | import Ionicons from '@expo/vector-icons/Ionicons'; 8 | import s from './styles'; 9 | import { delegate } from '../Header/constants'; 10 | import { colors } from '../../../../styles'; 11 | 12 | const searchAnimation = createAnimationConfig({ 13 | animation: { 14 | delegate, 15 | }, 16 | keyframes: { 17 | 0: { 18 | height: 36, 19 | opacity: 1, 20 | paddingBottom: 15, 21 | }, 22 | 8: { 23 | opacity: 0, 24 | }, 25 | 36: { 26 | height: 0, 27 | paddingBottom: 15, 28 | }, 29 | 51: { 30 | paddingBottom: 0, 31 | }, 32 | }, 33 | }); 34 | 35 | const Search = () => ( 36 | 37 | {({ height, opacity, paddingBottom }) => ( 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | Search 50 | 51 | 52 | 53 | )} 54 | 55 | ); 56 | 57 | export default Search; 58 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/SearchBox/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../../../styles'; 3 | 4 | const styles = StyleSheet.create({ 5 | container: { 6 | flexDirection: 'row', 7 | alignItems: 'center', 8 | backgroundColor: colors.backgroundSecondary, 9 | flex: 1, 10 | borderRadius: 11, 11 | paddingLeft: 8, 12 | }, 13 | text: { 14 | color: colors.textSecondary, 15 | fontSize: 17, 16 | marginLeft: 7, 17 | }, 18 | icon: { 19 | top: 1.5, 20 | }, 21 | }); 22 | 23 | export default styles; 24 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Placeholder } from './Placeholder/Placeholder'; 2 | export { default as Header } from './Header/Header'; 3 | export { default as SearchBox } from './SearchBox/SearchBox'; 4 | -------------------------------------------------------------------------------- /Example/screens/DelegateScroll/styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { colors } from '../../styles'; 3 | 4 | export default StyleSheet.create({ 5 | container: { 6 | flex: 1, 7 | backgroundColor: colors.white, 8 | }, 9 | placeholder: {}, 10 | header: { 11 | alignItems: 'center', 12 | justifyContent: 'center', 13 | backgroundColor: colors.green, 14 | flex: 1, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /Example/screens/Examples/Examples.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FlatList } from 'react-native'; 3 | import screens from '../../navigation/screens'; 4 | import { ListItem, Separator } from '../../components'; 5 | import { NavigationService } from '../../services'; 6 | 7 | const list = [ 8 | { title: 'Base transition', screen: screens.TransitionBase }, 9 | { 10 | title: 'Interpolation transition', 11 | screen: screens.InterpolationTransition, 12 | }, 13 | { 14 | title: 'Lazy Interpolation transition', 15 | screen: screens.InterpolationTransition, 16 | params: { 17 | lazy: true, 18 | }, 19 | }, 20 | { title: 'Keyframes (interpolation)', screen: screens.Keyframes }, 21 | { title: 'Delegate (Scroll)', screen: screens.DelegateScroll }, 22 | ]; 23 | 24 | const Examples = () => { 25 | const renderItem = ({ item }) => ( 26 | 29 | NavigationService.navigate(item.screen, { 30 | title: item.title, 31 | params: item.params, 32 | }) 33 | } 34 | /> 35 | ); 36 | 37 | return ( 38 | item.title} 44 | /> 45 | ); 46 | }; 47 | 48 | Examples.navigationOptions = { 49 | title: 'Examples', 50 | }; 51 | 52 | export default Examples; 53 | -------------------------------------------------------------------------------- /Example/screens/InterpolationTransition/InterpolationTransition.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Dimensions, FlatList } from 'react-native'; 3 | import { 4 | Reanimatable, 5 | createAnimationConfig, 6 | } from 'react-native-reanimatable'; 7 | import Animated from 'react-native-reanimated'; 8 | import { Button } from '../../components'; 9 | 10 | const { width: windowWidth } = Dimensions.get('window'); 11 | 12 | const colors = { 13 | red: '#e74c3c', 14 | white: 'white', 15 | green: '#2ecc71', 16 | }; 17 | 18 | const config = { 19 | animation: { 20 | type: 'timing', 21 | duration: 300, 22 | interpolation: true, 23 | lazy: false, 24 | }, 25 | values: { 26 | width: { from: 50, to: 200 }, 27 | height: { from: 50, to: 200 }, 28 | left: { from: 20, to: windowWidth - 20 - 200 }, 29 | borderRadius: { from: 0, to: 100 }, 30 | }, 31 | }; 32 | 33 | const defaultConfig = createAnimationConfig(config); 34 | 35 | config.animation.lazy = true; 36 | const lazyConfig = createAnimationConfig(config); 37 | 38 | const s = StyleSheet.create({ 39 | scroll: { 40 | paddingVertical: 20, 41 | }, 42 | animationContainer: { 43 | height: 250, 44 | justifyContent: 'center', 45 | }, 46 | animatableView: { 47 | backgroundColor: colors.red, 48 | }, 49 | row: { 50 | flexDirection: 'row', 51 | alignSelf: 'center', 52 | }, 53 | }); 54 | 55 | class Example extends React.PureComponent { 56 | state = { 57 | value: true, 58 | }; 59 | initialValue = this.state.value; 60 | 61 | toggleAnimation() { 62 | this.setState((state) => ({ value: !state.value })); 63 | } 64 | 65 | render() { 66 | return ( 67 | 68 | 73 | {({ translateX, ...animatedValues }) => ( 74 | 77 | )} 78 | 79 | 80 | 81 |