Files
image-sequencer/src/ImageSequencer.js
2017-06-16 11:02:23 +05:30

376 lines
11 KiB
JavaScript

if (typeof window !== 'undefined') {window.$ = window.jQuery = require('jquery'); isBrowser = true}
else {window = global; var isBrowser = false}
ImageSequencer = function ImageSequencer(options) {
options = options || {};
options.inBrowser = options.inBrowser || isBrowser;
// if (options.inBrowser) options.ui = options.ui || require('./UserInterface');
options.sequencerCounter = 0;
function CImage(src) {
datauri = (options.inBrowser)?(src):require('urify')(src);
image = {
src: datauri,
format: datauri.split(':')[1].split(';')[0].split('/')[1]
}
return image;
}
function objTypeOf(object){
return Object.prototype.toString.call(object).split(" ")[1].slice(0,-1)
}
function log(color,msg) {
if(options.ui!="none") {
if(arguments.length==1) console.log(arguments[0]);
else if(arguments.length==2) console.log(color,msg);
}
}
function copy(a) {
if (!typeof(a) == "object") return a;
if (objTypeOf(a) == "Array") return a.slice();
if (objTypeOf(a) == "Object") return JSON.parse(JSON.stringify(a));
return a;
}
function makeArray(input) {
return (objTypeOf(input)=="Array")?input:[input];
}
var image,
steps = [],
modules = require('./Modules'),
images = {};
// if in browser, prompt for an image
// if (options.imageSelect || options.inBrowser) addStep('image-select');
// else if (options.imageUrl) loadImage(imageUrl);
function addStep(image, name, o_) {
log('\x1b[36m%s\x1b[0m','adding step \"' + name + '\" to \"' + image + '\".');
o = {};
o.id = options.sequencerCounter++; //Gives a Unique ID to each step
o.name = o_.name || name;
o.selector = o_.selector || 'ismod-' + name;
o.container = o_.container || options.selector;
o.image = image;
var module = modules[name](o);
images[image].steps.push(module);
function defaultSetupModule() {
if (options.ui && options.ui!="none") module.options.ui = options.ui({
selector: o.selector,
title: module.options.title,
id: o.id
});
}
if (module.hasOwnProperty('setup')) module.setup(); // add a default UI, unless the module has one specified
else defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
// tell the UI that a step has been added.
return true;
}
function addSteps(){
args = [];
json_q = {};
for (i in images) {
lastimage = i;
}
for (var arg in arguments) {
args.push(copy(arguments[arg]));
}
if (args.length == 1) {
if(objTypeOf(args[0]) == "Object") //addSteps(JSON)
json_q = arguments[0];
else { //addSteps(name) => addSteps([image],[name])
args.splice(0,0,[]);
for (img in images) args[0].push(img);
}
}
if (args.length == 2) {
//addSteps(name,o) => addSteps([image],[name],o)
if (objTypeOf(args[1])=="Object") {
args.splice(0,0,[]);
for (img in images) args[0].push(img);
}
else { //addSteps(image,name) => addSteps([image],[name],o)
args[2] = {};
}
}
if (args.length == 3) { //addSteps(image,name,o) => addSteps(JSON)
args[0] = makeArray(args[0]);
args[1] = makeArray(args[1]);
for (img in args[0]) {
json_q[args[0][img]] = [];
for (step in args[1]) {
json_q[args[0][img]].push({
name: args[1][step],
o: args[2]
});
}
}
}
for (i in json_q)
for (j in json_q[i])
addStep.call(this,i,json_q[i][j].name,json_q[i][j].o);
}
function removeStep(image,index) {
//remove the step from images[image].steps and redraw remaining images
if(index>0) {
log('\x1b[31m%s\x1b[0m',"Removing "+index+" from "+image);
images[image].steps.splice(index,1);
}
//tell the UI a step has been removed
}
function removeSteps(image,index) {
run = {};
this_ = this;
args = [];
for(var arg in arguments) args.push(copy(arguments[arg]));
json_q = {};
if(args.length==1) {
if (objTypeOf(args[0])=="Object") { //removeSteps(JSON)
json_q = args[0];
}
else { //removeSteps(index) => removeSteps([image],[index])
args.splice(0,0,[]);
for(img in images) args[0].push(img);
}
}
if(args.length==2) { //removeSteps(image,index) => removeSteps(JSON)
args[0] = makeArray(args[0]);
args[1] = makeArray(args[1]);
for(img in args[0]) {
json_q[args[0][img]] = args[1];
}
}
for (img in json_q) {
indices = json_q[img].sort(function(a,b){return b-a});
run[img] = indices[indices.length-1];
for (i in indices)
removeStep(img,indices[i]);
}
this.run(run)
}
function insertStep(image, index, name, o) {
log('\x1b[36m%s\x1b[0m','inserting step \"' + name + '\" to \"' + image + '\" at \"'+index+'\".');
o = o || {};
o.id = options.sequencerCounter++; //Gives a Unique ID to each step
o.name = o.name || name;
o.selector = o.selector || 'ismod-' + name;
o.container = o.container || options.selector;
o.image = image;
var module = modules[name](o);
images[image].steps.splice(index, 0, module);
function defaultSetupModule() {
if (options.ui && options.ui!="none") module.options.ui = options.ui({
selector: o.selector,
title: module.options.title,
id: o.id
});
}
if (module.hasOwnProperty('setup')) module.setup(); // add a default UI, unless the module has one specified
else defaultSetupModule.apply(module); // run default setup() in scope of module (is this right?)
// tell the UI that a step has been inserted.
return true;
}
function insertSteps(image, index, name, o) {
run = {};
this_ = this;
if (arguments.length==2 || arguments.length==3) {
if (typeof(arguments[0])=="number") {
if (typeof(arguments[1])=="string" || objTypeOf(arguments[1])=="Array") {
var p = arguments[0];
var m = arguments[1];
var o = arguments[2];
arguments = [];
arguments[0] = {};
for (image in this_.images) {
arguments[0][image] = {
index: p,
name: m,
o: o
};
}
}
} // end if argument is string
}
if(arguments.length==4 || arguments.length==3) {
o = o || {};
size = this_.images[image].steps.length;
index = (index==size)?index:index%size;
if (index<0) index += size+1;
insertStep(image,index,name, o);
run[image] = index;
}
else if(arguments.length==1) {
if (objTypeOf(arguments[0])=='Object') {
for (img in arguments[0]) {
var details = arguments[0][img];
if (objTypeOf(details) == "Object") {
size = this_.images[img].steps.length;
details.index = (details.index==size)?details.index:details.index%size;
if (details.index<0) details.index += size+1;
insertStep(img,details.index,details.name,details.o);
run[img]=details.index;
}
else if (objTypeOf(details) == "Array") {
details = details.sort(function(a,b){return b.index-a.index});
run[img] = details[details.length-1].index;
for (i in details) {
size = this_.images[img].steps.length;
details[i].index = (details[i].index==size)?details[i].index:details[i].index%size;
if (details[i].index<0) details[i].index += size+1;
insertStep(img,details[i].index,details[i].name,details[i].o);
}
}
}
} // end if argument is object
}
this.run(run)
}
function run(t_image,t_from) {
log('\x1b[32m%s\x1b[0m',"Running the Sequencer!");
this_ = this;
runimg = {};
json_q = {};
args = [];
for (var arg in arguments) args.push(copy(arguments[arg]));
for (var arg in args)
if(objTypeOf(args[arg]) == "Function")
var callback = args.splice(arg,1)[0];
for (image in images) {
runimg[image] = 0;
}
function drawStep(drawarray,pos) {
if(pos==drawarray.length) if(objTypeOf(callback)=='Function') callback();
if(pos>=drawarray.length) return true;
image = drawarray[pos].image;
i = drawarray[pos].i;
images[image].steps[i].draw.call(this_,function(){
drawStep(drawarray,++pos);
});
}
function drawSteps(json_q) {
drawarray = [];
for (image in json_q) {
no_steps = images[image].steps.length;
init = json_q[image];
for(i = 0; i < no_steps-init; i++) {
drawarray.push({image: image,i: init+i});
}
}
drawStep(drawarray,0);
}
function filter(json_q){
for (image in json_q) {
prevstep = images[image].steps[json_q[image]-1];
while (typeof(prevstep) == "undefined" || typeof(prevstep.output) == "undefined") {
prevstep = images[image].steps[(--json_q[image]) - 1];
}
}
return json_q;
}
if (arguments.length == 0) {
for (image in images)
json_q[image] = 1;
}
else if (arguments.length == 1) {
if (typeof(arguments[0]) == "string")
json_q[arguments[0]] = 1;
else if (typeof(arguments[0]) == "number")
for (image in images)
json_q[image] = arguments[0];
else if (objTypeOf(arguments[0]) == "Array")
for (image in arguments[0])
json_q[arguments[0][image]] = 1;
else if (objTypeOf(arguments[0]) == "Object")
json_q = arguments[0];
}
else if (arguments.length == 2) {
json_q[t_image] = t_from;
}
json_q = filter(json_q);
drawSteps(json_q);
}
function loadImage(name, src, callback) {
image = {
src: src,
steps: [{
options: {
id: options.sequencerCounter++,
name: "load-image",
title: "Load Image"
},
draw: function() {
if(arguments.length==1){
this.outputData = CImage(arguments[0]);
return true;
}
return false;
},
output: CImage(src)
}]
};
images[name] = image;
if (callback) callback();
}
function loadImages() {
if (arguments.length == 1) {
for (image in arguments[0])
loadImage(image,arguments[0][image]);
}
else if (arguments.length == 2) {
if (objTypeOf(arguments[1]) == "Function") {
for (image in arguments[0]) {
loadImage(image,arguments[0][image])
}
arguments[1]();
}
else {
loadImage(arguments[0],arguments[1])
}
}
else if (arguments.length == 3) {
loadImage(arguments[0],arguments[1],arguments[2])
}
}
return {
options: options,
loadImages: loadImages,
addSteps: addSteps,
removeSteps: removeSteps,
insertSteps: insertSteps,
run: run,
modules: modules,
images: images,
ui: options.ui
}
}
module.exports = ImageSequencer;