zyra / ionic-image-loader

Ionic 2+ Component that loads images in a background thread and caches them for later use
MIT License
436 stars 137 forks source link
ionic

npm npm npm

Ionic Image Loader

Ionic Module that loads images in a background thread and caches them for later use. Uses HttpClient from Angular 4+, and cordova-plugin-file via ionic-native wrappers.

Features

Gif

View our example project here: https://github.com/zyramedia/ionic-image-loader-example

Installation

1. Install the NPM Package

npm install --save ionic-image-loader

2. Install Required Plugins

npm i --save @ionic-native/file
ionic cordova plugin add cordova-plugin-file

3. Import IonicImageLoader module

Add IonicImageLoader.forRoot() in your app's root module

import { IonicImageLoader } from 'ionic-image-loader';

// import the module
@NgModule({
  ...
  imports: [
    IonicImageLoader.forRoot()
  ]
})
export class AppModule {}

Then add IonicImageLoader in your child/shared module(s)

import { IonicImageLoader } from 'ionic-image-loader';

@NgModule({
  ...
  imports: [
    IonicImageLoader
  ]
})
export class SharedModule {}

Usage

Basic Usage

This HTML code demonstrates basic usage of this module:

<img-loader src="https://path.to/my/image.jpg"></img-loader>

By default, the module sets the image as the background of the <img-loader> element. If you want the module to use the image as an <img> tag inside the <img-loader> element, just add useImg attribute as shown below:

<img-loader src="https://path.to/my/image.jpg" useImg></img-loader>

You can also listen to the load event to be notified when the image has been loaded:

<img-loader src="https://github.com/zyra/ionic-image-loader/raw/master/path/to/image" (load)="onImageLoad($event)></img-loader>
import { ImgLoaderComponent } from 'ionic-image-loader';

...

onImageLoad(imgLoader: ImgLoaderComponent) {
  // do something with the loader
}

Advanced Usage

The <img-loader> component takes many attributes that allows you to customize the image. You can use the following table as a reference:

Attribute Name Type Description Default Value
src string The image URL N/A
fallbackUrl string Fallback image url to load in case the original image fails to load N/A
spinner boolean Show a spinner while the image loads true
useImg boolean Use <img> tag to display the image in false
width string The width of the image. This is ignored if useImg is set to true. 100%
height string The height of the image. This is ignored if useImg is set to true. 100%
display string Sets the display CSS property of the <img-loader> element. This is ignored if useImg is set to true. block
backgroundSize string Sets the background-size CSS property of the <img-loader> element. This is ignored if useImg is set to true. contain
backgroundRepeat string Sets the background-repeat CSS property of the <img-loader> element. This is ignored if useImg is set to true. no-repeat
fallbackAsPlaceholder boolean Use fallback as a placeholder until the image loads. false
imgAttributes ImageAttribute[] An array of ImageAttribute objects (element, value). If useImg == true, this array will be iterated and each object added as an attribute to the generated <img> HTML element. []]

Note: The default values can be changed using the global configuration feature.

Quirks

In some cases, images won't load on the first time, the culprit seems to be @ionic-native/file or cordova-plugin-file in its writeFile function not calling resolve or reject.

In the meantime we find a solution, here's a quick workaround:

In ./src/index.html move your polyfill.jsinclude above cordova.js

    <!-- The polyfills js is generated during the build process -->
    <script src="https://github.com/zyra/ionic-image-loader/raw/master/build/polyfills.js"></script>

    <!-- cordova.js required for cordova apps (remove if not needed) -->
    <script src="https://github.com/zyra/ionic-image-loader/raw/master/cordova.js"></script>

Global Configuration

This is optional but it is helpful if you wish to set the global configuration for all of your <img-loader> instances. To configure the module, inject the ImageLoaderConfig provider in your app's main component.

import { ImageLoaderConfig } from 'ionic-image-loader';
@Component({
...
})
export class MyMainAppComponent {

  constructor(
    private imageLoaderConfig: ImageLoaderConfig // optional, if you wish to configure the service 
  ){

    // disable spinners by default, you can add [spinner]="true" to a specific component instance later on to override this
    imageLoaderConfig.enableSpinner(false);

    // set the maximum concurrent connections to 10
    imageLoaderConfig.setConcurrency(10);
  }

}

Below are all the methods that the config provider has:

enableDebugMode()

Enables debug mode to receive console logs, errors, warnings.

Example:

// enable debug mode to get console errors/warnings/logs
// this could be useful while trying to debug issues with the component
this.imageLoaderConfig.enableDebugMode();

enableSpinner(enable: boolean)

Sets the cache directory name. Defaults to 'image-loader-cache'. Defaults to true.

Example:

this.imageLoaderConfig.enableSpinner(false); // disable spinner by default

setHeight(height: string)

Set default height for images that are not using tag. Defaults to 100%.


setWidth(width: string)

Set default width for images that are not using tag. Defaults to 100%.

