From 5465636ca5e70ad5a99a3122eecdde165101e0f8 Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 05:32:02 +0000 Subject: [PATCH 1/8] * Safer image loading: wrong or missing imgage sources are replaced with a placeholder --- HISTORY.md | 18 ++++++++++++++++++ component.json | 2 +- index.js | 7 +++++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100755 HISTORY.md diff --git a/HISTORY.md b/HISTORY.md new file mode 100755 index 0000000..9e2679d --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,18 @@ +# Release history + +## v0.2.2 + +- Safer image loading: images with a wrong or missing source get a placeholder image (when used + in a DOM context a missing image is not a big deal, but when trying to draw it on a canvas it crashes javascript) + +## v0.2.1 + +- Switch to wizcorp/util + +## v0.2.0 + +- Lowercase name + +## v0.1.0 + +- First version \ No newline at end of file diff --git a/component.json b/component.json index 242ee3e..e692fac 100755 --- a/component.json +++ b/component.json @@ -1,6 +1,6 @@ { "name": "image-preloader", - "version": "0.2.1", + "version": "0.2.2", "description": "An image pre-loader component", "dependencies": { "Wizcorp/eventemitter": "*", diff --git a/index.js b/index.js index c64b064..78c555d 100755 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ var EventEmitter = require('EventEmitter'); var defaultTtl = 3000; var defaultMaxParallel = 5; +var placeholderImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII='; function ImagePreloader() { this.urlList = {}; @@ -15,6 +16,7 @@ function ImagePreloader() { this.ttl = defaultTtl; this.maxParallel = defaultMaxParallel; + this.placeholderImg = placeholderImg; } inherit(ImagePreloader, EventEmitter); @@ -40,7 +42,7 @@ function loadNext() { var key = this._keyMap[done]; var img = this.imgList[key] = new Image(); - var url = this.urlList[key]; + var url = this.urlList[key] || this.placeholderImg; function onLoad() { callback(); @@ -70,7 +72,8 @@ function loadNext() { var toLoad = that._keyMap.length; if (!processed) { if (err) { - that.imgList[key] = null; + that.imgList[key] = new Image(); + that.imgList[key].src = that.placeholderImg; that.error++; that.emit('error', {loaded: that.loaded, error: that.error, total: toLoad, errorMsg: err}); } else { From 0f55a97b8b3fd07792665a18b24c95875e217472 Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:31:47 +0000 Subject: [PATCH 2/8] * Failed images key list is now returned to the final callback and improved documentation --- README.md | 102 +++++++++++++++++++++++++++++++++++------------------- index.js | 32 ++++++++++++----- 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index d22aefe..a9780ba 100755 --- a/README.md +++ b/README.md @@ -1,47 +1,79 @@ -image-preloader +ImagePreloader ============== -Preload your images with the ImagePreloader +ImagePreloader is an image preloader particularly designed to work with canvas. -### Usage example +# Overview + +Basically, you provide an object with a list of urls and you get back another object where the urls have been replaced with the corresponding images, ready to be drawn somewhere. + +Simple example: ```javascript var imagePreloader = new ImagePreloader(); -var urlList = { - whatever1: 'http://domain/path/to/image1.png', - whatever2: 'http://domain/path/to/image2.png', - whatever3: 'http://domain/path/to/image3.png', - whatever4: 'http://domain/path/to/image4.png', - whatever5: 'http://domain/path/to/image5.png', - whatever6: 'http://domain/path/to/image6.png' +var assets = { + sprite: 'http://domain.whatever.com/assets/sprite1.png', + background: 'http://domain.whatever.com/assets/bg.png', + button: 'http://domain.whatever.com/assets/btn.png' }; -imagePreloader.add(urlList); +imagePreloader.add(assets); +imagePreloader.on('finished', function (data) { + // the images are in data.images, matching the + // provided object structure, so you can simply do: + assets = data.images; + // and now you have image objects instead of strings, you can for example: + whateverContext.drawImage(assets.sprite, 0, 0); +}); +imagePreloader.start(); +``` -var stepCb = function (data) { - var loaded = data.loaded; - var error = data.error; - var total = data.total; - console.log('loadInProgress: ' + (loaded + error) + '/' + total); -}; +# In depth -var finalCb = function (data) { - var loaded = data.loaded; - var error = data.error; - var total = data.total; - var images = data.images; - console.log('All (' + total + ') pictures have been processed. ' + loaded + ' have been loaded and ' + error + ' have not.'); - if (images.whatever1) { - document.body.appendChild(images.whatever1); - } -}; +## .start() parameters -imagePreloader.on('error', stepCb); -imagePreloader.on('loaded', stepCb); -imagePreloader.on('finished', finalCb); +You can provide completely optional parameters to the start method: -var notMandatory = { - ttl: 5000, - maxParallel: 3 -} -imagePreloader.start(notMandatory); +- `ttl`: the maximum time you want to wait on one image before having the onerror triggered (ms). Default value is 3000ms. +- `maxParallel`: the maximum number of images you want to allow to be loaded in parallel (if you want to avoid something else to be blocked). Default value is 5. +- `placeholderImgData`: what data image you want for failed images. Default is an empty 1x1 transparent png. + +Example: +```javascript +imagePreloader.start({ + ttl: 10000, + maxParallel: 2, + placeholderImgData: 'data:image/png;base64,iVBORw0KGgo....' +}); ``` + +## events + +You can listen for: + +### finished + +Sent back object contains: + +- `loaded`: number of images successfully loaded +- `error`: number of images where loading failed +- `errKeys`: array containing the list of keys who failed +- `images`: object, matching the original urls object structure, where strings have been replaced by images objects + +### loaded + +Called every-time a picture is successfully loaded, you can use it for progress bars. Sent back object contains: + +- `currentKey`: which key have been loaded +- `loaded`: number of images successfully loaded so far +- `error`: number of failed images so far +- `total`: total number of images we are processing + +### error + +Called every-time a picture fails to load, you can use it for progress bars. Sent back object contains: + +- `currentKey`: which key failed +- `loaded`: number of images successfully loaded so far +- `error`: number of failed images so far +- `total`: total number of images we are processing +- errorMsg: string error message \ No newline at end of file diff --git a/index.js b/index.js index 78c555d..27f291f 100755 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ var EventEmitter = require('EventEmitter'); var defaultTtl = 3000; var defaultMaxParallel = 5; -var placeholderImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII='; +var emptyImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII='; function ImagePreloader() { this.urlList = {}; @@ -13,10 +13,11 @@ function ImagePreloader() { this.loading = 0; this.loaded = 0; this.error = 0; + this.errKeys = []; this.ttl = defaultTtl; this.maxParallel = defaultMaxParallel; - this.placeholderImg = placeholderImg; + this.placeholderImgData = emptyImg; } inherit(ImagePreloader, EventEmitter); @@ -42,7 +43,7 @@ function loadNext() { var key = this._keyMap[done]; var img = this.imgList[key] = new Image(); - var url = this.urlList[key] || this.placeholderImg; + var url = this.urlList[key]; function onLoad() { callback(); @@ -73,18 +74,19 @@ function loadNext() { if (!processed) { if (err) { that.imgList[key] = new Image(); - that.imgList[key].src = that.placeholderImg; + that.imgList[key].src = that.placeholderImgData; that.error++; - that.emit('error', {loaded: that.loaded, error: that.error, total: toLoad, errorMsg: err}); + that.errKeys.push(key); + that.emit('error', {loaded: that.loaded, error: that.error, total: toLoad, errorMsg: err, currentKey: key}); } else { that.loaded++; - that.emit('loaded', {loaded: that.loaded, error: that.error, total: toLoad}); + that.emit('loaded', {loaded: that.loaded, error: that.error, total: toLoad, currentKey: key}); } that.loading--; processed = true; } if (that.loaded + that.error === toLoad) { - that.emit('finished', {loaded: that.loaded, error: that.error, total: toLoad, images: that.imgList}, 'test OKKKKKK'); + that.emit('finished', {loaded: that.loaded, error: that.error, errKeys: that.errKeys, total: toLoad, images: that.imgList}); } else { loadNext.call(that); } @@ -95,7 +97,12 @@ function loadNext() { img.addEventListener('abort', onError, false); ttlTimeout = setTimeout(onTimeout, this.ttl); - img.src = url; + if (url) { + img.src = url; + } else { + onError(); + } + loadNext.call(this); } @@ -122,12 +129,19 @@ ImagePreloader.prototype.start = function (options) { this.maxParallel = defaultMaxParallel; } + if (options.placeholderImgData !== undefined) { + this.placeholderImgData = options.placeholderImgData; + } else { + this.placeholderImgData = emptyImg; + } + this.imgList = {}; this._keyMap = Object.keys(this.urlList); this.loading = 0; this.loaded = 0; this.error = 0; + this.errKeys = []; loadNext.call(this); -}; +}; \ No newline at end of file From d46c4527531f923cef77e9a8f2a77289026c7a0a Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:34:15 +0000 Subject: [PATCH 3/8] * cosmetics --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9780ba..408792f 100755 --- a/README.md +++ b/README.md @@ -76,4 +76,4 @@ Called every-time a picture fails to load, you can use it for progress bars. Sen - `loaded`: number of images successfully loaded so far - `error`: number of failed images so far - `total`: total number of images we are processing -- errorMsg: string error message \ No newline at end of file +- `errorMsg`: string error message \ No newline at end of file From b6c81a0c57ffa25d8487f0b20bb673f404155afb Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:37:31 +0000 Subject: [PATCH 4/8] * cosmetics --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 408792f..8267797 100755 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ imagePreloader.on('finished', function (data) { // the images are in data.images, matching the // provided object structure, so you can simply do: assets = data.images; - // and now you have image objects instead of strings, you can for example: + // and now you have image objects instead of strings, you can do for example: whateverContext.drawImage(assets.sprite, 0, 0); }); imagePreloader.start(); From 45273017be1eb500b2de4b77fd82a6ac415c9836 Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:41:55 +0000 Subject: [PATCH 5/8] * cosmetics --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8267797..256c63f 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -ImagePreloader +image-preloader ============== -ImagePreloader is an image preloader particularly designed to work with canvas. +image-preloader is an image preloader particularly designed to work with canvas. # Overview From b22bf458ea94afc4e79ed24a2b74a711e514da6f Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:47:10 +0000 Subject: [PATCH 6/8] * wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 256c63f..4e92c8c 100755 --- a/README.md +++ b/README.md @@ -75,5 +75,5 @@ Called every-time a picture fails to load, you can use it for progress bars. Sen - `currentKey`: which key failed - `loaded`: number of images successfully loaded so far - `error`: number of failed images so far -- `total`: total number of images we are processing +- `total`: total number of processed images - `errorMsg`: string error message \ No newline at end of file From 3bb66eef4f465d4a95d725021d9a3e770cc3aeb4 Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:48:49 +0000 Subject: [PATCH 7/8] * wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e92c8c..256c63f 100755 --- a/README.md +++ b/README.md @@ -75,5 +75,5 @@ Called every-time a picture fails to load, you can use it for progress bars. Sen - `currentKey`: which key failed - `loaded`: number of images successfully loaded so far - `error`: number of failed images so far -- `total`: total number of processed images +- `total`: total number of images we are processing - `errorMsg`: string error message \ No newline at end of file From 01beacdc0f5db2b14e761654f84359b928bafa49 Mon Sep 17 00:00:00 2001 From: tbrebant Date: Fri, 9 May 2014 09:53:13 +0000 Subject: [PATCH 8/8] * Removed unnecessary line --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 27f291f..d661d67 100755 --- a/index.js +++ b/index.js @@ -73,7 +73,6 @@ function loadNext() { var toLoad = that._keyMap.length; if (!processed) { if (err) { - that.imgList[key] = new Image(); that.imgList[key].src = that.placeholderImgData; that.error++; that.errKeys.push(key);