Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

QuintonC/rn-progressive-image

Repository files navigation

rn-progressive-image

An easy to use and highly customizable progressive-image component for react-native.



Built with 🖤  by Quinton Chester



Features

  • Optimistic UI that allows you to give users context before the images load.
  • Customizability
    • Choose between two different placeholder types, Shimmer or Thumbnail
    • Define your own animation durations, shimmer colors, animating easings, and more.
  • Built on react-native-reanimated
  • Includes type definitions for widespread adoption and a better understanding of how the package works.
  • Optimized code which removes unused placeholder after the image has loaded.
  • Covered by unit tests so you can rest assured that the component will never let you down.

Table of Contents

Installation

$ npm install rn-progressive-image

Note: This package makes use of other packages, specifically react-native-reanimated and react-native-linear-gradient. In order for this to work properly, you must follow the installation instructions for those packages. Not following these instructions will result in the package not working.

npm install react-native-reanimated react-native-linear-gradient

Reanimated instructions


Usage

Import the package as follows:

import ProgressiveImage from 'rn-progressive-image'

The simplest form of usage is as follows:

    <ProgressiveImage 
        source={{ uri: https://myimageprovider.com/myImagePath.jpg }}
    />

Note: using this component without specifying thumbnailSource will result in the placeholder being a ShimmerEffect.

Props


Prop Default Required Description
source true The source for the image which will be lazy-loaded
style A square that is equal to half of the device's width with a gray background. false Images use StyleSheet.absoluteFillObject, so define your desired style here and the images will automatically be set to cover the defined view.
thumbnailSource false The source for the thumbnail image which will be used for the placeholder.
blurRadius 3 false The blurRadius for the thumbnailImage. iOS only per React Native implementation. There is a thought for improvement listed near the end of the README that discusses the potential for a blur view to be added to Android in a future release.
shimmerColors [#F2F2F7, #DDDEE0, #F2F2F7] false The colors used for the shimmer effect.
shimmerDuration 1000 false The duration it takes for the shimmer to move across the View element.
inEasing Easing.bezier(0.65, 0, 0.35, 1) false This is the easing applied to the source image as it transitions in.
outEasing Easing.bezier(0.65, 0, 0.35, 1) false This is the easing that is applied to the placeholder as it transitions out.
animationDuration 350 false The transition duration for the image source fading in and the placeholder fading out.
onLoad false An optional callback that is invoked when the source image has loaded. This will trigger prior to the placeholder unmounting.
testID false Testing is important, and I understand that you will likely want to be able to test this component and the props within it. I've added a testID so you can do just that.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please follow the issue format outlined at the beginning of issue creation when creating a new issue. Additionally, please search through issues to see if your specific issue has already been mentioned, is currently being addressed, or has been fixed in an upcoming release.

To contribute, please ensure that you are using semver standards and writing unit tests for any additions you are making.

  1. Fork the repository
  2. Create your feature desired branch: git checkout -b feature/feature-name
  3. Commit your changes
  4. Push to your new branch: git push origin feature/feature-name
  5. Test code thoroughly
  6. Write unit tests
  7. Submit a pull request that includes a demonstration of your changes

Alternatively, feel free to open up [an issue](https://github.com/QuintonC/rn-progressive-image/issues).

Import structure to follow when contributing

// React
import { useEffect, useState, ... } from 'react';

// Packages
import PackageName from 'npm-package-name';

// Custom Components
import { MyComponent } from 'components'; 

// Props
import { PropTypeOne, PropTypeTwo } from './props';

// Style 
import style from './style';

// Utility Functions
import { performRequest } from 'utils';

// App Constants
import { APP_NAME } from 'constants/index';

Versions

This section details any changes that have been implemented across versions. It will be starting with version 3.0.0 as that is the most recent version.

3.0.0

  • Improvements
    • Added the ability to switch between two different types of progressive loading. Both are inferred via the types that you give the component. For the shimmer effect, do not supply a thumbnailSource prop and you will be using the types defined for the shimmer component and vice versa for the thumbnail based component.
    • Removed the unused placeholder component from the view hierarchy after the desired source has been loaded.
    • Generated typings with comments for better adoption and developer experience.
    • Wrote a custom ShimmerEffect component which is built on Reanimated with the usage of react-native-linear-gradient
    • Implemented new build features which streamline the building process and allow for better build outputs.
    • Added full test coverage (100% coverage confirmed via coverage folder).
    • Documentation improvements. Though this package is fairly simple, I want it to be one that continues to be easy to use, performant, and attractive to mobile developers and their users.
  • Breaking changes
    • Updated prop names (breaking change).
    • Removed the usage of React Native Animated API in favor of utilizing only Reanimated.
    • Removed the ability to use different configurations such as Spring.

Thoughts for further improvement

Caching

Some decisions have been made (for now), which are to omit the addition of caching. While I believe that caching is important, I am uncertain if I want to include it in this package by default. And having it be another prop that you must define to use the package seems sloppy. However, in the future, it is possible that a new component could be added that introduces caching (e.g. CachedProgressiveImage).

I've had some time to think about the best way to do this and I have two potential routes. One might include the use of react-native-async-storage, where the base64 of an image is retrieved and a cache method is implemented to store the base64 of the image. This would be an object that gets stored as stringified JSON:

{
    key: 'CACHE_KEY',
    type: 'Thumbnail' | 'Original Source',
    base64: Base64 data
}

The other method involves the use of rn-fetch-blob. This is used for retrieving the base64 of an image and has its own caching system. However, there are some nuances around the caching system of this package as it does not include any built-in cache flushing functionality.

Thoughts on how to implement this are as follows, but are not complete. To do this, we could add an additional package that would help us achieve the desired behavior. The thought is to potentially include something such as rn-fetch-blob. It has built-in caching functionality, however, there would

Blur view on Android.

While blurRadius is not natively supported on Android, it is possible to add a blurring view on top via other packages (or just through styling), which would allow Android users to also receive the same blur effect that makes this packaage so great. This may become an optional feature in the future so that it is not a breaking change.

License

Licensed under the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published