From 89466d582aaf9061d24831c379160c5760a49650 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Mon, 23 Jun 2014 00:49:54 +0200 Subject: [PATCH] Feature : Save Piskel project as File First commit : Removed Local storage feature Added 'download project' 'open project' options First attempt at simplifying right panel. To be continued ... --- .gitignore | 1 + src/css/reset.css | 4 + src/css/settings.css | 88 ++++++++++++++----- src/css/style.css | 4 + src/index.html | 5 +- src/js/Constants.js | 4 +- .../settings/GifExportController.js | 49 ++++------- .../controller/settings/ImportController.js | 60 ++++++++++--- .../settings/PngExportController.js | 17 ++-- src/js/controller/settings/SaveController.js | 82 ++++++++++------- .../controller/settings/SettingsController.js | 6 +- src/js/utils/{ImageToBlob.js => BlobUtils.js} | 15 ++-- src/js/utils/DateUtils.js | 24 +++++ src/js/utils/FileUtils.js | 2 +- src/js/utils/Template.js | 9 ++ src/js/utils/serialization/Serializer.js | 3 + src/piskel-script-list.js | 3 +- src/templates/settings.html | 33 +++---- src/templates/settings/export-gif.html | 22 ----- src/templates/settings/export-png.html | 23 ----- src/templates/settings/export.html | 40 +++++++++ src/templates/settings/import.html | 53 +++++++---- src/templates/settings/save.html | 33 +++++-- 23 files changed, 366 insertions(+), 214 deletions(-) rename src/js/utils/{ImageToBlob.js => BlobUtils.js} (71%) create mode 100644 src/js/utils/DateUtils.js delete mode 100644 src/templates/settings/export-gif.html delete mode 100644 src/templates/settings/export-png.html create mode 100644 src/templates/settings/export.html diff --git a/.gitignore b/.gitignore index 578dec56..e25a5dc9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ diff.txt # build destination dest +build/closure/closure_compiled_binary.js # marked as private *.private.* \ No newline at end of file diff --git a/src/css/reset.css b/src/css/reset.css index 6c81940f..d6fdcba7 100644 --- a/src/css/reset.css +++ b/src/css/reset.css @@ -33,4 +33,8 @@ ul, li { ::-webkit-scrollbar-track { background-color: rgba(50, 50, 50, 0.4); +} + +a, a:visited { + color:gold; } \ No newline at end of file diff --git a/src/css/settings.css b/src/css/settings.css index 726d3403..d9c30ca1 100644 --- a/src/css/settings.css +++ b/src/css/settings.css @@ -70,7 +70,7 @@ position: relative; } -.upload-cloud-icon .label { +.tool-icon .label { position: absolute; left: 0; bottom: 4px; @@ -126,6 +126,7 @@ text-transform: uppercase; border-bottom: 1px #aaa solid; padding-bottom: 5px; + color: gold; } .settings-description { @@ -141,6 +142,10 @@ margin : 10px 0; } +[name*=checkbox] { + vertical-align: middle; +} + /************************************************************************************************/ /* Application settings */ /************************************************************************************************/ @@ -203,13 +208,6 @@ background:gold; } -.gif-export-preview, -.png-export-preview { - margin-top:20px; - max-width:240px; - position:relative; -} - .png-export-preview { margin:10px 0; overflow: hidden; @@ -223,6 +221,38 @@ margin : 10px 0; } +.gif-upload-status, +.gif-export-preview { + float : left; +} + +.gif-export-preview { + +} + +.gif-upload-status { + width: 180px; + margin-left: 5px; + margin-top: 10px; +} + + +.gif-export-preview, +.png-export-preview { + margin-top:10px; + position:relative; +} + +.png-export-preview { + max-width:240px; +} + +.gif-export-preview, +.png-export-preview { + max-width:32px; + max-height:32px; +} + .preview-upload-ongoing:before{ content: "Upload ongoing ..."; position: absolute; @@ -243,7 +273,7 @@ .import-section, .resize-section { - margin: 15px 0; + margin: 10px 0; } .import-section-title { @@ -296,26 +326,36 @@ text-shadow: none; } -.save-field { - width: 100%; -} - -#save-status { - margin-top: 10px; -} -.status { - height: 1.5rem; - vertical-align: middle; - font-weight: normal; - text-shadow: none; -} - [name=smooth-resize-checkbox] { margin : 0 8px; } -[name*=checkbox] { +/************************************************************************************************/ +/* Save panel */ +/************************************************************************************************/ + +.save-field { + width: 100%; +} + +#save-online-status { + margin-top: 10px; +} +#save-local-status { + margin-bottom: 10px; +} +.save-status { vertical-align: middle; + font-weight: normal; + text-shadow: none; + font-style: italic; +} + +.save-local-name { + white-space: nowrap; + font-weight: bold; + color: white; + font-style: normal; } diff --git a/src/css/style.css b/src/css/style.css index 0cb64084..66539f42 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -11,6 +11,10 @@ body { display: none; } +.clearfix { + overflow: hidden; +} + .allow-user-select { -webkit-touch-callout: initial; -webkit-user-select: initial; diff --git a/src/index.html b/src/index.html index f0bb2a69..790ae2bf 100644 --- a/src/index.html +++ b/src/index.html @@ -54,9 +54,8 @@ - - - + + diff --git a/src/js/Constants.js b/src/js/Constants.js index 65b00fe7..ad93d15d 100644 --- a/src/js/Constants.js +++ b/src/js/Constants.js @@ -56,8 +56,8 @@ var Constants = { SAVE : 'save' } }, - IMAGE_SERVICE_UPLOAD_URL : 'http://piskel-imgstore-a.appspot.com/__/upload', - IMAGE_SERVICE_GET_URL : 'http://piskel-imgstore-a.appspot.com/img/', + IMAGE_SERVICE_UPLOAD_URL : 'http://piskel-imgstore-b.appspot.com/__/upload', + IMAGE_SERVICE_GET_URL : 'http://piskel-imgstore-b.appspot.com/img/', ZOOMED_OUT_BACKGROUND_COLOR : '#A0A0A0', diff --git a/src/js/controller/settings/GifExportController.js b/src/js/controller/settings/GifExportController.js index 4eaa052a..8d2d98e5 100644 --- a/src/js/controller/settings/GifExportController.js +++ b/src/js/controller/settings/GifExportController.js @@ -1,7 +1,7 @@ (function () { var ns = $.namespace("pskl.controller.settings"); - var URL_MAX_LENGTH = 60; + var URL_MAX_LENGTH = 30; var MAX_GIF_COLORS = 256; ns.GifExportController = function (piskelController) { @@ -27,12 +27,12 @@ ]; ns.GifExportController.prototype.init = function () { - this.radioTemplate_ = pskl.utils.Template.get("gif-export-radio-template"); + this.optionTemplate_ = pskl.utils.Template.get("gif-export-option-template"); this.uploadStatusContainerEl = document.querySelector(".gif-upload-status"); this.previewContainerEl = document.querySelector(".gif-export-preview"); - this.radioGroupEl = document.querySelector(".gif-export-radio-group"); + this.selectResolutionEl = document.querySelector(".gif-export-select-resolution"); this.uploadButton = $(".gif-upload-button"); this.uploadButton.click(this.onUploadButtonClick_.bind(this)); @@ -45,7 +45,7 @@ this.exportProgressStatusEl = document.querySelector('.gif-export-progress-status'); this.exportProgressBarEl = document.querySelector('.gif-export-progress-bar'); - this.createRadioElements_(); + this.createOptionElements_(); }; ns.GifExportController.prototype.onUploadButtonClick_ = function (evt) { @@ -63,8 +63,8 @@ this.renderAsImageDataAnimatedGIF(zoom, fps, function (imageData) { pskl.app.imageUploadService.upload(imageData, this.onImageUploadCompleted_.bind(this)); - pskl.utils.ImageToBlob.imageDataToBlob(imageData, "image/gif", function(blob) { - pskl.utils.FileUtils.downloadAsFile(fileName, blob); + pskl.utils.BlobUtils.dataToBlob(imageData, "image/gif", function(blob) { + pskl.utils.FileUtils.downloadAsFile(blob, fileName); }); }.bind(this)); }; @@ -82,43 +82,30 @@ }; ns.GifExportController.prototype.updatePreview_ = function (src) { - this.previewContainerEl.innerHTML = "
"; + this.previewContainerEl.innerHTML = "
"; }; ns.GifExportController.prototype.getSelectedZoom_ = function () { - var radiosColl = this.exportForm.get(0).querySelectorAll("[name=gif-zoom-level]"), - radios = Array.prototype.slice.call(radiosColl,0); - var selectedRadios = radios.filter(function(radio) {return !!radio.checked;}); - - if (selectedRadios.length == 1) { - return selectedRadios[0].value; - } else { - throw "Unexpected error when retrieving selected zoom"; - } + return this.selectResolutionEl.value; }; - ns.GifExportController.prototype.createRadioElements_ = function () { + ns.GifExportController.prototype.createOptionElements_ = function () { var resolutions = ns.GifExportController.RESOLUTIONS; for (var i = 0 ; i < resolutions.length ; i++) { - var radio = this.createRadioForResolution_(resolutions[i]); - this.radioGroupEl.appendChild(radio); + var option = this.createOptionForResolution_(resolutions[i]); + this.selectResolutionEl.appendChild(option); } }; - ns.GifExportController.prototype.createRadioForResolution_ = function (resolution) { + ns.GifExportController.prototype.createOptionForResolution_ = function (resolution) { var zoom = resolution.zoom; var label = zoom*this.piskelController.getWidth() + "x" + zoom*this.piskelController.getHeight(); var value = zoom; - var radioHTML = pskl.utils.Template.replace(this.radioTemplate_, {value : value, label : label}); - var radioEl = pskl.utils.Template.createFromHTML(radioHTML); + var optionHTML = pskl.utils.Template.replace(this.optionTemplate_, {value : value, label : label}); + var optionEl = pskl.utils.Template.createFromHTML(optionHTML); - if (resolution['default']) { - var input = radioEl.getElementsByTagName("input")[0]; - input.setAttribute("checked", "checked"); - } - - return radioEl; + return optionEl; }; ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(zoom, fps, cb) { @@ -181,8 +168,10 @@ ns.GifExportController.prototype.shorten_ = function (url, maxLength, suffix) { if (url.length > maxLength) { - url = url.substring(0, maxLength); - url += suffix; + var index = Math.round((maxLength-suffix.length) / 2); + var part1 = url.substring(0, index); + var part2 = url.substring(url.length - index, url.length); + url = part1 + suffix + part2; } return url; }; diff --git a/src/js/controller/settings/ImportController.js b/src/js/controller/settings/ImportController.js index 7ad4d9e1..21e4fabf 100644 --- a/src/js/controller/settings/ImportController.js +++ b/src/js/controller/settings/ImportController.js @@ -1,6 +1,6 @@ (function () { var ns = $.namespace('pskl.controller.settings'); - var DEFAULT_FILE_STATUS = 'No file selected ...'; + var DEFAULT_FILE_STATUS = ''; var PREVIEW_HEIGHT = 60; ns.ImportController = function (piskelController) { @@ -9,6 +9,9 @@ }; ns.ImportController.prototype.init = function () { + this.hiddenOpenPiskelInput = $('[name=open-piskel-input]'); + this.openPiskelInputButton = $('.open-piskel-button'); + this.importForm = $('[name=import-form]'); this.hiddenFileInput = $('[name=file-upload-input]'); this.fileInputButton = $('.file-input-button'); @@ -20,12 +23,16 @@ this.resizeWidth = $('[name=resize-width]'); this.resizeHeight = $('[name=resize-height]'); this.smoothResize = $('[name=smooth-resize-checkbox]'); - this.submitButton = $('[name=import-submit]'); + + $('.import-options').hide(); this.importForm.submit(this.onImportFormSubmit_.bind(this)); this.hiddenFileInput.change(this.onFileUploadChange_.bind(this)); this.fileInputButton.click(this.onFileInputClick_.bind(this)); + this.hiddenOpenPiskelInput.change(this.onOpenPiskelChange_.bind(this)); + this.openPiskelInputButton.click(this.onOpenPiskelClick_.bind(this)); + this.resizeWidth.keyup(this.onResizeInputKeyUp_.bind(this, 'width')); this.resizeHeight.keyup(this.onResizeInputKeyUp_.bind(this, 'height')); }; @@ -61,14 +68,47 @@ }; ns.ImportController.prototype.onFileUploadChange_ = function (evt) { - this.importFromFile_(); + this.importPictureFromFile_(); }; ns.ImportController.prototype.onFileInputClick_ = function (evt) { this.hiddenFileInput.click(); }; - ns.ImportController.prototype.importFromFile_ = function () { + ns.ImportController.prototype.onOpenPiskelChange_ = function (evt) { + this.openPiskelFile_(); + }; + + ns.ImportController.prototype.onOpenPiskelClick_ = function (evt) { + this.hiddenOpenPiskelInput.click(); + }; + + ns.ImportController.prototype.openPiskelFile_ = function () { + var files = this.hiddenOpenPiskelInput.get(0).files; + if (files.length == 1) { + + var file = files[0]; + if (this.isPiskel_(file)){ + pskl.utils.FileUtils.readFile(file, function (content) { + var rawPiskel = window.atob(content.replace('data:;base64,','')); + var serializedPiskel = JSON.parse(rawPiskel); + var name = serializedPiskel.piskel.name; + var description = serializedPiskel.piskel.description; + var fps = serializedPiskel.piskel.fps; + + pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, function (piskel) { + piskel.setDescriptor(new pskl.model.piskel.Descriptor(name, description, true)); + pskl.app.piskelController.setPiskel(piskel); + pskl.app.animationController.setFPS(fps); + }); + }); + this.reset_(); + } + } + }; + + + ns.ImportController.prototype.importPictureFromFile_ = function () { var files = this.hiddenFileInput.get(0).files; if (files.length == 1) { var file = files[0]; @@ -83,15 +123,9 @@ }; ns.ImportController.prototype.enableDisabledSections_ = function () { - this.resizeWidth.removeAttr('disabled'); - this.resizeHeight.removeAttr('disabled'); - this.smoothResize.removeAttr('disabled'); - this.submitButton.removeAttr('disabled'); - this.fileInputButton.removeClass('button-primary'); this.fileInputButton.blur(); - - $('.import-section-disabled').removeClass('import-section-disabled'); + $('.import-options').show(); }; ns.ImportController.prototype.readImageFile_ = function (imageFile) { @@ -200,4 +234,8 @@ return file.type.indexOf('image') === 0; }; + ns.ImportController.prototype.isPiskel_ = function (file) { + return (/\.piskel$/).test(file.name); + }; + })(); \ No newline at end of file diff --git a/src/js/controller/settings/PngExportController.js b/src/js/controller/settings/PngExportController.js index c35e7b57..2c1c8b72 100644 --- a/src/js/controller/settings/PngExportController.js +++ b/src/js/controller/settings/PngExportController.js @@ -9,28 +9,23 @@ ns.PngExportController.prototype.init = function () { this.previewContainerEl = document.querySelectorAll(".png-export-preview")[0]; - this.uploadStatusContainerEl = document.querySelectorAll(".png-upload-status")[0]; - document.querySelector(".png-upload-button").addEventListener('click', this.onPngUploadButtonClick_.bind(this)); document.querySelector(".png-download-button").addEventListener('click', this.onPngDownloadButtonClick_.bind(this)); document.querySelector(".zip-generate-button").addEventListener('click', this.onZipButtonClick_.bind(this)); this.updatePreview_(this.getFramesheetAsCanvas().toDataURL("image/png")); + + (new ns.GifExportController(this.piskelController)).init(); }; ns.PngExportController.prototype.onPngDownloadButtonClick_ = function (evt) { var fileName = this.getPiskelName_() + '.png'; - pskl.utils.ImageToBlob.canvasToBlob(this.getFramesheetAsCanvas(), function(blob) { - pskl.utils.FileUtils.downloadAsFile(fileName, blob); + pskl.utils.BlobUtils.canvasToBlob(this.getFramesheetAsCanvas(), function(blob) { + pskl.utils.FileUtils.downloadAsFile(blob, fileName); }); }; - ns.PngExportController.prototype.onPngUploadButtonClick_ = function (evt) { - this.previewContainerEl.classList.add("preview-upload-ongoing"); - pskl.app.imageUploadService.upload(this.getFramesheetAsCanvas().toDataURL("image/png"), this.onImageUploadCompleted_.bind(this)); - }; - ns.PngExportController.prototype.onZipButtonClick_ = function () { var zip = new window.JSZip(); @@ -43,8 +38,8 @@ var fileName = this.getPiskelName_() + '.zip'; - var fileContent = zip.generate({type:"blob"}); - pskl.utils.FileUtils.downloadAsFile(fileName, fileContent); + var blob = zip.generate({type:"blob"}); + pskl.utils.FileUtils.downloadAsFile(blob, fileName); }; ns.PngExportController.prototype.getFrameAsCanvas_ = function (frame) { diff --git a/src/js/controller/settings/SaveController.js b/src/js/controller/settings/SaveController.js index d0cfc38a..b79a49f2 100644 --- a/src/js/controller/settings/SaveController.js +++ b/src/js/controller/settings/SaveController.js @@ -13,13 +13,16 @@ this.nameInput = $('#save-name'); this.descriptionInput = $('#save-description'); this.isPublicCheckbox = $('input[name=save-public-checkbox]'); - this.saveCloudButton = $('#save-cloud-button'); + this.saveOnlineButton = $('#save-online-button'); this.saveLocalButton = $('#save-local-button'); // Only available in app-engine mode ... this.piskelName = $('.piskel-name').get(0); - this.status = $('#save-status'); + this.saveOnlineStatus = $('#save-online-status'); + + this.saveLocalStatus = $('#save-local-status'); + this.timestamp = new Date(); var descriptor = this.piskelController.getPiskel().getDescriptor(); this.nameInput.val(descriptor.name); @@ -27,27 +30,38 @@ this.isPublicCheckbox.prop('checked', descriptor.isPublic); - if (!pskl.app.isLoggedIn()) { - this.saveCloudButton.attr('disabled', 'disabled'); - this.status.html('You are not logged in. Only Local Save is available.'); - } else { + this.saveLocalButton.click(this.onSaveLocalClick_.bind(this)); + this.nameInput.keyup(this.updateLocalStatusFilename_.bind(this)); + + if (pskl.app.isLoggedIn()) { this.saveForm.submit(this.onSaveFormSubmit_.bind(this)); + } else { + this.saveOnlineButton.hide(); + $('.save-public-section').hide(); + this.saveOnlineStatus.html(pskl.utils.Template.get('save-please-login-partial')); + this.saveLocalButton.get(0).classList.add('button-primary'); + this.saveForm.submit(this.onSaveLocalClick_.bind(this)); } - this.saveLocalButton.click(this.onSaveLocalClick_.bind(this)); + this.updateLocalStatusFilename_(); + }; + + ns.SaveController.prototype.updateLocalStatusFilename_ = function () { + this.saveLocalStatus.html(pskl.utils.Template.getAndReplace('save-local-status-template', { + name : this.getLocalFilename_() + })); + }; + + ns.SaveController.prototype.getLocalFilename_ = function () { + var piskelName = this.getName(); + var timestamp = pskl.utils.DateUtils.format(this.timestamp, "{{Y}}{{M}}{{D}}-{{H}}{{m}}{{s}}"); + return piskelName + "-" + timestamp + ".piskel"; }; ns.SaveController.prototype.onSaveFormSubmit_ = function (evt) { evt.preventDefault(); evt.stopPropagation(); - var name = this.getName(); - var description = this.getDescription(); - var isPublic = !!this.isPublicCheckbox.prop('checked'); - - var descriptor = new pskl.model.piskel.Descriptor(name, description, isPublic); - this.piskelController.getPiskel().setDescriptor(descriptor); - this.beforeSaving_(); pskl.app.storageService.store({ success : this.onSaveSuccess_.bind(this), @@ -57,22 +71,13 @@ }; ns.SaveController.prototype.onSaveLocalClick_ = function (evt) { - var localStorageService = pskl.app.localStorageService; - var isOk = true; - var name = this.getName(); - var description = this.getDescription(); - if (localStorageService.getPiskel(name)) { - isOk = window.confirm('There is already a piskel saved as ' + name + '. Override ?'); - } + this.beforeSaving_(); - if (isOk) { - this.beforeSaving_(); - localStorageService.save(name, description, pskl.app.piskelController.serialize()); - window.setTimeout(function () { - this.onSaveSuccess_(); - this.afterSaving_(); - }.bind(this), 1000); - } + pskl.utils.BlobUtils.stringToBlob(pskl.app.piskelController.serialize(), function(blob) { + pskl.utils.FileUtils.downloadAsFile(blob, this.getLocalFilename_()); + this.onSaveSuccess_(); + this.afterSaving_(); + }.bind(this), "application/piskel+json"); }; ns.SaveController.prototype.getName = function () { @@ -84,14 +89,25 @@ }; ns.SaveController.prototype.beforeSaving_ = function () { - this.saveCloudButton.attr('disabled', true); - this.status.html('Saving ...'); + this.updatePiskelDescriptor_(); + + this.saveOnlineButton.attr('disabled', true); + this.saveOnlineStatus.html('Saving ...'); if (this.piskelName) { this.piskelName.classList.add('piskel-name-saving'); } }; + ns.SaveController.prototype.updatePiskelDescriptor_ = function () { + var name = this.getName(); + var description = this.getDescription(); + var isPublic = !!this.isPublicCheckbox.prop('checked'); + + var descriptor = new pskl.model.piskel.Descriptor(name, description, isPublic); + this.piskelController.getPiskel().setDescriptor(descriptor); + }; + ns.SaveController.prototype.onSaveSuccess_ = function () { $.publish(Events.CLOSE_SETTINGS_DRAWER); $.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]); @@ -103,8 +119,8 @@ }; ns.SaveController.prototype.afterSaving_ = function () { - this.saveCloudButton.attr('disabled', false); - this.status.html(''); + this.saveOnlineButton.attr('disabled', false); + this.submitButton.html(''); if (this.piskelName) { this.piskelName.classList.remove('piskel-name-saving'); diff --git a/src/js/controller/settings/SettingsController.js b/src/js/controller/settings/SettingsController.js index f8c5fd89..5246fc0c 100644 --- a/src/js/controller/settings/SettingsController.js +++ b/src/js/controller/settings/SettingsController.js @@ -10,12 +10,8 @@ template : 'templates/settings/resize.html', controller : ns.ResizeController }, - 'gif' : { - template : 'templates/settings/export-gif.html', - controller : ns.GifExportController - }, 'png' : { - template : 'templates/settings/export-png.html', + template : 'templates/settings/export.html', controller : ns.PngExportController }, 'import' : { diff --git a/src/js/utils/ImageToBlob.js b/src/js/utils/BlobUtils.js similarity index 71% rename from src/js/utils/ImageToBlob.js rename to src/js/utils/BlobUtils.js index 49fe7278..8ef595bf 100644 --- a/src/js/utils/ImageToBlob.js +++ b/src/js/utils/BlobUtils.js @@ -3,8 +3,8 @@ var BASE64_REGEX = /\s*;\s*base64\s*(?:;|$)/i; - ns.ImageToBlob = { - imageDataToBlob : function(dataURI, type, callback) { + ns.BlobUtils = { + dataToBlob : function(dataURI, type, callback) { var header_end = dataURI.indexOf(","), data = dataURI.substring(header_end + 1), isBase64 = BASE64_REGEX.test(dataURI.substring(0, header_end)), @@ -26,13 +26,18 @@ canvasToBlob : function(canvas, callback, type /*, ...args*/) { type = type || "image/png"; - if (this.mozGetAsFile) { - callback(this.mozGetAsFile("canvas", type)); + if (canvas.mozGetAsFile) { + callback(canvas.mozGetAsFile("canvas", type)); } else { var args = Array.prototype.slice.call(arguments, 2); var dataURI = canvas.toDataURL.apply(canvas, args); - pskl.utils.ImageToBlob.imageDataToBlob(dataURI, type, callback); + pskl.utils.BlobUtils.dataToBlob(dataURI, type, callback); } + }, + + stringToBlob : function (string, callback, type) { + type = type || "text/plain"; + pskl.utils.BlobUtils.dataToBlob('data:'+type+',' + string, type, callback); } }; })(); \ No newline at end of file diff --git a/src/js/utils/DateUtils.js b/src/js/utils/DateUtils.js new file mode 100644 index 00000000..3e45e28c --- /dev/null +++ b/src/js/utils/DateUtils.js @@ -0,0 +1,24 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + var pad = function (num) { + if (num < 10) { + return "0" + num; + } else { + return "" + num; + } + }; + + ns.DateUtils = { + format : function (date, format) { + return pskl.utils.Template.replace(format, { + Y : date.getFullYear(), + M : pad(date.getMonth() + 1), + D : pad(date.getDate()), + H : pad(date.getHours()), + m : pad(date.getMinutes()), + s : pad(date.getSeconds()) + }); + } + }; +})(); \ No newline at end of file diff --git a/src/js/utils/FileUtils.js b/src/js/utils/FileUtils.js index 3b87cdcd..48cd9349 100644 --- a/src/js/utils/FileUtils.js +++ b/src/js/utils/FileUtils.js @@ -10,7 +10,7 @@ reader.readAsDataURL(file); }, - downloadAsFile : function (filename, content) { + downloadAsFile : function (content, filename) { var saveAs = window.saveAs || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator)); if (saveAs) { saveAs(content, filename); diff --git a/src/js/utils/Template.js b/src/js/utils/Template.js index 01c9671d..9a311d8b 100644 --- a/src/js/utils/Template.js +++ b/src/js/utils/Template.js @@ -17,6 +17,15 @@ return dummyEl.children[0]; }, + getAndReplace : function (templateId, dict) { + var result = ""; + var tpl = pskl.utils.Template.get(templateId); + if (tpl) { + result = pskl.utils.Template.replace(tpl, dict); + } + return result; + }, + replace : function (template, dict) { for (var key in dict) { if (dict.hasOwnProperty(key)) { diff --git a/src/js/utils/serialization/Serializer.js b/src/js/utils/serialization/Serializer.js index 271d41ae..c9ab9f3d 100644 --- a/src/js/utils/serialization/Serializer.js +++ b/src/js/utils/serialization/Serializer.js @@ -9,6 +9,9 @@ return JSON.stringify({ modelVersion : Constants.MODEL_VERSION, piskel : { + name : piskel.getDescriptor().name, + description : piskel.getDescriptor().description, + fps : pskl.app.piskelController.getFPS(), height : piskel.getHeight(), width : piskel.getWidth(), layers : serializedLayers, diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index cbdc0061..ee496705 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -24,13 +24,14 @@ "js/utils/core.js", "js/utils/UserAgent.js", "js/utils/Base64.js", + "js/utils/BlobUtils.js", "js/utils/CanvasUtils.js", + "js/utils/DateUtils.js", "js/utils/Dom.js", "js/utils/Math.js", "js/utils/FileUtils.js", "js/utils/FrameUtils.js", "js/utils/LayerUtils.js", - "js/utils/ImageToBlob.js", "js/utils/ImageResizer.js", "js/utils/PixelUtils.js", "js/utils/Template.js", diff --git a/src/templates/settings.html b/src/templates/settings.html index 24760296..ea267928 100644 --- a/src/templates/settings.html +++ b/src/templates/settings.html @@ -1,10 +1,5 @@
-
-
+
+
+
+
-
-
+
--> -
ANIM -
+ -->
- SHEET
\ No newline at end of file diff --git a/src/templates/settings/export-gif.html b/src/templates/settings/export-gif.html deleted file mode 100644 index 525fa1cc..00000000 --- a/src/templates/settings/export-gif.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
- Export to Animated GIF -
-
-
- - -
- - - -
- -
-
-
-
-
\ No newline at end of file diff --git a/src/templates/settings/export-png.html b/src/templates/settings/export-png.html deleted file mode 100644 index 08c9ee66..00000000 --- a/src/templates/settings/export-png.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
- Export Spritesheet as PNG -
-
- Preview : -
-
- - - -
-
-
- Export Spritesheet as ZIP -
-
- A ZIP archive will be created with one PNG file per frame. -
- -
-
-
\ No newline at end of file diff --git a/src/templates/settings/export.html b/src/templates/settings/export.html new file mode 100644 index 00000000..7a32c810 --- /dev/null +++ b/src/templates/settings/export.html @@ -0,0 +1,40 @@ +
+
+ Export Spritesheet +
+
+
+ PNG with all frames side by side. + +
+
+ ZIP with one PNG file per frame. +
+ +
+
+
+ Export to Animated GIF +
+
+
+
+ + + +
+
+ + +
+
+
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/src/templates/settings/import.html b/src/templates/settings/import.html index 6041cd3b..968784cf 100644 --- a/src/templates/settings/import.html +++ b/src/templates/settings/import.html @@ -1,33 +1,50 @@
- Import Picture + Open Piskel Project +
+
+
+ Load a .piskel file from your computer. + +
+ + + +
+
+
+
+ Import From Picture
+
Supports : PNG, JPG, BMP, Animated GIF ...
- File : - +
-
- Info : -
-
-
- Size : - x - -
-
- Smooth resize : - -
- - Animated GIFs will be split in several frames. Other images will be imported as a single-frame. +
+
+ Info : +
+
+
+ Size : + x + +
+
+ Smooth resize : + +
+ +
diff --git a/src/templates/settings/save.html b/src/templates/settings/save.html index 54e6a126..78be0253 100644 --- a/src/templates/settings/save.html +++ b/src/templates/settings/save.html @@ -1,7 +1,7 @@
-
Save
-
-
+ +
Describe your piskel
+
@@ -10,14 +10,29 @@
-
+
- - -
- -
+
+
Save online
+
+ +
+
+
Download Project
+
+
+ +
+ + + + +
\ No newline at end of file