diff --git a/dist/image-sequencer-ui.js b/dist/image-sequencer-ui.js new file mode 100644 index 00000000..828f674c --- /dev/null +++ b/dist/image-sequencer-ui.js @@ -0,0 +1,877 @@ +var setupCache = function() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('sw.js', { scope: '/examples/' }) + .then(function(registration) { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + console.log(installingWorker) + if (installingWorker.state === 'installed') { + location.reload(); + } + } + console.log('Registration successful, scope is:', registration.scope); + }) + .catch(function(error) { + console.log('Service worker registration failed, error:', error); + }); + } + + if ('serviceWorker' in navigator) { + caches.keys().then(function(cacheNames) { + cacheNames.forEach(function(cacheName) { + $("#clear-cache").append(" " + cacheName); + }); + }); + } + + $("#clear-cache").click(function() { + if ('serviceWorker' in navigator) { + caches.keys().then(function(cacheNames) { + cacheNames.forEach(function(cacheName) { + caches.delete(cacheName); + }); + }); + } + location.reload(); + }); +} +function DefaultHtmlSequencerUi(_sequencer, options) { + + options = options || {}; + var addStepSel = options.addStepSel = options.addStepSel || "#addStep"; + var removeStepSel = options.removeStepSel = options.removeStepSel || "button.remove"; + var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep"; + + function onLoad() { + importStepsFromUrlHash(); + if (!$('#selectStep').val()) + $(addStepSel + " #add-step-btn").prop("disabled", true); + handleSaveSequence(); + } + + // look up needed steps from Url Hash: + function importStepsFromUrlHash() { + var hash = getUrlHashParameter("steps"); + + if (hash) { + _sequencer.importString(hash); + _sequencer.run({ index: 0 }); + } + setUrlHashParameter("steps", sequencer.toString()); + } + + function selectNewStepUi() { + var m = $(addStepSel + " select").val(); + $(addStepSel + " .info").html(_sequencer.modulesInfo(m).description); + $(addStepSel + " #add-step-btn").prop("disabled", false); + } + + function removeStepUi() { + var index = $(removeStepSel).index(this) + 1; + sequencer.removeSteps(index).run({ index: index - 1 }); + // remove from URL hash too + setUrlHashParameter("steps", sequencer.toString()); + //disable save-sequence button if all steps are removed + handleSaveSequence(); + } + + function addStepUi() { + if ($(addStepSel + " select").val() == "none") return; + + var newStepName = $(addStepSel + " select").val(); + + /* + * after adding the step we run the sequencer from defined step + * and since loadImage is not a part of the drawarray the step lies at current + * length - 2 of the drawarray + */ + 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 + .addSteps(newStepName, options) + .run({ index: _sequencer.images.image1.steps.length - sequenceLength - 1 }); + $(addStepSel + " .info").html("Select a new module to add to your sequence."); + + //enable save-sequence button if disabled initially + handleSaveSequence(); + + // add to URL hash too + setUrlHashParameter("steps", _sequencer.toString()); + } + + function handleSaveSequence(){ + var stepCount=sequencer.images.image1.steps.length; + if(stepCount<2) + $(" #save-seq").prop("disabled", true); + else + $(" #save-seq").prop("disabled", false); + } + + return { + onLoad: onLoad, + importStepsFromUrlHash: importStepsFromUrlHash, + selectNewStepUi: selectNewStepUi, + removeStepUi: removeStepUi, + addStepUi: addStepUi + } +} + +// Set the UI in sequencer. This Will generate HTML based on +// Image Sequencer events : +// onSetup : Called every time a step is added +// onDraw : Called every time a step starts draw +// onComplete : Called every time a step finishes drawing +// onRemove : Called everytime a step is removed +// The variable 'step' stores useful data like input and +// output values, step information. +// See documetation for more details. +function stepRemovedNotify() { + if ($('#stepRemovedNotification').length == 0) { + var notification = document.createElement('span'); + notification.innerHTML = ' Step Removed '; + notification.id = 'stepRemovedNotification'; + + $('body').append(notification); + } + + $('#stepRemovedNotification').fadeIn(500).delay(200).fadeOut(500); +} +function DefaultHtmlStepUi(_sequencer, options) { + + options = options || {}; + var stepsEl = options.stepsEl || document.querySelector("#steps"); + var selectStepSel = options.selectStepSel = options.selectStepSel || "#selectStep"; + function onSetup(step, stepOptions) { + if (step.options && step.options.description) + step.description = step.options.description; + + step.ui = + '\ +
\ +
\ +
\ +
\ +

' +step.name + + ' ' + + '

"'+ + (step.description || "") + + '

\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ + '; + + var tools = + '
\ + \ + \ +
\ +
'; + + var util = IntermediateHtmlStepUi(_sequencer, step); + + var parser = new DOMParser(); + step.ui = parser.parseFromString(step.ui, "text/html"); + step.ui = step.ui.querySelector("div.container"); + step.linkElements = step.ui.querySelectorAll("a"); + step.imgElement = step.ui.querySelector("a img"); + + if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { + var inputs = _sequencer.modulesInfo(step.name).inputs; + var outputs = _sequencer.modulesInfo(step.name).outputs; + var merged = Object.assign(inputs, outputs); // combine outputs w inputs + + for (var paramName in merged) { + var isInput = inputs.hasOwnProperty(paramName); + var html = ""; + var inputDesc = isInput ? inputs[paramName] : {}; + if (!isInput) { + html += ''; + } else if (inputDesc.type.toLowerCase() == "select") { + html += '"; + } else { + let paramVal = step.options[paramName] || inputDesc.default; + html = + '' + '' + paramVal + ''; + + } + else html += '">'; + } + + var div = document.createElement("div"); + div.className = "row"; + div.setAttribute("name", paramName); + var description = inputs[paramName].desc || paramName; + div.innerHTML = + "
\ + \ + " + + html + + "\ +
"; + step.ui.querySelector("div.details").appendChild(div); + } + + $(step.ui.querySelector("div.details")).append( + '

Press apply to see changes

' + ); + + + } + + if (step.name != "load-image") { + step.ui + .querySelector("div.details") + .appendChild( + parser.parseFromString(tools, "text/html").querySelector("div") + ); + $(step.ui.querySelectorAll(".insert-step")).on('click', function() { util.insertStep(step.ID) }); + + // Insert the step's UI in the right place + if (stepOptions.index == _sequencer.images.image1.steps.length) { + stepsEl.appendChild(step.ui); + $("#steps .container:nth-last-child(1) .insert-step").prop('disabled',true); + if($("#steps .container:nth-last-child(2)")) + $("#steps .container:nth-last-child(2) .insert-step").prop('disabled',false); + } else { + stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]); + } + } + else { + $("#load-image").append(step.ui); + } + $(step.ui.querySelector(".toggle")).on("click", (e) => { + var className = e.target.className; + console.log("ele "+element) + if(className=="fa fa-caret-up"){ + $(step.ui.querySelectorAll(".collapse")).show(); + e.target.className="fa fa-caret-down"; + } + else{ + $(step.ui.querySelectorAll(".collapse")).hide(); + //e.target.localName.toggleClass('fa-caret-up'); + e.target.className="fa fa-caret-up"; + } + }); + + + function saveOptions(e) { + e.preventDefault(); + if (optionsChanged){ + $(step.ui.querySelector("div.details")) + .find("input,select") + .each(function(i, input) { + $(input) + .data('initValue', $(input).val()) + .data('hasChangedBefore', false); + step.options[$(input).attr("name")] = $(input).val(); + }); + _sequencer.run({ index: step.index - 1 }); + + // modify the url hash + setUrlHashParameter("steps", _sequencer.toString()); + + // disable the save button + $(step.ui.querySelector('.btn-save')).prop('disabled', true); + optionsChanged = false; + changedInputs = 0; + } + } + + function handleInputValueChange(currentValue, initValue, hasChangedBefore) { + var inputChanged = !(isNaN(initValue) || isNaN(currentValue) ? currentValue === initValue : currentValue - initValue === 0); + changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0; + optionsChanged = changedInputs > 0; + + $(step.ui.querySelector('.btn-save')).prop('disabled', !optionsChanged); + return inputChanged; + } + + var + changedInputs = 0, + optionsChanged = false; + $(step.ui.querySelector('.input-form')).on('submit', saveOptions); + $(step.ui.querySelectorAll('.target')).each(function(i, input) { + $(input) + .data('initValue', $(input).val()) + .data('hasChangedBefore', false) + .on('input', function() { + $(this) + .focus() + .data('hasChangedBefore', + handleInputValueChange( + $(this).val(), + $(this).data('initValue'), + $(this).data('hasChangedBefore') + ) + ) + }) + }) + + + + $('input[type="range"]').on('input', function() { + $(this).next().html($(this).val()); + }) + } + + + function onDraw(step) { + $(step.ui.querySelector(".load")).show(); + $(step.ui.querySelector("img")).hide(); + } + + function onComplete(step) { + $(step.ui.querySelector(".load")).hide(); + $(step.ui.querySelector("img")).show(); + + step.imgElement.src = step.output; + var imgthumbnail = step.ui.querySelector(".img-thumbnail"); + for (let index = 0; index < step.linkElements.length; index++) { + if (step.linkElements[index].contains(imgthumbnail)) + step.linkElements[index].href = step.output; + } + + // TODO: use a generalized version of this + function fileExtension(output) { + return output.split("/")[1].split(";")[0]; + } + + for (let index = 0; index < step.linkElements.length; index++) { + step.linkElements[index].download = step.name + "." + fileExtension(step.output); + step.linkElements[index].target = "_blank"; + } + + // fill inputs with stored step options + if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { + var inputs = _sequencer.modulesInfo(step.name).inputs; + var outputs = _sequencer.modulesInfo(step.name).outputs; + for (var i in inputs) { + if (step.options[i] !== undefined) { + if (inputs[i].type.toLowerCase() === "input") + $(step.ui.querySelector('div[name="' + i + '"] input')) + .val(step.options[i]) + .data('initValue', step.options[i]); + if (inputs[i].type.toLowerCase() === "select") + $(step.ui.querySelector('div[name="' + i + '"] select')) + .val(step.options[i]) + .data('initValue', step.options[i]); + } + } + for (var i in outputs) { + if (step[i] !== undefined) + $(step.ui.querySelector('div[name="' + i + '"] input')) + .val(step[i]); + } + } + } + + function onRemove(step) { + step.ui.remove(); + $("#steps .container:nth-last-child(1) .insert-step").prop('disabled',true); + $('div[class^=imgareaselect-]').remove(); + } + + function getPreview() { + return step.imgElement; + } + + return { + getPreview: getPreview, + onSetup: onSetup, + onComplete: onComplete, + onRemove: onRemove, + onDraw: onDraw + } +} + +function IntermediateHtmlStepUi(_sequencer, step, options) { + function stepUI() { + return '
\ +
\ +
\ +
\ +
\ +

Select a new module to add to your sequence.

\ +
\ +
\ + \ +

Brightness

\ +
\ +
\ + \ +

Contrast

\ +
\ +
\ + \ +

Saturation

\ +
\ +
\ + \ +

Rotate

\ +
\ +
\ + \ +

Crop

\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
'; + } + 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='

'+t.name+'

"'+(t.description||"")+'

';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="
"+u+"
",t.ui.querySelector("div.details").appendChild(f)}$(t.ui.querySelector("div.details")).append('

Press apply to see changes

')}"load-image"!=t.name?(t.ui.querySelector("div.details").appendChild(i.parseFromString('
',"text/html").querySelector("div")),$(t.ui.querySelectorAll(".insert-step")).on("click",function(){s.insertStep(t.ID)}),a.index==e.images.image1.steps.length?(n.appendChild(t.ui),$("#steps .container:nth-last-child(1) .insert-step").prop("disabled",!0),$("#steps .container:nth-last-child(2)")&&$("#steps .container:nth-last-child(2) .insert-step").prop("disabled",!1)):n.insertBefore(t.ui,$(n).children()[a.index])):$("#load-image").append(t.ui),$(t.ui.querySelector(".toggle")).on("click",e=>{var n=e.target.className;console.log("ele "+element),"fa fa-caret-up"==n?($(t.ui.querySelectorAll(".collapse")).show(),e.target.className="fa fa-caret-down"):($(t.ui.querySelectorAll(".collapse")).hide(),e.target.className="fa fa-caret-up")});var h=0,g=!1;$(t.ui.querySelector(".input-form")).on("submit",function(n){n.preventDefault(),g&&($(t.ui.querySelector("div.details")).find("input,select").each(function(e,n){$(n).data("initValue",$(n).val()).data("hasChangedBefore",!1),t.options[$(n).attr("name")]=$(n).val()}),e.run({index:t.index-1}),setUrlHashParameter("steps",e.toString()),$(t.ui.querySelector(".btn-save")).prop("disabled",!0),g=!1,h=0)}),$(t.ui.querySelectorAll(".target")).each(function(e,n){$(n).data("initValue",$(n).val()).data("hasChangedBefore",!1).on("input",function(){var e,n,a,s;$(this).focus().data("hasChangedBefore",(e=$(this).val(),n=$(this).data("initValue"),a=$(this).data("hasChangedBefore"),s=!(isNaN(n)||isNaN(e)?e===n:e-n==0),g=(h+=a?s?0:-1:s?1:0)>0,$(t.ui.querySelector(".btn-save")).prop("disabled",!g),s))})}),$('input[type="range"]').on("input",function(){$(this).next().html($(this).val())})},onComplete:function(t){$(t.ui.querySelector(".load")).hide(),$(t.ui.querySelector("img")).show(),t.imgElement.src=t.output;var n=t.ui.querySelector(".img-thumbnail");for(let e=0;e

Select a new module to add to your sequence.

Brightness

Contrast

Saturation

Rotate

Crop

';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\
\
\ -

' + - step.name + - "

\ -

" + +

' +step.name + + ' ' + + '

"'+ (step.description || "") + - '

\ + '

\
\
\ -
\ +
\ \ \
\ @@ -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 = - "
\ + "
\