I did something similar, but for ionic / angular as a directive, as I said I used plugin file .
I'll leave the code as a template for how I did it.
angular.module('imagefusion', ['ionic', 'ngCordova.plugins.file'])
.directive('imageFusion', function($compile, $timeout, $cordovaFile, $cordovaFileTransfer) {
return {
restrict: 'E',
//replace: true,
//template: '<div></div>',
//transclude: true,
scope: {
config: '=',
},
link: function(scope, $image, attrs){
var debug = true;
var localPath = 'images/'+scope.config.name;
var $spinner = null;
var ghost = angular.element(new Image());
function changeSource(src){
ghost.attr('src', src);
if($spinner){
$spinner.remove();
}
}
function displayLoader(){
$spinner = angular.element($compile('<ion-spinner></ion-spinner>')(scope));
$image.append($spinner);
var wrapperSize = {width:$image[0].offsetWidth, height:$image[0].offsetHeight};
//var spinnerSize = {width:$spinner[0].offsetHeight, height:$spinner[0].offsetHeight};
var spinnerSize = {width:28, height:28};
$spinner.css('position', 'absolute');
$spinner.css('left', ((wrapperSize.width-spinnerSize.width)/2)+'px');
$spinner.css('top', ((wrapperSize.height-spinnerSize.height)/2)+'px');
}
function formatSize(size){
var s = null;
if(size){
if( typeof size=='number' || (typeof size=='string' && size.indexOf('%')==-1) ){
s = size+'px';
}else{
s = size;
}
}
return s;
}
var size = null;
if(scope.config.size){
size = scope.config.size;
}
// naturalHeight
// console.log(cordova.file.applicationStorageDirectory);
// file:///data/data/br.com.nibler.doctorphotosolution/
if(size){
var w = formatSize(size.width);
$image.css('width', w);
$image.css('height', w);
}
ghost.on('load', function(event){
var target = event.target;
if(!size.height){
var height;
var image = $image[0];
if(attrs.original!==undefined){
// (original height / original width) x new width = new height
var originalWidth = ghost[0].naturalWidth;
var originalHeight = ghost[0].naturalHeight;
var currentWidth = image.clientWidth;
//var currentHeight = image.clientHeight;
height = (originalHeight/originalWidth)*currentWidth;
}else{
height = image.clientWidth;
}
$image.css('height', formatSize(height));
}
$image.css('background-image', 'url('+target.src+')');
});
$image.on('error', function(){
if(debug){
console.log('Error');
}
});
$image.css('background-position', 'center center');
$image.css('background-repeat', 'no-repeat');
$image.css('background-size', 'cover');
$image.css('display', 'inline-block');
if(attrs.relative!==undefined)
$image.css('position', 'relative');
$timeout(function(){
displayLoader();
//console.log(localPath);
//console.log(cordova.file);
cordova.file;
//debugger;
var storageDir = null;
if(ionic.Platform.isIOS()){
storageDir = cordova.file.documentsDirectory;
}else{
storageDir = cordova.file.applicationStorageDirectory;
}
var fullLocalPath = storageDir+localPath;
if(!scope.config.name || scope.config.url.indexOf('http')==-1){
changeSource(scope.config.placeholder);
}else{
$cordovaFile.checkFile(storageDir, localPath).then(
function(success){
changeSource(fullLocalPath);
if(debug){
console.log('['+scope.config.name+'] Fetched from Disk');
}
},
function(err){
if(debug){
console.log('['+scope.config.name+'] Not exists, downloading....');
}
$cordovaFileTransfer.download(scope.config.url, fullLocalPath).then(
function(resp){
changeSource(fullLocalPath);
if(debug){
console.log('['+scope.config.name+'] Downloaded');
}
},
function(err){
if(debug){
console.log('['+scope.config.name+'] Download error');
console.log(err);
}
}
);
}
);
}
});
}
};
});