mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-15 04:40:02 +01:00
376 lines
11 KiB
JavaScript
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;
|