├── .gitignore ├── FadeIn.android.js ├── FadeIn.js ├── README.md ├── example ├── .gitignore ├── App.js ├── babel.config.js └── package.json ├── index.d.ts ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | -------------------------------------------------------------------------------- /FadeIn.android.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | const onlyChild = React.Children.only; 5 | 6 | export default class FadeIn extends React.Component { 7 | 8 | render() { 9 | let image = onlyChild(this.props.children); 10 | 11 | // Get rid of any unused styles to avoid warnings 12 | let safeImageStyle = {...StyleSheet.flatten(image.props.style)}; 13 | delete safeImageStyle.tintColor; 14 | delete safeImageStyle.resizeMode; 15 | 16 | return ( 17 | 18 | 19 | 20 | {this.props.renderPlaceholderContent} 21 | 22 | 23 | 24 | {image} 25 | 26 | ); 27 | } 28 | } 29 | 30 | let styles = StyleSheet.create({ 31 | placeholderContainer: { 32 | position: 'absolute', 33 | top: 0, 34 | left: 0, 35 | bottom: 0, 36 | right: 0, 37 | }, 38 | placeholder: { 39 | // default no placeholder style 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /FadeIn.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated, StyleSheet, View } from 'react-native'; 3 | import TimerMixin from 'react-timer-mixin'; 4 | 5 | import reactMixin from 'react-mixin'; 6 | import cloneReferencedElement from 'react-clone-referenced-element'; 7 | 8 | const onlyChild = React.Children.only; 9 | 10 | export default class FadeIn extends React.Component { 11 | static defaultProps = { 12 | useNativeDriver: true, 13 | }; 14 | 15 | state = { 16 | placeholderContainerOpacity: new Animated.Value(1), 17 | }; 18 | 19 | render() { 20 | let image = cloneReferencedElement(onlyChild(this.props.children), { 21 | ref: component => { 22 | this._image = component; 23 | }, 24 | onLoadEnd: this._onLoadEnd, 25 | }); 26 | 27 | let safeImageProps = { ...StyleSheet.flatten(image.props.style) }; 28 | delete safeImageProps.tintColor; 29 | delete safeImageProps.resizeMode; 30 | 31 | return ( 32 | 33 | {image} 34 | 35 | 41 | 48 | {this.props.renderPlaceholderContent} 49 | 50 | 51 | 52 | ); 53 | } 54 | 55 | _onLoadEnd = () => { 56 | /* NOTE(brentvatne): If we animate in immediately when the onLoadEvent event 57 | fires, there are two unwanted consequences: 58 | 1. Animation feels janky - not entirely sure why that is 59 | (handled with minimumWait) 60 | 2. Many images finish loading in the same frame for some reason, and in my 61 | opinion it looks better when the images fade in separately 62 | (handled with staggerNonce) */ 63 | 64 | const minimumWait = 100; 65 | const staggerNonce = 200 * Math.random(); 66 | 67 | this.setTimeout(() => { 68 | Animated.timing(this.state.placeholderContainerOpacity, { 69 | toValue: 0, 70 | duration: 350, 71 | useNativeDriver: this.props.useNativeDriver, 72 | }).start(); 73 | }, minimumWait + staggerNonce); 74 | }; 75 | } 76 | 77 | reactMixin(FadeIn.prototype, TimerMixin); 78 | 79 | let styles = StyleSheet.create({ 80 | placeholderContainer: { 81 | position: 'absolute', 82 | top: 0, 83 | left: 0, 84 | bottom: 0, 85 | right: 0, 86 | }, 87 | placeholder: { 88 | backgroundColor: '#eee', 89 | }, 90 | }); 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated: replaced by expo-image 2 | 3 | This library is deprecated. Use [expo-image](https://docs.expo.dev/versions/latest/sdk/image/) instead - it has this behavior built-in. 4 | 5 |
6 | 7 | ## react-native-fade-in-image 8 | 9 | Wrap Image components in `` to have them fade in pleasantly when they finish loading. 10 | 11 | ### Installation 12 | 13 | ``` 14 | npm i react-native-fade-in-image --save 15 | ``` 16 | 17 | ### Usage 18 | 19 | ```javascript 20 | import React from 'react'; 21 | import { Image } from 'react-native'; 22 | import FadeIn from 'react-native-fade-in-image'; 23 | 24 | const uri = 'https://d3lwq5rlu14cro.cloudfront.net/v1/AQ5jDS5SYyUkapWWEviV.png'; 25 | 26 | class FancyImage extends React.Component { 27 | render() { 28 | return ( 29 | 30 | 31 | 32 | ); 33 | } 34 | } 35 | ``` 36 | 37 | #### props 38 | 39 | - `style` adds style to the image wrapper. 40 | - `renderPlaceholderContent` renders an element while loading the image, e.g. a spinner. 41 | - `placeholderStyle` adds style to the placeholder wrapper, default background color is `#eee`. 42 | 43 | ### Example 44 | 45 | See the [example 46 | project 47 | source](https://github.com/expo/react-native-fade-in-image/tree/master/example) 48 | or try it out at https://exp.host/@community/fade-in-image-example 49 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | 12 | # macOS 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /example/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ActivityIndicator, Image, View } from 'react-native'; 3 | 4 | import FadeIn from 'react-native-fade-in-image'; 5 | 6 | const Placeholder = () => ( 7 | 8 | 9 | 10 | ); 11 | 12 | const uri1 = 'http://media.idownloadblog.com/wp-content/uploads/2016/06/macOS-Sierra-Wallpaper-Macbook-Wallpaper.jpg'; 13 | const uri2 = 'http://media.idownloadblog.com/wp-content/uploads/2015/06/Wallpaper-OS-X-El-Capitan-Mac.jpg'; 14 | 15 | const FancyImage = ({ uri, style }) => ( 16 | } 19 | placeholderStyle={{ backgroundColor: '#eee' }}> 20 | 21 | 22 | ); 23 | 24 | export default function App () { 25 | return ( 26 | 27 | 28 | 29 | 30 | ); 31 | } 32 | 33 | const full = { flex: 1 }; 34 | const landing = { flex: 1, alignItems: 'center', justifyContent: 'center' }; 35 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /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 | "web": "expo start --web" 8 | }, 9 | "dependencies": { 10 | "react-native-fade-in-image": "^1.5.0", 11 | "expo": "~41.0.1", 12 | "expo-status-bar": "~1.0.4", 13 | "react": "16.13.1", 14 | "react-dom": "16.13.1", 15 | "react-native": "^0.63.2", 16 | "react-native-web": "~0.13.12" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.9.0" 20 | }, 21 | "private": true 22 | } 23 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleProp, ViewStyle } from 'react-native'; 3 | 4 | export interface FadeInProps { 5 | style?: StyleProp; 6 | renderPlaceholderContent?: React.ReactNode; 7 | placeholderStyle?: StyleProp; 8 | children?: React.ReactNode; 9 | } 10 | 11 | export default class FadeIn extends React.Component {} 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import FadeIn from './FadeIn'; 2 | export default FadeIn; 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-fade-in-image", 3 | "version": "1.6.1", 4 | "description": "Wrap Image components in to have them fade in pleasantly when they finish loading", 5 | "main": "index.js", 6 | "types": "./index.d.ts", 7 | "author": "Brent Vatne ", 8 | "license": "MIT", 9 | "files": [ 10 | "FadeIn.android.js", 11 | "FadeIn.js", 12 | "index.js", 13 | "index.d.ts", 14 | "README.md" 15 | ], 16 | "dependencies": { 17 | "react-clone-referenced-element": "^1.0.1", 18 | "react-mixin": "^3.0.5", 19 | "react-timer-mixin": "^0.13.3" 20 | } 21 | } 22 | --------------------------------------------------------------------------------