';
+ }
+ function selectNewStepUi() {
+ var m = $("#insertStep select").val();
+ $("#insertStep .info").html(_sequencer.modulesInfo(m).description);
+ $("#insertStep #add-step-btn").prop("disabled", false);
+ }
+ insertStep = function(id) {
+ var modulesInfo = _sequencer.modulesInfo();
+ var parser = new DOMParser();
+ var addStepUI = stepUI();
+ addStepUI = parser.parseFromString(addStepUI, "text/html").querySelector("div")
+ step.ui
+ .querySelector("div.step")
+ .insertAdjacentElement('afterend',
+ addStepUI
+ );
+ var insertStepSelect = $("#insertStep select");
+ insertStepSelect.html("");
+ // Add modules to the insertStep dropdown
+ for (var m in modulesInfo) {
+ if (modulesInfo[m] !== undefined)
+ insertStepSelect.append(
+ '"
+ );
+ }
+
+ $('#insertStep #add-step-btn').prop('disabled', true);
+
+ insertStepSelect.append('');
+ $('#insertStep .radio-group .radio').on("click", function() {
+ $(this).parent().find('.radio').removeClass('selected');
+ $(this).addClass('selected');
+ newStep = $(this).attr('data-value');
+ insertStepSelect.val(newStep);
+ selectNewStepUi();
+ insert(id);
+ $(this).removeClass('selected');
+ });
+ $(step.ui.querySelector("#insertStep select")).on('change', selectNewStepUi);
+ $(step.ui.querySelector("#insertStep #add-step-btn")).on('click', function() { insert(id) });
+ }
+
+ function insert(id) {
+
+ options = options || {};
+ var insertStepSelect = $("#insertStep select");
+ if (insertStepSelect.val() == "none") return;
+
+ var newStepName = insertStepSelect.val()
+ $('div .insertDiv').remove();
+ var sequenceLength = 1;
+ if (sequencer.sequences[newStepName]) {
+ sequenceLength = sequencer.sequences[newStepName].length;
+ } else if (sequencer.modules[newStepName][1]["length"]) {
+ sequenceLength = sequencer.modules[newStepName][1]["length"];
+ }
+ _sequencer
+ .insertSteps(id + 1, newStepName).run({ index: id });
+
+ // add to URL hash too
+ setUrlHashParameter("steps", _sequencer.toString());
+
+ }
+ return {
+ insertStep
+ }
+}
+$(document).ready(function($){
+ $(function(){
+ $(window).scroll(function(){
+ if ($(this).scrollTop() > 100){
+ $('.move-up').fadeIn();
+ } else {
+ $('.move-up').fadeOut();
+ }
+ });
+ $('.move-up button').click(function(){
+ $('body,html').animate({
+ scrollTop: 0
+ }, 800);
+ return false;
+ });
+ });
+});
+
+const staticCacheName = 'image-sequencer-static-v3';
+
+self.addEventListener('install', event => {
+ console.log('Attempting to install service worker');
+});
+
+self.addEventListener('activate', function(e) {
+ console.log('[ServiceWorker] Activate');
+ e.waitUntil(
+ caches.keys().then(function(cacheNames) {
+ return Promise.all(
+ cacheNames.filter(function(cacheName){
+ return cacheName.startsWith('image-sequencer-') &&
+ cacheName != staticCacheName;
+ }).map(function(cacheName){
+ return caches.delete(cacheName);
+ })
+ );
+ })
+ );
+});
+
+self.addEventListener('fetch', function(event) {
+ event.respondWith(
+ caches.open(staticCacheName).then(function(cache) {
+ return cache.match(event.request).then(function (response) {
+ return response || fetch(event.request).then(function(response) {
+ if(event.request.method == "GET")
+ cache.put(event.request, response.clone());
+ return response;
+ });
+ });
+ })
+ );
+});
+function getUrlHashParameter(param) {
+
+ var params = getUrlHashParameters();
+ return params[param];
+
+}
+
+function getUrlHashParameters() {
+
+ var sPageURL = window.location.hash;
+ if (sPageURL) sPageURL = sPageURL.split('#')[1];
+ var pairs = sPageURL.split('&');
+ var object = {};
+ pairs.forEach(function(pair, i) {
+ pair = pair.split('=');
+ if (pair[0] != '') object[pair[0]] = pair[1];
+ });
+ return object;
+}
+
+// accepts an object like { paramName: value, paramName1: value }
+// and transforms to: url.com#paramName=value¶mName1=value
+function setUrlHashParameters(params) {
+
+ var keys = Object.keys(params);
+ var values = Object.values(params);
+ var pairs = [];
+ keys.forEach(function(key, i) {
+ if (key != '') pairs.push(keys[i] + '=' + values[i]);
+ });
+ var hash = pairs.join('&');
+ window.location.hash = hash;
+
+}
+
+function setUrlHashParameter(param, value) {
+
+ var params = getUrlHashParameters();
+ params[param] = value;
+ setUrlHashParameters(params);
+
+}
+
+window.onload = function() {
+ function generatePreview(previewStepName, customValues, path) {
+ var previewSequencer = ImageSequencer();
+
+ function insertPreview(src) {
+ var img = document.createElement('img');
+ img.classList.add('img-thumbnail')
+ img.classList.add('no-border');
+ img.src = src;
+ $(img).css("max-width", "200%");
+ $(img).css("transform", "translateX(-20%)");
+ var stepDiv = $('#addStep .row').find('div').each(function() {
+ if ($(this).find('div').attr('data-value') === previewStepName) {
+ $(this).find('div').append(img);
+ }
+ });
+ }
+ function loadPreview() {
+ previewSequencer = previewSequencer.addSteps('resize', { resize: "40%" });
+
+ if (previewStepName === "crop") {
+ console.log(customValues);
+ previewSequencer.addSteps(previewStepName, customValues).run(insertPreview);
+ }
+ else {
+ previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview);
+ }
+ }
+ previewSequencer.loadImage(path, loadPreview);
+ }
+
+
+ sequencer = ImageSequencer();
+
+ function refreshOptions() {
+ // Load information of all modules (Name, Inputs, Outputs)
+ var modulesInfo = sequencer.modulesInfo();
+ console.log(modulesInfo)
+
+ var addStepSelect = $("#addStep select");
+ addStepSelect.html("");
+
+ // Add modules to the addStep dropdown
+ for (var m in modulesInfo) {
+ if (modulesInfo[m] && modulesInfo[m].name)
+ addStepSelect.append(
+ '"
+ );
+ }
+ // Null option
+ addStepSelect.append('');
+ }
+ refreshOptions();
+
+ // UI for each step:
+ sequencer.setUI(DefaultHtmlStepUi(sequencer));
+
+ // UI for the overall demo:
+ var ui = DefaultHtmlSequencerUi(sequencer);
+
+ // find any `src` parameters in URL hash and attempt to source image from them and run the sequencer
+ if (getUrlHashParameter('src')) {
+ sequencer.loadImage(getUrlHashParameter('src'), ui.onLoad);
+ } else {
+ sequencer.loadImage("images/tulips.png", ui.onLoad);
+ }
+
+ var resetSequence = function(){
+ var r=confirm("Do you want to reset the sequence?");
+ if (r)
+ window.location = "/";
+ }
+
+ $("#addStep select").on("change", ui.selectNewStepUi);
+ $("#addStep #add-step-btn").on("click", ui.addStepUi);
+ $("#resetButton").on("click",resetSequence);
+
+ //Module button radio selection
+ $('.radio-group .radio').on("click", function() {
+ $(this).parent().find('.radio').removeClass('selected');
+ $(this).addClass('selected');
+ newStep = $(this).attr('data-value');
+ console.log(newStep);
+ //$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
+ $("#addStep select").val(newStep);
+ ui.selectNewStepUi();
+ ui.addStepUi();
+ $(this).removeClass('selected');
+ });
+
+ $('#download-btn').click(function() {
+ $('.step-thumbnail:last()').trigger("click");
+ return false;
+ });
+
+ function displayMessageOnSaveSequence(){
+ $(".savesequencemsg").fadeIn();
+ setTimeout(function() {
+ $(".savesequencemsg").fadeOut();
+ }, 1000);
+ }
+
+ $('body').on('click', 'button.remove', ui.removeStepUi);
+ $('#save-seq').click(() => {
+ var result = window.prompt("Please give a name to your sequence... (Saved sequence will only be available in this browser).");
+ if(result){
+ result = result + " (local)";
+ sequencer.saveSequence(result, sequencer.toString());
+ sequencer.loadModules();
+ displayMessageOnSaveSequence();
+ refreshOptions();
+ }
+ });
+
+ var isWorkingOnGifGeneration = false;
+
+ $('.js-view-as-gif').on('click', function(event) {
+ // Prevent user from triggering generation multiple times
+ if (isWorkingOnGifGeneration) return;
+
+ isWorkingOnGifGeneration = true;
+
+ var button = event.target;
+ button.disabled = true;
+
+
+ try {
+ // Select all images from previous steps
+ var imgs = document.getElementsByClassName("step-thumbnail");
+
+ var imgSrcs = [];
+
+ for (var i = 0; i < imgs.length; i++) {
+ imgSrcs.push(imgs[i].src);
+ }
+
+ var options = {
+ 'gifWidth': imgs[0].width,
+ 'gifHeight': imgs[0].height,
+ 'images': imgSrcs,
+ 'frameDuration': 7,
+ }
+
+ gifshot.createGIF(options, function(obj) {
+ if (!obj.error) {
+ // Final gif encoded with base64 format
+ var image = obj.image;
+ var animatedImage = document.createElement('img');
+
+ animatedImage.id = "gif_element";
+ animatedImage.src = image;
+
+
+ var modal = $('#js-download-gif-modal');
+
+ $("#js-download-as-gif-button").one("click", function() {
+ // Trigger download
+ download(image, "index.gif", "image/gif");
+
+ // Close modal
+ modal.modal('hide');
+ })
+
+ var gifContainer = document.getElementById("js-download-modal-gif-container");
+
+ // Clear previous results
+ gifContainer.innerHTML = '';
+
+ // Insert image
+ gifContainer.appendChild(animatedImage);
+
+
+ // Open modal
+ modal.modal();
+
+ button.disabled = false;
+ isWorkingOnGifGeneration = false;
+ }
+ });
+ }
+ catch (e) {
+ console.error(e);
+ button.disabled = false;
+ isWorkingOnGifGeneration = false;
+
+ }
+ });
+
+ // image selection and drag/drop handling from examples/lib/imageSelection.js
+ sequencer.setInputStep({
+ dropZoneSelector: "#dropzone",
+ fileInputSelector: "#fileInput",
+ takePhotoSelector: "#take-photo",
+ onLoad: function onFileReaderLoad(progress) {
+ var reader = progress.target;
+ var step = sequencer.images.image1.steps[0];
+ step.output.src = reader.result;
+ sequencer.run({ index: 0 });
+ step.options.step.imgElement.src = reader.result;
+ updatePreviews(reader.result);
+ },
+ onTakePhoto: function (url) {
+ var step = sequencer.images.image1.steps[0];
+ step.output.src = url;
+ sequencer.run({ index: 0 });
+ step.options.step.imgElement.src = url;
+ }
+ });
+
+ setupCache();
+
+ function updatePreviews(src) {
+ $('#addStep img').remove();
+
+ var previewSequencerSteps = {
+ "brightness": "175",
+ "saturation": "0.5",
+ "rotate": 90,
+ "contrast": 90,
+ "crop": {
+ "x": 0,
+ "y": 0,
+ "w": "(50%)",
+ "h": "(50%)",
+ "noUI": true
+ }
+ }
+
+ Object.keys(previewSequencerSteps).forEach(function(step, index) {
+ generatePreview(step, Object.values(previewSequencerSteps)[index], src);
+ });
+ }
+
+ if (getUrlHashParameter('src')) {
+ updatePreviews(getUrlHashParameter('src'));
+ } else {
+ updatePreviews("images/tulips.png");
+ }
+};
diff --git a/dist/image-sequencer-ui.min.js b/dist/image-sequencer-ui.min.js
new file mode 100644
index 00000000..2e31ce58
--- /dev/null
+++ b/dist/image-sequencer-ui.min.js
@@ -0,0 +1 @@
+var setupCache=function(){"serviceWorker"in navigator&&navigator.serviceWorker.register("sw.js",{scope:"/examples/"}).then(function(e){const t=e.installing;t.onstatechange=(()=>{console.log(t),"installed"===t.state&&location.reload()}),console.log("Registration successful, scope is:",e.scope)}).catch(function(e){console.log("Service worker registration failed, error:",e)}),"serviceWorker"in navigator&&caches.keys().then(function(e){e.forEach(function(e){$("#clear-cache").append(" "+e)})}),$("#clear-cache").click(function(){"serviceWorker"in navigator&&caches.keys().then(function(e){e.forEach(function(e){caches.delete(e)})}),location.reload()})};function DefaultHtmlSequencerUi(e,t){var n=(t=t||{}).addStepSel=t.addStepSel||"#addStep",a=t.removeStepSel=t.removeStepSel||"button.remove";t.selectStepSel=t.selectStepSel||"#selectStep";function s(){var t=getUrlHashParameter("steps");t&&(e.importString(t),e.run({index:0})),setUrlHashParameter("steps",sequencer.toString())}function i(){sequencer.images.image1.steps.length<2?$(" #save-seq").prop("disabled",!0):$(" #save-seq").prop("disabled",!1)}return{onLoad:function(){s(),$("#selectStep").val()||$(n+" #add-step-btn").prop("disabled",!0),i()},importStepsFromUrlHash:s,selectNewStepUi:function(){var t=$(n+" select").val();$(n+" .info").html(e.modulesInfo(t).description),$(n+" #add-step-btn").prop("disabled",!1)},removeStepUi:function(){var e=$(a).index(this)+1;sequencer.removeSteps(e).run({index:e-1}),setUrlHashParameter("steps",sequencer.toString()),i()},addStepUi:function(){if("none"!=$(n+" select").val()){var a=$(n+" select").val(),s=1;sequencer.sequences[a]?s=sequencer.sequences[a].length:sequencer.modules[a][1].length&&(s=sequencer.modules[a][1].length),e.addSteps(a,t).run({index:e.images.image1.steps.length-s-1}),$(n+" .info").html("Select a new module to add to your sequence."),i(),setUrlHashParameter("steps",e.toString())}}}}function stepRemovedNotify(){if(0==$("#stepRemovedNotification").length){var e=document.createElement("span");e.innerHTML=' Step Removed ',e.id="stepRemovedNotification",$("body").append(e)}$("#stepRemovedNotification").fadeIn(500).delay(200).fadeOut(500)}function DefaultHtmlStepUi(e,t){var n=(t=t||{}).stepsEl||document.querySelector("#steps");t.selectStepSel=t.selectStepSel||"#selectStep";return{getPreview:function(){return step.imgElement},onSetup:function(t,a){t.options&&t.options.description&&(t.description=t.options.description),t.ui='
';var s=IntermediateHtmlStepUi(e,t),i=new DOMParser;if(t.ui=i.parseFromString(t.ui,"text/html"),t.ui=t.ui.querySelector("div.container"),t.linkElements=t.ui.querySelectorAll("a"),t.imgElement=t.ui.querySelector("a img"),e.modulesInfo().hasOwnProperty(t.name)){var o=e.modulesInfo(t.name).inputs,r=e.modulesInfo(t.name).outputs,l=Object.assign(o,r);for(var c in l){var d=o.hasOwnProperty(c),u="",p=d?o[c]:{};if(d)if("select"==p.type.toLowerCase()){for(var m in u+='"}else{let e=t.options[c]||p.default;u=''+e+"":u+='">'}else u+='';var f=document.createElement("div");f.className="row",f.setAttribute("name",c);var v=o[c].desc||c;f.innerHTML="
';o=(new DOMParser).parseFromString(o,"text/html").querySelector("div"),t.ui.querySelector("div.step").insertAdjacentElement("afterend",o);var r=$("#insertStep select");for(var l in r.html(""),i)void 0!==i[l]&&r.append('");$("#insertStep #add-step-btn").prop("disabled",!0),r.append(''),$("#insertStep .radio-group .radio").on("click",function(){$(this).parent().find(".radio").removeClass("selected"),$(this).addClass("selected"),newStep=$(this).attr("data-value"),r.val(newStep),a(),s(n),$(this).removeClass("selected")}),$(t.ui.querySelector("#insertStep select")).on("change",a),$(t.ui.querySelector("#insertStep #add-step-btn")).on("click",function(){s(n)})},{insertStep:insertStep}}$(document).ready(function(e){e(function(){e(window).scroll(function(){e(this).scrollTop()>100?e(".move-up").fadeIn():e(".move-up").fadeOut()}),e(".move-up button").click(function(){return e("body,html").animate({scrollTop:0},800),!1})})});const staticCacheName="image-sequencer-static-v3";function getUrlHashParameter(e){return getUrlHashParameters()[e]}function getUrlHashParameters(){var e=window.location.hash;e&&(e=e.split("#")[1]);var t={};return e.split("&").forEach(function(e,n){""!=(e=e.split("="))[0]&&(t[e[0]]=e[1])}),t}function setUrlHashParameters(e){var t=Object.keys(e),n=Object.values(e),a=[];t.forEach(function(e,s){""!=e&&a.push(t[s]+"="+n[s])});var s=a.join("&");window.location.hash=s}function setUrlHashParameter(e,t){var n=getUrlHashParameters();n[e]=t,setUrlHashParameters(n)}self.addEventListener("install",e=>{console.log("Attempting to install service worker")}),self.addEventListener("activate",function(e){console.log("[ServiceWorker] Activate"),e.waitUntil(caches.keys().then(function(e){return Promise.all(e.filter(function(e){return e.startsWith("image-sequencer-")&&e!=staticCacheName}).map(function(e){return caches.delete(e)}))}))}),self.addEventListener("fetch",function(e){e.respondWith(caches.open(staticCacheName).then(function(t){return t.match(e.request).then(function(n){return n||fetch(e.request).then(function(n){return"GET"==e.request.method&&t.put(e.request,n.clone()),n})})}))}),window.onload=function(){function e(){var e=sequencer.modulesInfo();console.log(e);var t=$("#addStep select");for(var n in t.html(""),e)e[n]&&e[n].name&&t.append('");t.append('')}sequencer=ImageSequencer(),e(),sequencer.setUI(DefaultHtmlStepUi(sequencer));var t=DefaultHtmlSequencerUi(sequencer);getUrlHashParameter("src")?sequencer.loadImage(getUrlHashParameter("src"),t.onLoad):sequencer.loadImage("images/tulips.png",t.onLoad);$("#addStep select").on("change",t.selectNewStepUi),$("#addStep #add-step-btn").on("click",t.addStepUi),$("#resetButton").on("click",function(){confirm("Do you want to reset the sequence?")&&(window.location="/")}),$(".radio-group .radio").on("click",function(){$(this).parent().find(".radio").removeClass("selected"),$(this).addClass("selected"),newStep=$(this).attr("data-value"),console.log(newStep),$("#addStep select").val(newStep),t.selectNewStepUi(),t.addStepUi(),$(this).removeClass("selected")}),$("#download-btn").click(function(){return $(".step-thumbnail:last()").trigger("click"),!1}),$("body").on("click","button.remove",t.removeStepUi),$("#save-seq").click(()=>{var t=window.prompt("Please give a name to your sequence... (Saved sequence will only be available in this browser).");t&&(t+=" (local)",sequencer.saveSequence(t,sequencer.toString()),sequencer.loadModules(),$(".savesequencemsg").fadeIn(),setTimeout(function(){$(".savesequencemsg").fadeOut()},1e3),e())});var n=!1;function a(e){$("#addStep img").remove();var t={brightness:"175",saturation:"0.5",rotate:90,contrast:90,crop:{x:0,y:0,w:"(50%)",h:"(50%)",noUI:!0}};Object.keys(t).forEach(function(n,a){!function(e,t,n){var a=ImageSequencer();function s(t){var n=document.createElement("img");n.classList.add("img-thumbnail"),n.classList.add("no-border"),n.src=t,$(n).css("max-width","200%"),$(n).css("transform","translateX(-20%)"),$("#addStep .row").find("div").each(function(){$(this).find("div").attr("data-value")===e&&$(this).find("div").append(n)})}a.loadImage(n,function(){a=a.addSteps("resize",{resize:"40%"}),"crop"===e?(console.log(t),a.addSteps(e,t).run(s)):a.addSteps(e,{[e]:t}).run(s)})}(n,Object.values(t)[a],e)})}$(".js-view-as-gif").on("click",function(e){if(!n){n=!0;var t=e.target;t.disabled=!0;try{for(var a=document.getElementsByClassName("step-thumbnail"),s=[],i=0;i\
\
-
\
+
\
\
\
\
@@ -50,13 +49,14 @@ function DefaultHtmlStepUi(_sequencer, options) {
';
var tools =
- '
\
+ '
\
\
\
+
\
';
var util = IntermediateHtmlStepUi(_sequencer, step);
@@ -114,7 +114,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
div.setAttribute("name", paramName);
var description = inputs[paramName].desc || paramName;
div.innerHTML =
- "