From 564f74265ab7f354d01d3ab17b22f38b8bd0f5e8 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Tue, 8 Oct 2013 23:44:06 +0200 Subject: [PATCH 1/3] Piskel website adaptations : M CanvasRenderer : can set the color used to represent transparency M app.js : modified code responsible for saving when in website mode M PiskelController.js : just some argument renaming --- js/app.js | 6 +++++- js/controller/PiskelController.js | 8 ++++++-- js/rendering/CanvasRenderer.js | 19 +++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/js/app.js b/js/app.js index 529e201b..8ad7af28 100644 --- a/js/app.js +++ b/js/app.js @@ -180,7 +180,11 @@ formData.append('frames', this.piskelController.getFrameCount()); // Get image/png data for first frame - formData.append('preview', this.getFirstFrameAsPNGData_()); + var firstFrame = this.piskelController.getFrameAt(0); + var frameRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); + frameRenderer.drawTransparentAs('rgba(0,0,0,0)'); + var firstFrameCanvas = frameRenderer.render().canvas; + formData.append('preview', firstFrameCanvas.toDataURL("image/png")); var imageData = (new pskl.rendering.SpritesheetRenderer(this.piskelController)).renderAsImageDataSpritesheetPNG(); formData.append('framesheet', imageData); diff --git a/js/controller/PiskelController.js b/js/controller/PiskelController.js index 6ae26503..17cf84f6 100644 --- a/js/controller/PiskelController.js +++ b/js/controller/PiskelController.js @@ -184,9 +184,13 @@ return pskl.utils.Serializer.serializePiskel(this.piskel); }; - ns.PiskelController.prototype.deserialize = function (json) { + ns.PiskelController.prototype.load = function (data) { + this.deserialize(JSON.stringify(data)); + }; + + ns.PiskelController.prototype.deserialize = function (jsonStr) { try { - var piskel = pskl.utils.Serializer.deserializePiskel(json); + var piskel = pskl.utils.Serializer.deserializePiskel(jsonStr); this.setPiskel(piskel); } catch (e) { console.error('Failed to deserialize'); diff --git a/js/rendering/CanvasRenderer.js b/js/rendering/CanvasRenderer.js index 1a9f94d8..2153f207 100644 --- a/js/rendering/CanvasRenderer.js +++ b/js/rendering/CanvasRenderer.js @@ -4,9 +4,19 @@ ns.CanvasRenderer = function (frame, dpi) { this.frame = frame; this.dpi = dpi; + this.transparentColor_ = 'white'; }; - ns.CanvasRenderer.prototype.render = function (frame, dpi) { + /** + * Decide which color should be used to represent transparent pixels + * Default : white + * @param {String} color the color to use either as '#ABCDEF' or 'red' or 'rgb(x,y,z)' or 'rgba(x,y,z,a)' + */ + ns.CanvasRenderer.prototype.drawTransparentAs = function (color) { + this.transparentColor_ = color; + }; + + ns.CanvasRenderer.prototype.render = function () { var canvas = this.createCanvas_(); var context = canvas.getContext('2d'); for(var col = 0, width = this.frame.getWidth(); col < width; col++) { @@ -20,11 +30,12 @@ }; ns.CanvasRenderer.prototype.renderPixel_ = function (color, col, row, context) { - if(color == Constants.TRANSPARENT_COLOR) { - color = "#FFF"; - } + if(color == Constants.TRANSPARENT_COLOR) { + color = this.transparentColor_; + } context.fillStyle = color; + context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi); }; From 55e3607eccf335d5e12e3bed89a23ab5b4e3c90c Mon Sep 17 00:00:00 2001 From: jdescottes Date: Thu, 10 Oct 2013 00:06:11 +0200 Subject: [PATCH 2/3] Cleanup of saving/loading process --- js/Constants.js | 12 ++- js/app.js | 150 +++++++++++++++++----------- js/controller/PiskelController.js | 16 +-- js/rendering/SpritesheetRenderer.js | 4 +- js/utils/Serializer.js | 27 +++-- 5 files changed, 125 insertions(+), 84 deletions(-) diff --git a/js/Constants.js b/js/Constants.js index 1bba84bc..fd0bcdc2 100644 --- a/js/Constants.js +++ b/js/Constants.js @@ -31,7 +31,17 @@ var Constants = { /* * Default entry point for piskel web service: */ - PISKEL_SERVICE_URL: 'http://3.piskel-app.appspot.com', + STATIC : { + URL : { + SAVE : 'http://3.piskel-app.appspot.com/store', + GET : 'http://3.piskel-app.appspot.com/get' + } + }, + APPENGINE : { + URL : { + SAVE : 'save' + } + }, IMAGE_SERVICE_UPLOAD_URL : 'http://screenletstore.appspot.com/__/upload', IMAGE_SERVICE_GET_URL : 'http://screenletstore.appspot.com/img/', diff --git a/js/app.js b/js/app.js index 8ad7af28..def736df 100644 --- a/js/app.js +++ b/js/app.js @@ -73,20 +73,29 @@ this.isStaticVersion = !pskl.appEngineToken_; if (this.isStaticVersion) { - var framesheetId = this.readFramesheetIdFromURL_(); - if (framesheetId) { - $.publish(Events.SHOW_NOTIFICATION, [{ - "content" : "Loading animation with id : [" + framesheetId + "]" - }]); - this.loadFramesheetFromService(framesheetId); - } else { - this.localStorageService.displayRestoreNotification(); - } + this.finishInitStatic_(); } else { - if (pskl.framesheetData_ && pskl.framesheetData_.content) { - this.piskelController.load(pskl.framesheetData_.content); - pskl.app.animationController.setFPS(pskl.framesheetData_.fps); - } + this.finishInitAppEngine_(); + } + }, + + finishInitStatic_ : function () { + var framesheetId = this.readFramesheetIdFromURL_(); + if (framesheetId) { + $.publish(Events.SHOW_NOTIFICATION, [{ + "content" : "Loading animation with id : [" + framesheetId + "]" + }]); + this.loadFramesheetFromService(framesheetId); + } else { + this.localStorageService.displayRestoreNotification(); + } + }, + + finishInitAppEngine_ : function () { + if (pskl.framesheetData_ && pskl.framesheetData_.content) { + var piskel = pskl.utils.Serializer.createPiskel(pskl.framesheetData_.content); + piskel.app.PiskelController.setPiskel(piskel); + pskl.app.animationController.setFPS(pskl.framesheetData_.fps); } }, @@ -143,12 +152,12 @@ loadFramesheetFromService : function (frameId) { var xhr = new XMLHttpRequest(); - xhr.open('GET', Constants.PISKEL_SERVICE_URL + '/get?l=' + frameId, true); + xhr.open('GET', Constants.STATIC.URL.GET + '?l=' + frameId, true); xhr.responseType = 'text'; - var piskelController = this.piskelController; xhr.onload = function (e) { var res = JSON.parse(this.responseText); - piskelController.deserialize(JSON.stringify(res.framesheet)); + var piskel = pskl.utils.Serializer.createPiskel(res.framesheet); + pskl.app.piskelController.setPiskel(piskel); pskl.app.animationController.setFPS(res.fps); $.publish(Events.HIDE_NOTIFICATION); }; @@ -160,55 +169,13 @@ xhr.send(); }, - getFirstFrameAsPNGData_ : function () { - throw 'getFirstFrameAsPNGData_ not implemented'; - }, - - // TODO(julz): Create package ? storeSheet : function (event) { - var xhr = new XMLHttpRequest(); - var formData = new FormData(); - formData.append('framesheet_content', this.piskelController.serialize()); - formData.append('fps_speed', $('#preview-fps').val()); - if (this.isStaticVersion) { - // anonymous save on old app-engine backend - xhr.open('POST', Constants.PISKEL_SERVICE_URL + "/store", true); + this.storeSheetStatic_(); } else { - // additional values only used with latest app-engine backend - formData.append('name', $('#piskel-name').val()); - formData.append('frames', this.piskelController.getFrameCount()); - - // Get image/png data for first frame - var firstFrame = this.piskelController.getFrameAt(0); - var frameRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); - frameRenderer.drawTransparentAs('rgba(0,0,0,0)'); - var firstFrameCanvas = frameRenderer.render().canvas; - formData.append('preview', firstFrameCanvas.toDataURL("image/png")); - - var imageData = (new pskl.rendering.SpritesheetRenderer(this.piskelController)).renderAsImageDataSpritesheetPNG(); - formData.append('framesheet', imageData); - - xhr.open('POST', "save", true); + this.storeSheetAppEngine_(); } - xhr.onload = function(e) { - if (this.status == 200) { - if (pskl.app.isStaticVersion) { - var baseUrl = window.location.href.replace(window.location.search, ""); - window.location.href = baseUrl + "?frameId=" + this.responseText; - } else { - $.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]); - } - } else { - this.onerror(e); - } - }; - xhr.onerror = function(e) { - $.publish(Events.SHOW_NOTIFICATION, [{"content": "Saving failed ("+this.status+")"}]); - }; - xhr.send(formData); - if(event) { event.stopPropagation(); event.preventDefault(); @@ -216,8 +183,69 @@ return false; }, + storeSheetStatic_ : function () { + var xhr = new XMLHttpRequest(); + var formData = new FormData(); + formData.append('framesheet_content', this.piskelController.serialize()); + formData.append('fps_speed', $('#preview-fps').val()); + + xhr.open('POST', Constants.STATIC.URL.SAVE, true); + + xhr.onload = function(e) { + if (this.status == 200) { + var baseUrl = window.location.href.replace(window.location.search, ""); + window.location.href = baseUrl + "?frameId=" + this.responseText; + } else { + this.onerror(e); + } + }; + xhr.onerror = function(e) { + $.publish(Events.SHOW_NOTIFICATION, [{"content": "Saving failed ("+this.status+")"}]); + }; + xhr.send(formData); + }, + + storeSheetAppEngine_ : function () { + var xhr = new XMLHttpRequest(); + var formData = new FormData(); + formData.append('framesheet_content', this.piskelController.serialize()); + formData.append('fps_speed', $('#preview-fps').val()); + formData.append('name', $('#piskel-name').val()); + formData.append('frames', this.piskelController.getFrameCount()); + formData.append('preview', this.getFirstFrameAsPng()); + formData.append('framesheet', this.getFramesheetAsPng()); + + xhr.open('POST', Constants.APPENGINE.URL.SAVE, true); + + xhr.onload = function(e) { + if (this.status == 200) { + $.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]); + } else { + this.onerror(e); + } + }; + xhr.onerror = function(e) { + $.publish(Events.SHOW_NOTIFICATION, [{"content": "Saving failed ("+this.status+")"}]); + }; + xhr.send(formData); + }, + + getFirstFrameAsPng : function () { + var firstFrame = this.piskelController.getFrameAt(0); + var frameRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); + frameRenderer.drawTransparentAs('rgba(0,0,0,0)'); + var firstFrameCanvas = frameRenderer.render().canvas; + return firstFrameCanvas.toDataURL("image/png"); + }, + + getFramesheetAsPng : function () { + var renderer = new pskl.rendering.SpritesheetRenderer(this.piskelController); + var framesheetCanvas = renderer.render(); + return framesheetCanvas.toDataURL("image/png"); + }, + uploadAsSpritesheetPNG : function () { - var imageData = (new pskl.rendering.SpritesheetRenderer(this.piskelController)).renderAsImageDataSpritesheetPNG(); + var imageData = this.getFramesheetAsPng(); this.imageUploadService.upload(imageData, this.openWindow.bind(this)); }, diff --git a/js/controller/PiskelController.js b/js/controller/PiskelController.js index 17cf84f6..8d102322 100644 --- a/js/controller/PiskelController.js +++ b/js/controller/PiskelController.js @@ -2,7 +2,11 @@ var ns = $.namespace('pskl.controller'); ns.PiskelController = function (piskel) { - this.setPiskel(piskel); + if (piskel) { + this.setPiskel(piskel); + } else { + throw 'A piskel instance is mandatory for instanciating PiskelController'; + } }; ns.PiskelController.prototype.setPiskel = function (piskel) { @@ -187,14 +191,4 @@ ns.PiskelController.prototype.load = function (data) { this.deserialize(JSON.stringify(data)); }; - - ns.PiskelController.prototype.deserialize = function (jsonStr) { - try { - var piskel = pskl.utils.Serializer.deserializePiskel(jsonStr); - this.setPiskel(piskel); - } catch (e) { - console.error('Failed to deserialize'); - console.error(e.stack); - } - }; })(); \ No newline at end of file diff --git a/js/rendering/SpritesheetRenderer.js b/js/rendering/SpritesheetRenderer.js index 8162f7fa..d634da0f 100644 --- a/js/rendering/SpritesheetRenderer.js +++ b/js/rendering/SpritesheetRenderer.js @@ -6,13 +6,13 @@ this.piskelController = piskelController; }; - ns.SpritesheetRenderer.prototype.renderAsImageDataSpritesheetPNG = function () { + ns.SpritesheetRenderer.prototype.render = function () { var canvas = this.createCanvas_(); for (var i = 0 ; i < this.piskelController.getFrameCount() ; i++) { var frame = this.piskelController.getFrameAt(i); this.drawFrameInCanvas_(frame, canvas, i * this.piskelController.getWidth(), 0); } - return canvas.toDataURL("image/png"); + return canvas; }; /** diff --git a/js/utils/Serializer.js b/js/utils/Serializer.js index a4493191..a7115d51 100644 --- a/js/utils/Serializer.js +++ b/js/utils/Serializer.js @@ -25,11 +25,20 @@ }); }, - deserializePiskel : function (json) { + deserializePiskel : function (piskelString) { + var piskelData = JSON.parse(piskelString); + return this.createPiskelFromData(piskelData); + }, + + /** + * Similar to deserializePiskel, but dealing directly with a parsed piskel + * @param {Object} piskelData JSON.parse of a serialized piskel + * @return {Piskel} a piskel + */ + createPiskel : function (piskelData) { var piskel = null; - var data = JSON.parse(json); - if (data.modelVersion == Constants.MODEL_VERSION) { - var pData = data.piskel; + if (piskelData.modelVersion == Constants.MODEL_VERSION) { + var pData = piskelData.piskel; piskel = new pskl.model.Piskel(pData.width, pData.height); pData.layers.forEach(function (serializedLayer) { @@ -37,14 +46,14 @@ piskel.addLayer(layer); }); } else { - piskel = pskl.utils.Serializer.backwardDeserializer_(data); + piskel = pskl.utils.Serializer.backwardDeserializer_(piskelData); } return piskel; }, - deserializeLayer : function (json) { - var lData = JSON.parse(json); + deserializeLayer : function (layerString) { + var lData = JSON.parse(layerString); var layer = new pskl.model.Layer(lData.name); lData.frames.forEach(function (serializedFrame) { @@ -55,8 +64,8 @@ return layer; }, - deserializeFrame : function (json) { - var framePixelGrid = JSON.parse(json); + deserializeFrame : function (frameString) { + var framePixelGrid = JSON.parse(frameString); return pskl.model.Frame.fromPixelGrid(framePixelGrid); }, From 4527846ad6cee812a1566477873169f38252ec3c Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Thu, 10 Oct 2013 13:35:18 +0200 Subject: [PATCH 3/3] PR138#commitcomment-4293036 use full namespace when specifying a classtype See https://github.com/juliandescottes/piskel/pull/138#commitcomment-4293036 --- js/utils/Serializer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/utils/Serializer.js b/js/utils/Serializer.js index a7115d51..0006acab 100644 --- a/js/utils/Serializer.js +++ b/js/utils/Serializer.js @@ -33,7 +33,7 @@ /** * Similar to deserializePiskel, but dealing directly with a parsed piskel * @param {Object} piskelData JSON.parse of a serialized piskel - * @return {Piskel} a piskel + * @return {pskl.model.Piskel} a piskel */ createPiskel : function (piskelData) { var piskel = null; @@ -84,4 +84,4 @@ return piskel; } }; -})(); \ No newline at end of file +})();