Example:

this.imageLoaderConfig.setWidth('500px'); // set default width to 500px

setDisplay(display: string)

Enable display mode for images that are not using tag. Defaults to block.

Example:

this.imageLoaderConfig.setDisplay('inline-block');

useImageTag(use: boolean)

Use tag by default.

Example:

this.imageLoaderConfig.useImageTag(true); // use `<img>` tag by default

setBackgroundSize(backgroundSize: string)

Set default background size for images that are not using tag. Defaults to contain.

Example:

this.imageLoaderConfig.setBackgroundSize('cover');

setBackgroundRepeat(backgroundRepeat: string)

Set background repeat for images that are not using tag. Defaults to no-repeat.

Example:

this.imageLoaderConfig.setBackgroundRepeat('repeat-x');

setFallbackUrl(fallbackUrl: string)

Set fallback URL to use when image src is undefined or did not resolve. This image will not be cached. This should ideally be a locally saved image.

Example:

this.imageLoaderConfig.setFallbackUrl('assets/fallback.png'); // if images fail to load, display this image instead

setCacheDirectoryName(directoryName: string)

Set a custom directory name to store the cached images in. The cache directory by default is named image-loader-cache.

Example:

this.imageLoaderConfig.setCacheDirectoryName('my-custom-cache-directory-name');

setConcurrency(concurrency: number)

Set the maximum number of concurrent connections. Cached images will be loaded instantly, this limit is only for new images.

Example:

this.imageLoaderConfig.setConcurrency(5); // 5 concurrent connections

setMaximumCacheSize(cacheSize: number)

Sets the maximum cache size in bytes.

Example:

this.imageLoaderConfig.setMaximumCacheSize(20 * 1024 * 1024); // set max size to 20MB

setMaximumCacheAge(cacheAge: number)

Sets the maximum allowed cache age in milliseconds

Example:

this.imageLoaderConfig.setMaximumCacheAge(7 * 24 * 60 * 60 * 1000); // 7 days

setImageReturnType(imageReturnType: string)

Set the return type of cached images. By default this option is set to 'uri', which will return the native file URL. If you want to get a base64-encoded representation of the file set the return type to 'base64'.

Example:

this.imageLoaderConfig.setImageReturnType('base64');

enableFallbackAsPlaceholder(enable: boolean)

Enable/Disable the fallback image as placeholder instead of the spinner. Defaults to false.

Example:

this.imageLoaderConfig.enableFallbackAsPlaceholder(true);

setHttpHeaders(headers: HttpHeaders)

Set headers for HttpClient to use.

Example:

const headers = new HttpHeaders()
                  .set("Authorization", "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==");
this.imageLoaderConfig.setHttpHeaders(headers);

setFileNameCachedWithExtension(enable: boolean)

Enable/Disable the save filename of cached images with extension. Defaults to false.

Example:

this.imageLoaderConfig.setFileNameCachedWithExtension(true);

setFallbackFileNameCachedExtension(extension: string)

Sometime url missing extension, in this case you can set fallback as default extension. Defaults to '.jpg'

Example:

this.imageLoaderConfig.setFallbackFileNameCachedExtension('.png');

Preloading images

import { ImageLoader } from 'ionic-image-loader';

class MyComponent {

  constructor(imageLoader: ImageLoader) {
    imageLoader.preload('http://path.to/image.jpg');
  }

}

Clearing the cache


import { ImageLoader } from 'ionic-image-loader';

@Component(...)
class MyComponent {

  constructor(imageLoader: ImageLoader) {
    imageLoader.clearCache();
  }

}

Clearing single image cache


import { ImageLoader } from 'ionic-image-loader';

@Component(...)
class MyComponent {

  constructor(imageLoader: ImageLoader) {
    imageLoader.clearImageCache('http://path.to/image.jpeg');
  }

}

Passing HTML / CSS Attributes to a generated image

When using ImageLoader to generate an <img> element it may be desirable for the generated element to include additional attributes to provide styling or interaction qualities. The optional imgAttributes value can be used to provide such additional attributes which will be included in the generated <img> element in the DOM.

Usage:

  1. Include the ImageAttribute model in your .ts

    import { ImageAttribute } from 'ionic-image-loader'
  2. Generate an array of ImageAttribute objects

    const imageAttributes: ImageAttribute[] = [];
    imageAttributes.push({
    element: 'class',
    value: 'circle-photo'
    })
  3. Include the imgAttributes element in the img-loader element of your HTML

    <img-loader [src]="..." useImg [imgAttributes]="imageAttributes"> </img-loader>
  4. The generated <img> tag will be rendered with the specified attributes

    <img src="https://github.com/zyra/ionic-image-loader/raw/master/.." class="circle-photo">



Contribution

Support this project

If you find this project useful, please star the repo to let people know that it's reliable. Also, share it with friends and colleagues that might find this useful as well. Thank you :smile: