add loading spinner fallback (#202)

* add loading spinner fallback fixes #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* handle testing with progress spinners

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* apply fixes and improvements

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add example

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* bug fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* resolves #189

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
This commit is contained in:
Varun Gupta
2018-03-31 10:51:28 +05:30
committed by Jeffrey Warren
parent fba80bb151
commit 3b791ad58b
20 changed files with 5549 additions and 235 deletions

View File

@@ -31,17 +31,64 @@ Any module must follow this basic format:
```js
module.exports = function ModuleName(options,UI) {
options = options || {};
options.title = "Title of the Module";
UI.onSetup(options.step);
var output;
function draw(input,callback) {
UI.onDraw(options.step);
var output = /*do something with the input*/ ;
var output = function(input){
/* do something with the input */
return input;
}
this.output = output;
this.output = output(input);
options.step.output = output.src;
callback();
UI.onComplete(options.step);
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}
```
The default loading spinner can be optionally overriden with a custom progress object to draw progress on the CLI, following is a basic module format for the same
```js
module.exports = function ModuleName(options,UI) {
options = options || {};
options.title = "Title of the Module";
UI.onSetup(options.step);
var output;
function draw(input,callback,progressObj) {
/* If you wish to supply your own progress bar you need to override progressObj */
progressObj.stop() // Stop the current progress spinner
progressObj.overrideFlag = true; // Tell image sequencer that you will supply your own progressBar
/* Override the object and give your own progress Bar */
progressObj = /* Your own progress Object */
UI.onDraw(options.step);
var output = function(input){
/* do something with the input */
return input;
};
this.output = output();
options.step.output = output.src;
callback();
UI.onComplete(options.step);
@@ -89,6 +136,8 @@ When you have done your calculations and produced an image output, you are requi
to set `this.output` to an object similar to what the input object was, call
`callback()`, and set `options.step.output` equal to the output DataURL
* `progressObj` is an optional Object which handles the progress output of the step in the CLI, this is not consumed unless a custom progress bar needs to be drawn, for which this default spinner should be stopped with `progressObj.stop()` and image-sequencer is informed about the custom progress bar with `progressObj.overrideFlag = true;` following which this object can be overriden with custom progress object.
### UI Methods
The module is responsible for emitting various events for the UI to capture. There are

5328
dist/image-sequencer.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,7 @@
require('./src/ImageSequencer');
sequencer = ImageSequencer({ui: false});
var Spinner = require('ora')
var program = require('commander');
var readlineSync = require('readline-sync');
@@ -109,12 +110,19 @@ sequencer.loadImages(program.image,function(){
sequencer.addSteps(step, options);
});
var spinnerObj = Spinner('Your Image is being processed..').start();
// Run the sequencer.
sequencer.run(function(){
sequencer.run(spinnerObj,function(){
// Export all images or final image as binary files.
sequencer.exportBin(program.output,program.basic);
//check if spinner was not overriden stop it
if(!spinnerObj.overrideFlag) {
spinnerObj.succeed()
console.log(`\nDone!!`)
}
});

View File

@@ -32,6 +32,7 @@
"jsqr": "^0.2.2",
"lodash": "^4.17.5",
"ndarray-gaussian-filter": "^1.0.0",
"ora": "^2.0.0",
"pace": "0.0.4",
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",

View File

@@ -114,7 +114,13 @@ ImageSequencer = function ImageSequencer(options) {
return this;
}
function run(t_image,t_from) {
function run(spinnerObj,t_image,t_from) {
let progressObj;
if(arguments[0] != 'test'){
progressObj = spinnerObj
delete arguments['0']
}
var this_ = (this.name == "ImageSequencer")?this:this.sequencer;
var args = (this.name == "ImageSequencer")?[]:[this.images];
for (var arg in arguments) args.push(copy(arguments[arg]));
@@ -126,7 +132,7 @@ ImageSequencer = function ImageSequencer(options) {
var json_q = formatInput.call(this_,args,"r");
require('./Run')(this_, json_q, callback);
require('./Run')(this_, json_q, callback,progressObj);
return true;
}

View File

@@ -28,7 +28,7 @@ function ReplaceImage(ref,selector,steps,options) {
function make(url) {
tempSequencer.loadImage(url, function(){
this.addSteps(steps).run(function(out){
this.addSteps(steps).run({stop:function(){}},function(out){
img.src = out;
});
});

View File

@@ -1,4 +1,5 @@
function Run(ref, json_q, callback) {
function Run(ref, json_q, callback,progressObj) {
if(!progressObj) progressObj = {stop: function(){}}
function drawStep(drawarray, pos) {
if (pos == drawarray.length && drawarray[pos - 1] !== undefined) {
@@ -17,7 +18,7 @@ function Run(ref, json_q, callback) {
var input = ref.images[image].steps[i - 1].output;
ref.images[image].steps[i].draw(ref.copy(input), function onEachStep() {
drawStep(drawarray, ++pos);
});
},progressObj);
}
}

View File

@@ -11,7 +11,10 @@ module.exports = function Blur(options,UI){
UI.onSetup(options.step);
var output;
function draw(input,callback){
function draw(input,callback,progressObj){
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -11,7 +11,16 @@ module.exports = function Brightness(options,UI){
UI.onSetup(options.step);
var output;
function draw(input,callback){
function draw(input,callback,progressObj){
progressObj.stop(true);
progressObj.overrideFlag = true;
/*
In this case progress is handled by changepixel internally otherwise progressObj
needs to be overriden and used
For eg. progressObj = new SomeProgressModule()
*/
// Tell the UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -8,7 +8,10 @@ module.exports = function Dynamic(options,UI) {
var output;
// This function is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that the step is being drawn
UI.onDraw(options.step);

View File

@@ -1,5 +1,4 @@
const _ = require('lodash')
var pace = require('pace')
//define kernels for the sobel filter
const kernelx = [[-1,0,1],[-2,0,2],[-1,0,1]],
@@ -12,7 +11,6 @@ let weakEdgePixels = []
let notInUI
module.exports = exports = function(pixels,highThresholdRatio,lowThresholdRatio,inBrowser){
notInUI = !inBrowser
if(notInUI) var progressbar1 = pace((pixels.shape[0] * pixels.shape[1]))
for(var x = 0; x < pixels.shape[0]; x++) {
angles.push([])
mags.push([])
@@ -33,7 +31,6 @@ module.exports = exports = function(pixels,highThresholdRatio,lowThresholdRatio
mags.slice(-1)[0].push(pixel[3])
angles.slice(-1)[0].push(result.angle)
if(notInUI)progressbar1.op()
}
}
@@ -75,7 +72,6 @@ function changePixel(pixels,val,a,x,y){
function nonMaxSupress(pixels) {
angles = angles.map((arr)=>arr.map(convertToDegrees))
if(notInUI) var progressbar2 = pace((pixels.shape[0] * pixels.shape[1]))
for(let i = 1;i<pixels.shape[0]-1;i++){
for(let j=1;j<pixels.shape[1]-1;j++){
@@ -118,7 +114,6 @@ function nonMaxSupress(pixels) {
else
pixels.set(i,j,3,0)
if(notInUI) progressbar2.op()
}
}
return pixels
@@ -133,7 +128,6 @@ var findMaxInMatrix = arr => Math.max(...arr.map(el=>el.map(val=>!!val?val:0)).m
function doubleThreshold(pixels,highThresholdRatio,lowThresholdRatio){
const highThreshold = findMaxInMatrix(mags) * 0.2
const lowThreshold = highThreshold * lowThresholdRatio
if(notInUI) var progressbar3 = pace((pixels.shape[0] * pixels.shape[1]))
for(let i =0;i<pixels.shape[0];i++){
for(let j=0;j<pixels.shape[1];j++){
@@ -144,7 +138,6 @@ function doubleThreshold(pixels,highThresholdRatio,lowThresholdRatio){
?strongEdgePixels.push(pixelPos)
:weakEdgePixels.push(pixelPos)
:pixels.set(i,j,3,0)
if(notInUI) progressbar3.op()
}
}

View File

@@ -15,7 +15,10 @@ module.exports = function edgeDetect(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function GreenChannel(options,UI) {
UI.onSetup(options.step);
var output;
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -12,8 +12,10 @@ module.exports = function Invert(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function NdviRed(options,UI) {
var output;
// The function which is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that a step is being drawn.
UI.onDraw(options.step);

View File

@@ -11,7 +11,10 @@ module.exports = function Saturation(options,UI) {
UI.onSetup(options.step);
var output;
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell UI that a step is being drawn
UI.onDraw(options.step);

View File

@@ -8,7 +8,10 @@ module.exports = function SegmentedColormap(options,UI) {
var output;
// This function is called on every draw.
function draw(input,callback) {
function draw(input,callback,progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
// Tell the UI that the step is being drawn
UI.onDraw(options.step);

View File

@@ -32,8 +32,14 @@ module.exports = function PixelManipulation(image, options) {
// this could possibly be more efficient; see
// https://github.com/p-v-o-s/infragram-js/blob/master/public/infragram.js#L173-L181
if(!options.inBrowser)
var pace = require('pace')((pixels.shape[0] * pixels.shape[1]))
if(!options.inBrowser){
try{
var pace = require('pace')((pixels.shape[0] * pixels.shape[1]));
}
catch(e){
options.inBrowser = true;
}
}
for(var x = 0; x < pixels.shape[0]; x++) {
for(var y = 0; y < pixels.shape[1]; y++) {

View File

@@ -15,12 +15,13 @@ var sequencer = ImageSequencer({ ui: false });
var qr = require('./images/IS-QR.js');
var test_png = require('./images/test.png.js');
var test_gif = require('./images/test.gif.js');
var spinner = require('ora')('').start()
sequencer.loadImages(test_png);
sequencer.addSteps(['invert','invert']);
test("Preload", function(t) {
sequencer.run(function(){
sequencer.run(spinner,function(){
t.end();
});
});
@@ -51,7 +52,7 @@ test("Twice inverted image is identical to original image", function (t) {
test("Decode QR module works properly :: setup", function (t) {
sequencer.loadImage(qr,function(){
this.addSteps('decode-qr').run(function(){
this.addSteps('decode-qr').run(spinner.start(),function(){
t.end();
});
})
@@ -64,7 +65,7 @@ test("Decode QR module works properly :: teardown", function (t) {
test("PixelManipulation works for PNG images", function (t) {
sequencer.loadImages(test_png,function(){
this.addSteps('invert').run(function(out){
this.addSteps('invert').run(spinner.start(),function(out){
t.equal(1,1)
t.end();
});
@@ -73,9 +74,10 @@ test("PixelManipulation works for PNG images", function (t) {
test("PixelManipulation works for GIF images", function (t) {
sequencer.loadImages(test_gif,function(){
this.addSteps('invert').run(function(out){
this.addSteps('invert').run(spinner,function(out){
t.equal(1,1)
t.end();
});
});
});
spinner.stop(true)