From 869f3d2e005ca0e9debffe51ed897e1e9b7f78b7 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sat, 8 Sep 2012 17:57:21 +0200 Subject: [PATCH 01/30] fixed bug when resizing --- js/controller/DrawingController.js | 2 +- js/drawingtools/Move.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index f6043669..d6803593 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -26,7 +26,7 @@ this.overlayRenderer.updateDPI(newDPI); this.renderer.render(this.frame); - this.overlayRenderer.render(this.frame); + this.overlayRenderer.render(this.overlayFrame); }; ns.DrawingController.prototype.renderFrame = function () { diff --git a/js/drawingtools/Move.js b/js/drawingtools/Move.js index 8a36e36f..2ff9ca73 100644 --- a/js/drawingtools/Move.js +++ b/js/drawingtools/Move.js @@ -12,8 +12,6 @@ // Stroke's first point coordinates (set in applyToolAt) this.startCol = null; this.startRow = null; - - this.canvasOverlay = null; }; pskl.utils.inherit(ns.Move, ns.BaseTool); From df405d917fe35a484d117ddf31185160cff1378e Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sat, 8 Sep 2012 18:15:53 +0200 Subject: [PATCH 02/30] Clone pixels pug --- js/model/Frame.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/model/Frame.js b/js/model/Frame.js index bef3e94c..b8c7a5eb 100644 --- a/js/model/Frame.js +++ b/js/model/Frame.js @@ -48,7 +48,7 @@ ns.Frame.prototype.clonePixels_ = function (pixels) { var clonedPixels = []; for (var col = 0 ; col < pixels.length ; col++) { - clonedPixels[col] = pixels[col].slice(0 , pixels[col].length-1); + clonedPixels[col] = pixels[col].slice(0 , pixels[col].length); } return clonedPixels; }; From 9dc7afee612193617e4c5a737b3299201e188802 Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 18:44:06 +0200 Subject: [PATCH 03/30] Moving drawing canvas code from piskel.js to drawingController.js --- js/Events.js | 7 ++ js/controller/DrawingController.js | 167 ++++++++++++++++++++++++ js/controller/PreviewFilmController.js | 13 +- js/piskel.js | 168 ++----------------------- js/rendering/FrameRenderer.js | 2 +- 5 files changed, 192 insertions(+), 165 deletions(-) diff --git a/js/Events.js b/js/Events.js index 2a1545b8..df4dfb89 100644 --- a/js/Events.js +++ b/js/Events.js @@ -22,6 +22,13 @@ Events = { */ REFRESH: "REFRESH", + /** + * Temporary event to bind the redraw of right preview film to the canvas. + * This redraw should be driven by model updates. + * TODO(vincz): Remove. + */ + REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM", + /** * The framesheet was reseted and is now probably drastically different. * Number of frames, content of frames, color used for the palette may have changed. diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index f6043669..66559fc1 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -19,8 +19,175 @@ this.renderer.init(this.frame); this.overlayRenderer.init(this.frame); + + // State of drawing controller: + this.isClicked = false; + this.isRightClicked = false; + this.previousMousemoveTime = 0; + this.currentToolBehavior = null; + this.primaryColor = Constants.DEFAULT_PEN_COLOR; + this.secondaryColor = Constants.TRANSPARENT_COLOR; + + this.initMouseBehavior(); + + $.subscribe(Events.TOOL_SELECTED, $.proxy(function(evt, toolBehavior) { + + console.log("Tool selected: ", toolBehavior); + this.currentToolBehavior = toolBehavior; + }, this)); + + $.subscribe(Events.COLOR_SELECTED, $.proxy(function(evt, color, isPrimary) { + console.log("Color selected: ", color); + if (isPrimary) { + this.primaryColor = color; + } else { + this.secondaryColor = color; + } + }, this)); }; + ns.DrawingController.prototype.initMouseBehavior = function() { + var body = $('body'); + this.container.mousedown($.proxy(this.onMousedown_, this)); + this.container.mousemove($.proxy(this.onMousemove_, this)); + body.mouseup($.proxy(this.onMouseup_, this)); + + // Deactivate right click: + this.container.contextmenu(this.onCanvasContextMenu_); + }; + + /** + * @private + */ + ns.DrawingController.prototype.onMousedown_ = function (event) { + this.isClicked = true; + + if(event.button == 2) { // right click + this.isRightClicked = true; + $.publish(Events.CANVAS_RIGHT_CLICKED); + } + + var spriteCoordinate = this.getSpriteCoordinate(event); + //console.log("mousedown: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); + + this.currentToolBehavior.applyToolAt( + spriteCoordinate.col, + spriteCoordinate.row, + this.getCurrentColor_(), + this + ); + + $.publish(Events.LOCALSTORAGE_REQUEST); + }; + + /** + * @private + */ + ns.DrawingController.prototype.onMousemove_ = function (event) { + var currentTime = new Date().getTime(); + // Throttling of the mousemove event: + if ((currentTime - this.previousMousemoveTime) > 40 ) { + var spriteCoordinate = this.getSpriteCoordinate(event); + if (this.isClicked) { + + this.currentToolBehavior.moveToolAt( + spriteCoordinate.col, + spriteCoordinate.row, + this.getCurrentColor_(), + this + ); + + //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); + + // TODO(vincz): Find a way to move that to the model instead of being at the interaction level. + // Eg when drawing, it may make sense to have it here. However for a non drawing tool, + // you don't need to draw anything when mousemoving and you request useless localStorage. + $.publish(Events.LOCALSTORAGE_REQUEST); + } else { + // debug mode to see the selected pixel + // this.clearOverlay(); + // this.overlayFrame.setPixel( spriteCoordinate.col,spriteCoordinate.row, "#ff0000"); + // this.renderOverlay(); + } + this.previousMousemoveTime = currentTime; + } + }; + + /** + * @private + */ + ns.DrawingController.prototype.onMouseup_ = function (event) { + if(this.isClicked || this.isRightClicked) { + // A mouse button was clicked on the drawing canvas before this mouseup event, + // the user was probably drawing on the canvas. + // Note: The mousemove movement (and the mouseup) may end up outside + // of the drawing canvas. + if(this.isRightClicked) { + $.publish(Events.CANVAS_RIGHT_CLICK_RELEASED); + } + + + this.isClicked = false; + this.isRightClicked = false; + var spriteCoordinate = this.getSpriteCoordinate(event); + console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); + this.currentToolBehavior.releaseToolAt( + spriteCoordinate.col, + spriteCoordinate.row, + this.getCurrentColor_(), + this + ); + + $.publish(Events.TOOL_RELEASED); + + // TODO: Remove that when we have the centralized redraw loop + $.publish(Events.REDRAW_PREVIEWFILM); + } + }, + + /** + * @private + */ + ns.DrawingController.prototype.getRelativeCoordinates = function (clientX, clientY) { + var canvasPageOffset = this.container.offset(); + return { + x : clientX - canvasPageOffset.left, + y : clientY - canvasPageOffset.top + } + }; + + /** + * @private + */ + ns.DrawingController.prototype.getSpriteCoordinate = function(event) { + var coords = this.getRelativeCoordinates(event.clientX, event.clientY); + return { + "col" : (coords.x - coords.x % this.dpi) / this.dpi, + "row" : (coords.y - coords.y % this.dpi) / this.dpi + } + }; + + /** + * @private + */ + ns.DrawingController.prototype.getCurrentColor_ = function () { + if(this.isRightClicked) { + return this.secondaryColor; + } else { + return this.primaryColor; + } + }; + + /** + * @private + */ + ns.DrawingController.prototype.onCanvasContextMenu_ = function (event) { + event.preventDefault(); + event.stopPropagation(); + event.cancelBubble = true; + return false; + }; + ns.DrawingController.prototype.updateDPI = function (newDPI) { this.renderer.updateDPI(newDPI); this.overlayRenderer.updateDPI(newDPI); diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js index 75383df0..7d7a2fe6 100644 --- a/js/controller/PreviewFilmController.js +++ b/js/controller/PreviewFilmController.js @@ -5,6 +5,10 @@ this.dpi = dpi; this.framesheet = framesheet; this.container = container; + + $.subscribe(Events.REDRAW_PREVIEWFILM, $.proxy(function(evt) { + this.createPreviews() + }, this)); }; ns.PreviewFilmController.prototype.init = function() { @@ -28,7 +32,7 @@ for (var i = 0, l = frameCount; i < l ; i++) { this.container.append(this.createInterstitialTile_(i)); - this.container.append(this.createPreviewTile_(i)); + this.container.append(this.createPreviewTile_(i, this.framesheet)); } this.container.append(this.createInterstitialTile_(frameCount)); @@ -142,7 +146,7 @@ * @private * TODO(vincz): clean this giant rendering function & remove listeners. */ - ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) { + ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber, framesheet) { var currentFrame = this.framesheet.getFrameByIndex(tileNumber); //var width = frame.getWidth() * this.dpi, // height = frame.getHeight() * this.dpi; @@ -183,7 +187,8 @@ canvasPreviewDuplicateAction.innerHTML = "dup" canvasPreviewDuplicateAction.addEventListener('click', function(evt) { - piskel.duplicateFrame(tileNumber); + framesheet.duplicateFrameByIndex(tileNumber); + $.publish('SET_ACTIVE_FRAME', [tileNumber + 1]); }); //this.renderer.render(this.framesheet.getFrameByIndex(tileNumber), canvasPreview); @@ -191,7 +196,7 @@ // TODO(vincz): Eventually optimize this part by not recreating a FrameRenderer. Note that the real optim // is to make this update function (#createPreviewTile) less aggressive. var renderingOptions = {"dpi": this.dpi }; - var currentFrameRenderer = new pskl.rendering.FrameRenderer(canvasContainer, renderingOptions, "tile-view"); + var currentFrameRenderer = new pskl.rendering.FrameRenderer($(canvasContainer), renderingOptions, "tile-view"); currentFrameRenderer.init(currentFrame); previewTileRoot.appendChild(canvasContainer); diff --git a/js/piskel.js b/js/piskel.js index af4f7a79..fde522b4 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -24,23 +24,8 @@ $.namespace("pskl"); // Animated canvas preview: previewAnimationCanvasDpi = 8, - // DOM references: - drawingAreaContainer, - drawingAreaCanvas, - previewCanvas, - - // States: - isClicked = false, - isRightClicked = false, - activeFrameIndex = -1, - animIndex = 0, - - primaryColor = Constants.DEFAULT_PEN_COLOR, - secondaryColor = Constants.TRANSPARENT_COLOR, - + activeFrameIndex = -1, currentFrame = null; - currentToolBehavior = null, - previousMousemoveTime = 0; /** * Main application controller @@ -56,7 +41,7 @@ $.namespace("pskl"); this.drawingController = new pskl.controller.DrawingController( frameSheet.getFrameByIndex(0), - $('#drawing-canvas-container')[0], + $('#drawing-canvas-container'), drawingCanvasDpi ); @@ -64,7 +49,7 @@ $.namespace("pskl"); this.animationController = new pskl.controller.AnimatedPreviewController( frameSheet, - $('#preview-canvas-container')[0], + $('#preview-canvas-container'), previewAnimationCanvasDpi ); @@ -91,6 +76,10 @@ $.namespace("pskl"); this.finishInit(); pskl.LocalStorageService.displayRestoreNotification(); } + + $.subscribe('SET_ACTIVE_FRAME', function(evt, frameId) { + piskel.setActiveFrameAndRedraw(frameId); + }); }, /** @@ -118,27 +107,12 @@ $.namespace("pskl"); finishInit : function () { - $.subscribe(Events.TOOL_SELECTED, function(evt, toolBehavior) { - console.log("Tool selected: ", toolBehavior); - currentToolBehavior = toolBehavior; - }); - - $.subscribe(Events.COLOR_SELECTED, function(evt, color, isPrimary) { - console.log("Color selected: ", color); - if (isPrimary) { - primaryColor = color; - } else { - secondaryColor = color; - } - }); + $.subscribe(Events.REFRESH, function() { piskel.setActiveFrameAndRedraw(0); }); - // TODO: Move this into their service or behavior files: - this.initDrawingArea(); - pskl.ToolSelector.init(); pskl.Palette.init(frameSheet); }, @@ -202,132 +176,6 @@ $.namespace("pskl"); return frameSheet.getFrameByIndex(activeFrameIndex); }, - initDrawingArea : function() { - drawingAreaContainer = $('#drawing-canvas-container')[0]; - document.body.addEventListener('mouseup', this.onMouseup.bind(this)); - drawingAreaContainer.addEventListener('mousedown', this.onMousedown.bind(this)); - drawingAreaContainer.addEventListener('mousemove', this.onMousemove.bind(this)); - document.body.addEventListener('contextmenu', this.onCanvasContextMenu); - }, - - removeFrame: function(frameIndex) { - frameSheet.removeFrameByIndex(frameIndex); - var activeFrameIndex = frameIndex ? frameIndex - 1 : 0; - this.setActiveFrameAndRedraw(activeFrameIndex); - }, - - duplicateFrame: function(frameIndex) { - frameSheet.duplicateFrameByIndex(frameIndex); - this.setActiveFrameAndRedraw(frameIndex + 1); - }, - - getCurrentColor : function () { - if(isRightClicked) { - return secondaryColor; - } else { - return primaryColor; - } - }, - - onMousedown : function (event) { - isClicked = true; - - if(event.button == 2) { // right click - isRightClicked = true; - $.publish(Events.CANVAS_RIGHT_CLICKED); - } - - var spriteCoordinate = this.getSpriteCoordinate(event); - currentToolBehavior.applyToolAt( - spriteCoordinate.col, - spriteCoordinate.row, - this.getCurrentColor(), - this.drawingController - ); - - $.publish(Events.LOCALSTORAGE_REQUEST); - }, - - onMousemove : function (event) { - var currentTime = new Date().getTime(); - // Throttling of the mousemove event: - if ((currentTime - previousMousemoveTime) > 40 ) { - var spriteCoordinate = this.getSpriteCoordinate(event); - if (isClicked) { - - currentToolBehavior.moveToolAt( - spriteCoordinate.col, - spriteCoordinate.row, - this.getCurrentColor(), - this.drawingController - ); - - // TODO(vincz): Find a way to move that to the model instead of being at the interaction level. - // Eg when drawing, it may make sense to have it here. However for a non drawing tool, - // you don't need to draw anything when mousemoving and you request useless localStorage. - $.publish(Events.LOCALSTORAGE_REQUEST); - } else { - // debug mode to see the selected pixel - // this.drawingController.clearOverlay(); - // this.drawingController.overlay.setPixel( spriteCoordinate.col,spriteCoordinate.row, "#ff0000"); - // this.drawingController.renderOverlay(); - } - previousMousemoveTime = currentTime; - } - }, - - onMouseup : function (event) { - if(isClicked || isRightClicked) { - // A mouse button was clicked on the drawing canvas before this mouseup event, - // the user was probably drawing on the canvas. - // Note: The mousemove movement (and the mouseup) may end up outside - // of the drawing canvas. - if(isRightClicked) { - $.publish(Events.CANVAS_RIGHT_CLICK_RELEASED); - } - - - isClicked = false; - isRightClicked = false; - var spriteCoordinate = this.getSpriteCoordinate(event); - currentToolBehavior.releaseToolAt( - spriteCoordinate.col, - spriteCoordinate.row, - this.getCurrentColor(), - this.drawingController - ); - - - $.publish(Events.TOOL_RELEASED); - // TODO: Remove that when we have the centralized redraw loop - this.previewsController.createPreviews(); - } - }, - - onCanvasContextMenu : function (event) { - event.preventDefault(); - event.stopPropagation(); - event.cancelBubble = true; - return false; - }, - - getRelativeCoordinates : function (x, y) { - var canvasRect = $(".drawing-canvas")[0].getBoundingClientRect(); - return { - x : x - canvasRect.left, - y : y - canvasRect.top - } - }, - - getSpriteCoordinate : function(event) { - var coord = this.getRelativeCoordinates(event.x, event.y); - var coords = this.getRelativeCoordinates(event.clientX, event.clientY); - return { - "col" : (coords.x - coords.x%drawingCanvasDpi) / drawingCanvasDpi, - "row" : (coords.y - coords.y%drawingCanvasDpi) / drawingCanvasDpi - } - }, - // TODO(julz): Create package ? storeSheet : function (event) { // TODO Refactor using jquery ? diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 63b96533..6dbe9bc0 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -80,7 +80,7 @@ canvas.setAttribute("class", canvasClassname); this.canvas = canvas; - this.container.appendChild(this.canvas); + this.container.append(this.canvas); this.canvasConfigDirty = false; } From 6e8142bb3a9d3f5ee14625f888f7176b91cd6a52 Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 18:45:18 +0200 Subject: [PATCH 04/30] Removing commented outdated code --- js/controller/PreviewFilmController.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js index 7d7a2fe6..12710341 100644 --- a/js/controller/PreviewFilmController.js +++ b/js/controller/PreviewFilmController.js @@ -148,9 +148,7 @@ */ ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber, framesheet) { var currentFrame = this.framesheet.getFrameByIndex(tileNumber); - //var width = frame.getWidth() * this.dpi, - // height = frame.getHeight() * this.dpi; - + var previewTileRoot = document.createElement("li"); var classname = "preview-tile"; previewTileRoot.setAttribute("data-tile-number", tileNumber); @@ -162,18 +160,10 @@ var canvasContainer = document.createElement("div"); canvasContainer.className = "canvas-container"; - //canvasContainer.setAttribute('style', 'width:' + width + 'px; height:' + height + 'px;'); - + var canvasBackground = document.createElement("div"); canvasBackground.className = "canvas-background"; canvasContainer.appendChild(canvasBackground); - /* - var canvasPreview = document.createElement("canvas"); - canvasPreview.className = "canvas tile-view" - - canvasPreview.setAttribute('width', width); - canvasPreview.setAttribute('height', height); - */ previewTileRoot.addEventListener('click', function(evt) { // has not class tile-action: From 2cda69b000e0819890f7845aa1212e89989592ca Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 19:00:03 +0200 Subject: [PATCH 05/30] Fixing remove and duplicate actions from previewfilm --- js/controller/PreviewFilmController.js | 5 ++++- js/piskel.js | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js index 12710341..7db43364 100644 --- a/js/controller/PreviewFilmController.js +++ b/js/controller/PreviewFilmController.js @@ -178,6 +178,7 @@ canvasPreviewDuplicateAction.addEventListener('click', function(evt) { framesheet.duplicateFrameByIndex(tileNumber); + $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model $.publish('SET_ACTIVE_FRAME', [tileNumber + 1]); }); @@ -197,7 +198,9 @@ canvasPreviewDeleteAction.className = "tile-action" canvasPreviewDeleteAction.innerHTML = "del" canvasPreviewDeleteAction.addEventListener('click', function(evt) { - piskel.removeFrame(tileNumber); + framesheet.removeFrameByIndex(tileNumber); + $.publish(Events.FRAMESHEET_RESET); + $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model }); previewTileRoot.appendChild(canvasPreviewDeleteAction); } diff --git a/js/piskel.js b/js/piskel.js index fde522b4..157a4673 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -80,6 +80,10 @@ $.namespace("pskl"); $.subscribe('SET_ACTIVE_FRAME', function(evt, frameId) { piskel.setActiveFrameAndRedraw(frameId); }); + + $.subscribe('FRAMESHEET_RESET', function(evt, frameId) { + piskel.redraw(); + }); }, /** From 82da78abf1f0e18bd655deed53199a4fcdda8d8d Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 22:26:17 +0200 Subject: [PATCH 06/30] Adding grid --- js/controller/DrawingController.js | 1 + js/piskel.js | 2 +- js/rendering/FrameRenderer.js | 99 ++++++++++++++++++++++++------ 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 66559fc1..25dc9f35 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -54,6 +54,7 @@ // Deactivate right click: this.container.contextmenu(this.onCanvasContextMenu_); + //this.container.contextmenu(this.onCanvasContextMenu_); }; /** diff --git a/js/piskel.js b/js/piskel.js index 157a4673..e1f9ac75 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -105,7 +105,7 @@ $.namespace("pskl"); * @private */ calculateDPIsForDrawingCanvas_ : function() { - var availableViewportHeight = $('.main-panel').height(); + var availableViewportHeight = $('.main-panel').height() - 50; return Math.floor(availableViewportHeight / framePixelHeight); }, diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 6dbe9bc0..0490dfac 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -1,22 +1,30 @@ (function () { var ns = $.namespace("pskl.rendering"); - this.dpi = null; - this.canvas = null; - + ns.FrameRenderer = function (container, renderingOptions, className) { + + this.defaultRenderingOptions = { + "gridStrokeWidth" : 0, + "gridStrokeColor" : "lightgray" + }; + renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions); + if(container == undefined) { throw "Bad FrameRenderer initialization. undefined."; } - this.container = container; - - if(renderingOptions == undefined || renderingOptions.dpi == undefined || isNaN(dpi)) { + + if(isNaN(renderingOptions.dpi)) { throw "Bad FrameRenderer initialization. not well defined."; } - this.displayGrid = !!renderingOptions.displayGrid; + this.container = container; this.dpi = renderingOptions.dpi; this.className = className; + this.canvas = null; + console.log(renderingOptions) + this.gridStrokeWidth = renderingOptions.gridStrokeWidth; + this.gridStrokeColor = renderingOptions.gridStrokeColor; // Flag to know if the config was altered this.canvasConfigDirty = true; @@ -34,16 +42,16 @@ ns.FrameRenderer.prototype.render = function (frame) { for(var col = 0, width = frame.getWidth(); col < width; col++) { for(var row = 0, height = frame.getHeight(); row < height; row++) { - this.drawPixel(col, row, frame, this.getCanvas_(frame), this.dpi); + this.drawPixel(col, row, frame, this.getCanvas_(frame, col, row), this.dpi); } } }; ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) { - var context = this.getCanvas_(frame).getContext('2d'); + var context = this.getCanvas_(frame, col, row).getContext('2d'); var color = frame.getPixel(col, row); if(color == Constants.TRANSPARENT_COLOR) { - context.clearRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi); + context.clearRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); } else { if(color != Constants.SELECTION_TRANSPARENT_COLOR) { @@ -51,37 +59,90 @@ $.publish(Events.COLOR_USED, [color]); } context.fillStyle = color; - context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi); + context.fillRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); } }; ns.FrameRenderer.prototype.clear = function (col, row, frame) { - var canvas = this.getCanvas_(frame) + var canvas = this.getCanvas_(frame, col, row) canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); }; + /** + * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered + * frame) into a sprite coordinate in column and row. + * @public + */ + ns.FrameRenderer.prototype.convertPixelCoordinatesIntoSpriteCoordinate = function(coords) { + var cellSize = this.dpi + this.gridStrokeWidth; + return { + "col" : (coords.x - coords.x % cellSize) / cellSize, + "row" : (coords.y - coords.y % cellSize) / cellSize + }; + }; + + /** + * @private + */ + ns.FrameRenderer.prototype.getFrameX_ = function(col) { + return col * this.dpi + ((col - 1) * this.gridStrokeWidth); + }; + + /** + * @private + */ + ns.FrameRenderer.prototype.getFrameY_ = function(row) { + return row * this.dpi + ((row - 1) * this.gridStrokeWidth); + }; + + /** + * @private + */ + ns.FrameRenderer.prototype.drawGrid_ = function(canvas, width, height, col, row) { + var ctx = canvas.getContext("2d"); + ctx.lineWidth = this.gridStrokeWidth; + ctx.strokeStyle = this.gridStrokeColor; + for(var c=1; c < col; c++) { + ctx.moveTo(this.getFrameX_(c), 0); + ctx.lineTo(this.getFrameX_(c), height); + ctx.stroke(); + } + + for(var r=1; r < row; r++) { + ctx.moveTo(0, this.getFrameY_(r)); + ctx.lineTo(width, this.getFrameY_(r)); + ctx.stroke(); + } + }; + /** * @private */ ns.FrameRenderer.prototype.getCanvas_ = function (frame) { if(this.canvasConfigDirty) { $(this.canvas).remove(); - var width = frame.getWidth(), - height = frame.getHeight(); + var col = frame.getWidth(), + row = frame.getHeight(); var canvas = document.createElement("canvas"); - canvas.setAttribute("width", width * this.dpi); - canvas.setAttribute("height", height * this.dpi); + var pixelWidth = col * this.dpi + this.gridStrokeWidth * (col - 1); + var pixelHeight = row * this.dpi + this.gridStrokeWidth * (row - 1); + canvas.setAttribute("width", pixelWidth); + canvas.setAttribute("height", pixelHeight); var canvasClassname = "canvas"; if(this.className) { canvasClassname += " " + this.className; } canvas.setAttribute("class", canvasClassname); - - this.canvas = canvas; - this.container.append(this.canvas); + this.container.append(canvas); + if(this.gridStrokeWidth > 0) { + this.drawGrid_(canvas, pixelWidth, pixelHeight, col, row); + } + + + this.canvas = canvas; this.canvasConfigDirty = false; } return this.canvas; From 6b9904935fa3209e3cc821a7ef457c287d22dee2 Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 22:26:27 +0200 Subject: [PATCH 07/30] Adding grid --- js/controller/DrawingController.js | 44 +++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 25dc9f35..b1a639f8 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -3,19 +3,41 @@ ns.DrawingController = function (frame, container, dpi) { this.dpi = dpi; + // TODO(vincz): Store user prefs in a localstorage string ? var renderingOptions = { "dpi": dpi, - "displayGrid": true // Retrieve from localsotrage config - } + "gridStrokeWidth" : 1, + "gridStrokeColor" : "lightgray" + }; - // Public + // jQuery deep copy of the rendering config: + overlayRenderingOptions = $.extend(true, {}, renderingOptions); + overlayRenderingOptions.gridStrokeColor = "transparent"; + + /** + * @public + */ this.frame = frame; - this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); // Type is frame + + /** + * @public + */ + this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); - // Private + /** + * @private + */ this.container = container; - this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "drawing-canvas"); - this.overlayRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "canvas-overlay"); + + this.renderer = new pskl.rendering.FrameRenderer( + this.container, + renderingOptions, + "drawing-canvas"); + + this.overlayRenderer = new pskl.rendering.FrameRenderer( + this.container, + overlayRenderingOptions, + "canvas-overlay"); this.renderer.init(this.frame); this.overlayRenderer.init(this.frame); @@ -53,7 +75,6 @@ body.mouseup($.proxy(this.onMouseup_, this)); // Deactivate right click: - this.container.contextmenu(this.onCanvasContextMenu_); //this.container.contextmenu(this.onCanvasContextMenu_); }; @@ -154,7 +175,7 @@ return { x : clientX - canvasPageOffset.left, y : clientY - canvasPageOffset.top - } + }; }; /** @@ -162,10 +183,7 @@ */ ns.DrawingController.prototype.getSpriteCoordinate = function(event) { var coords = this.getRelativeCoordinates(event.clientX, event.clientY); - return { - "col" : (coords.x - coords.x % this.dpi) / this.dpi, - "row" : (coords.y - coords.y % this.dpi) / this.dpi - } + return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords); }; /** From e4373ad1333a7523222ef526e6aea1c80747dbbd Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sat, 8 Sep 2012 23:10:05 +0200 Subject: [PATCH 08/30] Small updates to FrameRenderer for fun --- js/rendering/FrameRenderer.js | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 63b96533..5809e784 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -1,16 +1,13 @@ (function () { var ns = $.namespace("pskl.rendering"); - this.dpi = null; - this.canvas = null; - ns.FrameRenderer = function (container, renderingOptions, className) { if(container == undefined) { throw "Bad FrameRenderer initialization. undefined."; } this.container = container; - if(renderingOptions == undefined || renderingOptions.dpi == undefined || isNaN(dpi)) { + if(renderingOptions == undefined || renderingOptions.dpi == undefined) { throw "Bad FrameRenderer initialization. not well defined."; } @@ -66,24 +63,25 @@ ns.FrameRenderer.prototype.getCanvas_ = function (frame) { if(this.canvasConfigDirty) { $(this.canvas).remove(); - var width = frame.getWidth(), - height = frame.getHeight(); - - var canvas = document.createElement("canvas"); - canvas.setAttribute("width", width * this.dpi); - canvas.setAttribute("height", height * this.dpi); - - var canvasClassname = "canvas"; - if(this.className) { - canvasClassname += " " + this.className; - } - canvas.setAttribute("class", canvasClassname); - - this.canvas = canvas; + this.canvas = this.createCanvasForFrame_(frame); this.container.appendChild(this.canvas); this.canvasConfigDirty = false; } return this.canvas; }; + + /** + * @private + */ + ns.FrameRenderer.prototype.createCanvasForFrame_ = function (frame) { + var canvas = document.createElement("canvas"); + canvas.setAttribute("width", frame.getWidth() * this.dpi); + canvas.setAttribute("height", frame.getHeight() * this.dpi); + + canvas.classList.add("canvas"); + if(this.className) canvas.classList.add(this.className); + + return canvas; + }; })(); \ No newline at end of file From df945e10dd03cb7cad6ff1d6c49f74e94dc97e55 Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 23:43:16 +0200 Subject: [PATCH 09/30] Add grid checkbox --- index.html | 7 ++++++ js/Constants.js | 5 ++++- js/Events.js | 2 ++ js/ToolSelector.js | 18 +++++++++++++++ js/controller/DrawingController.js | 6 ++--- js/rendering/FrameRenderer.js | 36 ++++++++++++++++++++++++------ 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index 91efbe58..b0cb5181 100644 --- a/index.html +++ b/index.html @@ -52,6 +52,13 @@ 12 fps + +
    +
  • + + +
  • +
diff --git a/js/Constants.js b/js/Constants.js index ffa5d03f..8ef4e4da 100644 --- a/js/Constants.js +++ b/js/Constants.js @@ -12,5 +12,8 @@ var Constants = { /* * Default entry point for piskel web service: */ - PISKEL_SERVICE_URL: 'http://2.piskel-app.appspot.com' + PISKEL_SERVICE_URL: 'http://2.piskel-app.appspot.com', + + GRID_STROKE_WIDTH: 1, + GRID_STROKE_COLOR: "lightgray" }; \ No newline at end of file diff --git a/js/Events.js b/js/Events.js index df4dfb89..ce13ed7a 100644 --- a/js/Events.js +++ b/js/Events.js @@ -29,6 +29,8 @@ Events = { */ REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM", + GRID_DISPLAY_STATE_CHANGED: "GRID_DISPLAY_STATE_CHANGED", + /** * The framesheet was reseted and is now probably drastically different. * Number of frames, content of frames, color used for the palette may have changed. diff --git a/js/ToolSelector.js b/js/ToolSelector.js index 0f69feaf..ed0c51e0 100644 --- a/js/ToolSelector.js +++ b/js/ToolSelector.js @@ -67,6 +67,17 @@ pskl.ToolSelector = (function() { } }; + /** + * Get state for the checkbox that control the display of the grid + * on the drawing canvas. + * @private + */ + var isShowGridChecked_ = function() { + var showGridCheckbox = $('#show-grid'); + var isChecked = showGridCheckbox.is(':checked'); + return isChecked; + }; + return { init: function() { @@ -75,6 +86,13 @@ pskl.ToolSelector = (function() { selectTool_(toolInstances.simplePen); // Activate listener on tool panel: $("#tools-container").click(onToolIconClicked_); + + // Show/hide the grid on drawing canvas: + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [isShowGridChecked_()]) + $('#show-grid').change(function(evt) { + var checked = isShowGridChecked_(); + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]) + }); } }; })(); diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index b1a639f8..c6fa5dc9 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -6,14 +6,14 @@ // TODO(vincz): Store user prefs in a localstorage string ? var renderingOptions = { "dpi": dpi, - "gridStrokeWidth" : 1, - "gridStrokeColor" : "lightgray" + "hasGrid" : true }; // jQuery deep copy of the rendering config: overlayRenderingOptions = $.extend(true, {}, renderingOptions); - overlayRenderingOptions.gridStrokeColor = "transparent"; + overlayRenderingOptions.hasGrid = false; + /** * @public */ diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 0490dfac..14f6ae42 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -5,8 +5,7 @@ ns.FrameRenderer = function (container, renderingOptions, className) { this.defaultRenderingOptions = { - "gridStrokeWidth" : 0, - "gridStrokeColor" : "lightgray" + "hasGrid" : false }; renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions); @@ -22,16 +21,22 @@ this.dpi = renderingOptions.dpi; this.className = className; this.canvas = null; - console.log(renderingOptions) - this.gridStrokeWidth = renderingOptions.gridStrokeWidth; - this.gridStrokeColor = renderingOptions.gridStrokeColor; + this.hasGrid = renderingOptions.hasGrid; + this.gridStrokeWidth = 0; + + this.lastRenderedFrame = null; // Flag to know if the config was altered this.canvasConfigDirty = true; + + if(this.hasGrid) { + $.subscribe(Events.GRID_DISPLAY_STATE_CHANGED, $.proxy(this.showGrid, this)); + } }; ns.FrameRenderer.prototype.init = function (frame) { this.render(frame); + this.lastRenderedFrame = frame; }; ns.FrameRenderer.prototype.updateDPI = function (newDPI) { @@ -39,12 +44,27 @@ this.canvasConfigDirty = true; }; + ns.FrameRenderer.prototype.showGrid = function (evt, show) { + + this.gridStrokeWidth = 0; + if(show) { + this.gridStrokeWidth = Constants.GRID_STROKE_WIDTH; + } + + this.canvasConfigDirty = true; + + if(this.lastRenderedFrame) { + this.render(this.lastRenderedFrame); + } + }; + ns.FrameRenderer.prototype.render = function (frame) { for(var col = 0, width = frame.getWidth(); col < width; col++) { for(var row = 0, height = frame.getHeight(); row < height; row++) { this.drawPixel(col, row, frame, this.getCanvas_(frame, col, row), this.dpi); } } + this.lastRenderedFrame = frame; }; ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) { @@ -61,6 +81,7 @@ context.fillStyle = color; context.fillRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); } + this.lastRenderedFrame = frame; }; ns.FrameRenderer.prototype.clear = function (col, row, frame) { @@ -100,8 +121,8 @@ */ ns.FrameRenderer.prototype.drawGrid_ = function(canvas, width, height, col, row) { var ctx = canvas.getContext("2d"); - ctx.lineWidth = this.gridStrokeWidth; - ctx.strokeStyle = this.gridStrokeColor; + ctx.lineWidth = Constants.GRID_STROKE_WIDTH; + ctx.strokeStyle = Constants.GRID_STROKE_COLOR; for(var c=1; c < col; c++) { ctx.moveTo(this.getFrameX_(c), 0); ctx.lineTo(this.getFrameX_(c), height); @@ -121,6 +142,7 @@ ns.FrameRenderer.prototype.getCanvas_ = function (frame) { if(this.canvasConfigDirty) { $(this.canvas).remove(); + var col = frame.getWidth(), row = frame.getHeight(); From f169a90644b7fb229674b40f78d430f13053d7bd Mon Sep 17 00:00:00 2001 From: Vince Date: Sat, 8 Sep 2012 23:53:59 +0200 Subject: [PATCH 10/30] Checkbox crappy styling and fixing overlayproxy grid --- css/tools.css | 7 +++++++ js/controller/DrawingController.js | 11 +++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/css/tools.css b/css/tools.css index 7aeb3f49..6b1f308b 100644 --- a/css/tools.css +++ b/css/tools.css @@ -77,6 +77,13 @@ cursor: url(../img/tools/cursors/hand.png) 14 12, pointer; } +.tool-grid, +.tool-grid label, +.tool-grid input { + line-height: 2.5; + cursor: pointer; +} + .tool-icon.selected { cursor: auto; background-color: #eee; diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index c6fa5dc9..da330fab 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -9,11 +9,6 @@ "hasGrid" : true }; - // jQuery deep copy of the rendering config: - overlayRenderingOptions = $.extend(true, {}, renderingOptions); - overlayRenderingOptions.hasGrid = false; - - /** * @public */ @@ -36,7 +31,7 @@ this.overlayRenderer = new pskl.rendering.FrameRenderer( this.container, - overlayRenderingOptions, + renderingOptions, "canvas-overlay"); this.renderer.init(this.frame); @@ -75,7 +70,7 @@ body.mouseup($.proxy(this.onMouseup_, this)); // Deactivate right click: - //this.container.contextmenu(this.onCanvasContextMenu_); + this.container.contextmenu(this.onCanvasContextMenu_); }; /** @@ -152,7 +147,7 @@ this.isClicked = false; this.isRightClicked = false; var spriteCoordinate = this.getSpriteCoordinate(event); - console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); + //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); this.currentToolBehavior.releaseToolAt( spriteCoordinate.col, spriteCoordinate.row, From 6e7545a1d21cccbd50414b06df1f09da5e7e6f9b Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sat, 8 Sep 2012 23:59:44 +0200 Subject: [PATCH 11/30] Added drawing loop, unplugged traditional renderers --- index.html | 1 + js/controller/AnimatedPreviewController.js | 18 ++---------- js/drawingtools/Move.js | 1 - js/drawingtools/PaintBucket.js | 4 --- js/drawingtools/Rectangle.js | 9 ++---- js/drawingtools/SimplePen.js | 4 --- js/piskel.js | 34 ++++++++++------------ 7 files changed, 21 insertions(+), 50 deletions(-) diff --git a/index.html b/index.html index 91efbe58..df46a720 100644 --- a/index.html +++ b/index.html @@ -89,6 +89,7 @@ + diff --git a/js/controller/AnimatedPreviewController.js b/js/controller/AnimatedPreviewController.js index c8b7f51a..7acb319b 100644 --- a/js/controller/AnimatedPreviewController.js +++ b/js/controller/AnimatedPreviewController.js @@ -6,7 +6,8 @@ this.animIndex = 0; this.fps = parseInt($("#preview-fps")[0].value, 10); - + this.deltaTime = 0; + this.previousTime = 0; var renderingOptions = { "dpi": dpi }; @@ -25,29 +26,16 @@ $("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this)); }; - ns.AnimatedPreviewController.prototype.startAnimationTimer = function () { - this.stopAnimationTimer(); - this.animationTimer = window.setTimeout(this.refreshAnimatedPreview.bind(this), 1000/this.fps); - }; - - ns.AnimatedPreviewController.prototype.stopAnimationTimer = function () { - if (this.animationTimer) { - window.clearInterval(this.animationTimer); - this.animationTimer = null; - } - }; - ns.AnimatedPreviewController.prototype.onFPSSliderChange = function(evt) { this.fps = parseInt($("#preview-fps")[0].value, 10); }; - ns.AnimatedPreviewController.prototype.refreshAnimatedPreview = function () { + ns.AnimatedPreviewController.prototype.render = function () { if (!this.framesheet.hasFrameAtIndex(this.animIndex)) { this.animIndex = 0; } this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex)); this.animIndex++; - this.startAnimationTimer(); }; })(); \ No newline at end of file diff --git a/js/drawingtools/Move.js b/js/drawingtools/Move.js index 2ff9ca73..23b0f58f 100644 --- a/js/drawingtools/Move.js +++ b/js/drawingtools/Move.js @@ -29,7 +29,6 @@ var colDiff = col - this.startCol, rowDiff = row - this.startRow; if (colDiff != 0 || rowDiff != 0) { this.shiftFrame(colDiff, rowDiff, drawer.frame, this.frameClone); - drawer.renderFrame(); } }; diff --git a/js/drawingtools/PaintBucket.js b/js/drawingtools/PaintBucket.js index a4523bd7..f3c3ccfe 100644 --- a/js/drawingtools/PaintBucket.js +++ b/js/drawingtools/PaintBucket.js @@ -21,10 +21,6 @@ var targetColor = drawer.frame.getPixel(col, row); //this.recursiveFloodFill_(frame, col, row, targetColor, color); this.queueLinearFloodFill_(drawer.frame, col, row, targetColor, color); - - // Draw in canvas: - // TODO: Remove that when we have the centralized redraw loop - drawer.renderFrame(); }; /** diff --git a/js/drawingtools/Rectangle.js b/js/drawingtools/Rectangle.js index 36967878..5f2fa7c7 100644 --- a/js/drawingtools/Rectangle.js +++ b/js/drawingtools/Rectangle.js @@ -25,7 +25,6 @@ // Drawing the first point of the rectangle in the fake overlay canvas: drawer.overlayFrame.setPixel(col, row, color); - drawer.renderOverlay(); }; ns.Rectangle.prototype.moveToolAt = function(col, row, color, drawer) { @@ -44,13 +43,13 @@ } drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color); } - drawer.renderOverlay(); }; /** * @override */ ns.Rectangle.prototype.releaseToolAt = function(col, row, color, drawer) { + drawer.clearOverlay(); // If the stroke tool is released outside of the canvas, we cancel the stroke: if(drawer.frame.containsPixel(col, row)) { var strokePoints = this.getRectanglePixels_(this.startCol, col, this.startRow, row); @@ -59,12 +58,8 @@ drawer.frame.setPixel(strokePoints[i].col, strokePoints[i].row, color); } // The user released the tool to draw a line. We will compute the pixel coordinate, impact - // the model and draw them in the drawing canvas (not the fake overlay anymore) - // Draw in canvas: - // TODO: Remove that when we have the centralized redraw loop - drawer.renderFrame(); + // the model and draw them in the drawing canvas (not the fake overlay anymore) } - drawer.clearOverlay(); }; /** diff --git a/js/drawingtools/SimplePen.js b/js/drawingtools/SimplePen.js index 39a27363..86065d63 100644 --- a/js/drawingtools/SimplePen.js +++ b/js/drawingtools/SimplePen.js @@ -23,10 +23,6 @@ this.previousCol = col; this.previousRow = row; drawer.frame.setPixel(col, row, color); - - // Draw on canvas: - // TODO: Remove that when we have the centralized redraw loop - drawer.renderFramePixel(col, row); } }; diff --git a/js/piskel.js b/js/piskel.js index ba77acbf..f0610f5f 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -51,6 +51,7 @@ $.namespace("pskl"); piskel.initDPIs_(); + frameSheet = new pskl.model.FrameSheet(framePixelWidth, framePixelHeight); frameSheet.addEmptyFrame(); @@ -91,6 +92,16 @@ $.namespace("pskl"); this.finishInit(); pskl.LocalStorageService.displayRestoreNotification(); } + + var drawingLoop = new pskl.rendering.DrawingLoop(); + drawingLoop.addCallback(this.render, this); + drawingLoop.start(); + }, + + render : function (delta) { + this.drawingController.render(delta); + this.animationController.render(delta); + this.previewsController.render(delta); }, /** @@ -157,7 +168,7 @@ $.namespace("pskl"); }); $.subscribe(Events.REFRESH, function() { - piskel.setActiveFrameAndRedraw(0); + piskel.setActiveFrame(0); }); // TODO: Move this into their service or behavior files: @@ -186,13 +197,12 @@ $.namespace("pskl"); piskel.setActiveFrame(0); $.publish(Events.HIDE_NOTIFICATION); piskel.finishInit(); - piskel.setActiveFrameAndRedraw(0); }; xhr.onerror = function () { $.publish(Events.HIDE_NOTIFICATION); piskel.finishInit(); - piskel.setActiveFrameAndRedraw(0); + piskel.setActiveFrame(0); }; xhr.send(); @@ -203,18 +213,6 @@ $.namespace("pskl"); this.drawingController.frame = this.getCurrentFrame(); }, - setActiveFrameAndRedraw: function(index) { - this.setActiveFrame(index); - this.redraw(); - }, - - redraw : function () { - // Update drawing canvas: - this.drawingController.renderFrame(); - // Update slideshow: - this.previewsController.createPreviews(); - }, - getActiveFrameIndex: function() { if(-1 == activeFrameIndex) { throw "Bad active frame initialization." @@ -237,12 +235,12 @@ $.namespace("pskl"); removeFrame: function(frameIndex) { frameSheet.removeFrameByIndex(frameIndex); var activeFrameIndex = frameIndex ? frameIndex - 1 : 0; - this.setActiveFrameAndRedraw(activeFrameIndex); + this.setActiveFrame(activeFrameIndex); }, duplicateFrame: function(frameIndex) { frameSheet.duplicateFrameByIndex(frameIndex); - this.setActiveFrameAndRedraw(frameIndex + 1); + this.setActiveFrame(frameIndex + 1); }, getCurrentColor : function () { @@ -323,8 +321,6 @@ $.namespace("pskl"); $.publish(Events.TOOL_RELEASED); - // TODO: Remove that when we have the centralized redraw loop - this.previewsController.createPreviews(); } }, From 0fe9ade8709b22aabfb487224c9879c8ae8c0988 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Sun, 9 Sep 2012 00:09:18 +0200 Subject: [PATCH 12/30] added subl project artefacts to gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 5509140f..742e0b2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ +# mac artefacts *.DS_Store + +# sublime text stuff (the -project should actually be shared, but then we'd have to share the same disk location) +*.sublime-project +*.sublime-workspace \ No newline at end of file From d799221c24fb8fddf66e952f0deb04855b557f3b Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 00:28:58 +0200 Subject: [PATCH 13/30] Ignoring stackdump files from git --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 742e0b2c..69858933 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ # sublime text stuff (the -project should actually be shared, but then we'd have to share the same disk location) *.sublime-project -*.sublime-workspace \ No newline at end of file +*.sublime-workspace + +# git stackdumps +*.stackdump \ No newline at end of file From 63d8cd7eb710dd532974949bee6dd13fd4db0bd7 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 01:12:54 +0200 Subject: [PATCH 14/30] Slight performance improvement, previewfilmcontroller still buggy --- js/controller/AnimatedPreviewController.js | 24 +++++++------ js/controller/DrawingController.js | 13 +++++-- js/controller/PreviewFilmController.js | 42 ++++++++++++---------- js/piskel.js | 2 +- 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/js/controller/AnimatedPreviewController.js b/js/controller/AnimatedPreviewController.js index 9c944a40..ee1e7f1c 100644 --- a/js/controller/AnimatedPreviewController.js +++ b/js/controller/AnimatedPreviewController.js @@ -3,7 +3,9 @@ ns.AnimatedPreviewController = function (framesheet, container, dpi) { this.framesheet = framesheet; this.container = container; - this.animIndex = 0; + + this.elapsedTime = 0; + this.currentIndex = 0; this.fps = parseInt($("#preview-fps")[0].value, 10); this.deltaTime = 0; @@ -15,11 +17,6 @@ }; ns.AnimatedPreviewController.prototype.init = function () { - this.initDom(); - this.renderer.init(this.framesheet.getFrameByIndex(this.animIndex)); - }; - - ns.AnimatedPreviewController.prototype.initDom = function () { $("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this)); }; @@ -27,12 +24,17 @@ this.fps = parseInt($("#preview-fps")[0].value, 10); }; - ns.AnimatedPreviewController.prototype.render = function () { - if (!this.framesheet.hasFrameAtIndex(this.animIndex)) { - this.animIndex = 0; + ns.AnimatedPreviewController.prototype.render = function (delta) { + this.elapsedTime += delta; + var index = Math.floor(this.elapsedTime / (1000/this.fps)); + if (index != this.currentIndex) { + this.currentIndex = index; + if (!this.framesheet.hasFrameAtIndex(this.currentIndex)) { + this.currentIndex = 0; + this.elapsedTime = 0; + } + this.renderer.render(this.framesheet.getFrameByIndex(this.currentIndex)); } - this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex)); - this.animIndex++; }; })(); \ No newline at end of file diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 4cdf3b61..a9a32e3e 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -212,6 +212,7 @@ ns.DrawingController.prototype.render = function () { try { + this.renderFrame(); this.renderOverlay(); } catch (e) { @@ -220,7 +221,11 @@ }; ns.DrawingController.prototype.renderFrame = function () { - this.renderer.render(this.frame); + var serializedFrame = this.frame.serialize(); + if (this.serializedFrame != serializedFrame) { + this.serializedFrame = serializedFrame + this.renderer.render(this.frame); + } }; ns.DrawingController.prototype.renderFramePixel = function (col, row) { @@ -228,7 +233,11 @@ }; ns.DrawingController.prototype.renderOverlay = function () { - this.overlayRenderer.render(this.overlayFrame); + var serializedOverlay = this.overlayFrame.serialize(); + if (this.serializedOverlay != serializedOverlay) { + this.serializedOverlay = serializedOverlay + this.renderer.render(this.overlayFrame); + } }; ns.DrawingController.prototype.clearOverlay = function () { diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js index 4ec9b4b2..5ae04e03 100644 --- a/js/controller/PreviewFilmController.js +++ b/js/controller/PreviewFilmController.js @@ -6,37 +6,41 @@ this.framesheet = framesheet; this.container = container; + this.dirty = false; + $.subscribe(Events.REDRAW_PREVIEWFILM, $.proxy(function(evt) { - // this.render(); + this.dirty = true; }, this)); }; ns.PreviewFilmController.prototype.init = function() { - var addFrameButton = $('#add-frame-button')[0]; - addFrameButton.addEventListener('mousedown', this.addFrame.bind(this)); + var addFrameButton = $('#add-frame-button')[0]; + addFrameButton.addEventListener('mousedown', this.addFrame.bind(this)); }; ns.PreviewFilmController.prototype.addFrame = function () { this.framesheet.addEmptyFrame(); - piskel.setActiveFrameAndRedraw(this.framesheet.getFrameCount() - 1); + piskel.setActiveFrame(this.framesheet.getFrameCount() - 1); }; ns.PreviewFilmController.prototype.render = function () { - // TODO(vincz): Full redraw on any drawing modification, optimize. - this.container.html(""); + if (!this.dirty) return + // TODO(vincz): Full redraw on any drawing modification, optimize. + this.container.html(""); - var frameCount = this.framesheet.getFrameCount(); - - for (var i = 0, l = frameCount; i < l ; i++) { - this.container.append(this.createInterstitialTile_(i)); - this.container.append(this.createPreviewTile_(i, this.framesheet)); - } - this.container.append(this.createInterstitialTile_(frameCount)); + var frameCount = this.framesheet.getFrameCount(); - var needDragndropBehavior = !!(frameCount > 1); - if(needDragndropBehavior) { - this.initDragndropBehavior_(); - } + for (var i = 0, l = frameCount; i < l ; i++) { + this.container.append(this.createInterstitialTile_(i)); + this.container.append(this.createPreviewTile_(i, this.framesheet)); + } + this.container.append(this.createInterstitialTile_(frameCount)); + + var needDragndropBehavior = !!(frameCount > 1); + if(needDragndropBehavior) { + this.initDragndropBehavior_(); + } + this.dirty = false; }; /** @@ -132,7 +136,7 @@ $('#preview-list').removeClass("show-interstitial-tiles"); // TODO(vincz): deprecate. - piskel.setActiveFrameAndRedraw(activeFrame); + piskel.setActiveFrame(activeFrame); // TODO(vincz): move localstorage request to the model layer? $.publish(Events.LOCALSTORAGE_REQUEST); @@ -165,7 +169,7 @@ previewTileRoot.addEventListener('click', function(evt) { // has not class tile-action: if(!evt.target.classList.contains('tile-action')) { - piskel.setActiveFrameAndRedraw(tileNumber); + piskel.setActiveFrame(tileNumber); } }); diff --git a/js/piskel.js b/js/piskel.js index b442eb45..2aee3ebb 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -79,7 +79,7 @@ $.namespace("pskl"); } $.subscribe('SET_ACTIVE_FRAME', function(evt, frameId) { - piskel.setActiveFrameAndRedraw(frameId); + piskel.setActiveFrame(frameId); }); $.subscribe('FRAMESHEET_RESET', function(evt, frameId) { From 809fc8b688e5b34087ba2a84c78fed9c385eb1a7 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Sun, 9 Sep 2012 01:35:29 +0200 Subject: [PATCH 15/30] Fix the duplication in the overlay when grid toggl When the grid was toggled, the overlay would actually draw the main drawing frame instead of just redrawing itself with transparent pixels. This was due to the drawingcontroller passing the ref to the same frame object when initialiwing both renders. By the way, the overlay should probably be treated a bit differently as redrawing all its transprent pixels in that case is useless. --- js/controller/DrawingController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 97997a9c..8fa99c2c 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -35,7 +35,7 @@ "canvas-overlay"); this.renderer.init(this.frame); - this.overlayRenderer.init(this.frame); + this.overlayRenderer.init(this.overlayFrame); // State of drawing controller: this.isClicked = false; From d18c3cd5f778e6ad6240da705eb5a0b30c8c0b2f Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 02:34:54 +0200 Subject: [PATCH 16/30] Cleaned FrameRenderer.js FrameRenderer should also keep a reference on the frame it is updating - initially I wanted the renderer to be frame independant, but it doesnt bring much --- js/controller/DrawingController.js | 7 +-- js/drawingtools/Stroke.js | 3 -- js/rendering/FrameRenderer.js | 68 ++++++++++++------------------ 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 63dccdc6..145d83d8 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -206,13 +206,11 @@ this.renderer.updateDPI(newDPI); this.overlayRenderer.updateDPI(newDPI); - this.renderer.render(this.frame); - this.overlayRenderer.render(this.overlayFrame); + this.render(); }; ns.DrawingController.prototype.render = function () { try { - this.renderFrame(); this.renderOverlay(); } catch (e) { @@ -236,12 +234,11 @@ var serializedOverlay = this.overlayFrame.serialize(); if (this.serializedOverlay != serializedOverlay) { this.serializedOverlay = serializedOverlay - this.renderer.render(this.overlayFrame); + this.overlayRenderer.render(this.overlayFrame); } }; ns.DrawingController.prototype.clearOverlay = function () { this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(this.frame); - this.overlayRenderer.clear(); }; })(); \ No newline at end of file diff --git a/js/drawingtools/Stroke.js b/js/drawingtools/Stroke.js index 13dabac3..7a3137c7 100644 --- a/js/drawingtools/Stroke.js +++ b/js/drawingtools/Stroke.js @@ -35,7 +35,6 @@ // The fake canvas where we will draw the preview of the stroke: // Drawing the first point of the stroke in the fake overlay canvas: drawer.overlayFrame.setPixel(col, row, color); - drawer.renderOverlay(); }; ns.Stroke.prototype.moveToolAt = function(col, row, color, drawer) { @@ -59,7 +58,6 @@ } drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color); } - drawer.renderOverlay(); }; /** @@ -78,7 +76,6 @@ } // Draw in canvas: // TODO: Remove that when we have the centralized redraw loop - drawer.renderFrame(); } // For now, we are done with the stroke tool and don't need an overlay anymore: drawer.clearOverlay(); diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index a2f97e44..5761f85f 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -58,33 +58,42 @@ }; ns.FrameRenderer.prototype.render = function (frame) { + this.clear(frame); + var context = this.getCanvas_(frame).getContext('2d'); for(var col = 0, width = frame.getWidth(); col < width; col++) { for(var row = 0, height = frame.getHeight(); row < height; row++) { - this.drawPixel(col, row, frame, this.getCanvas_(frame, col, row), this.dpi); + var color = frame.getPixel(col, row); + this.renderPixel_(color, col, row, context); } } this.lastRenderedFrame = frame; }; ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) { - var context = this.getCanvas_(frame, col, row).getContext('2d'); + var context = this.getCanvas_(frame).getContext('2d'); var color = frame.getPixel(col, row); if(color == Constants.TRANSPARENT_COLOR) { - context.clearRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); - } - else { - if(color != Constants.SELECTION_TRANSPARENT_COLOR) { - // TODO(vincz): Found a better design to update the palette, it's called too frequently. - $.publish(Events.COLOR_USED, [color]); - } - context.fillStyle = color; - context.fillRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); + context.clearRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); + } else { + this.renderPixel_(color, col, row, context); } this.lastRenderedFrame = frame; }; - ns.FrameRenderer.prototype.clear = function (col, row, frame) { - var canvas = this.getCanvas_(frame, col, row) + ns.FrameRenderer.prototype.renderPixel_ = function (color, col, row, context) { + if(color != Constants.TRANSPARENT_COLOR) { + context.fillStyle = color; + context.fillRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); + } + + if(color != Constants.SELECTION_TRANSPARENT_COLOR) { + // TODO(vincz): Found a better design to update the palette, it's called too frequently. + $.publish(Events.COLOR_USED, [color]); + } + }; + + ns.FrameRenderer.prototype.clear = function (frame) { + var canvas = this.getCanvas_(frame); canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); }; @@ -104,15 +113,8 @@ /** * @private */ - ns.FrameRenderer.prototype.getFrameX_ = function(col) { - return col * this.dpi + ((col - 1) * this.gridStrokeWidth); - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.getFrameY_ = function(row) { - return row * this.dpi + ((row - 1) * this.gridStrokeWidth); + ns.FrameRenderer.prototype.getFramePos_ = function(index) { + return index * this.dpi + ((index - 1) * this.gridStrokeWidth); }; /** @@ -123,14 +125,14 @@ ctx.lineWidth = Constants.GRID_STROKE_WIDTH; ctx.strokeStyle = Constants.GRID_STROKE_COLOR; for(var c=1; c < col; c++) { - ctx.moveTo(this.getFrameX_(c), 0); - ctx.lineTo(this.getFrameX_(c), height); + ctx.moveTo(this.getFramePos_(c), 0); + ctx.lineTo(this.getFramePos_(c), height); ctx.stroke(); } for(var r=1; r < row; r++) { - ctx.moveTo(0, this.getFrameY_(r)); - ctx.lineTo(width, this.getFrameY_(r)); + ctx.moveTo(0, this.getFramePos_(r)); + ctx.lineTo(width, this.getFramePos_(r)); ctx.stroke(); } }; @@ -168,18 +170,4 @@ } return this.canvas; }; - - /** - * @private - */ - ns.FrameRenderer.prototype.createCanvasForFrame_ = function (frame) { - var canvas = document.createElement("canvas"); - canvas.setAttribute("width", frame.getWidth() * this.dpi); - canvas.setAttribute("height", frame.getHeight() * this.dpi); - - canvas.classList.add("canvas"); - if(this.className) canvas.classList.add(this.className); - - return canvas; - }; })(); \ No newline at end of file From 8982a5b4790bf9e349700b5b447d45d01161f64f Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 11:37:52 +0200 Subject: [PATCH 17/30] Removed 2 useless instance variables in AnimatedPreviewController --- js/controller/AnimatedPreviewController.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/controller/AnimatedPreviewController.js b/js/controller/AnimatedPreviewController.js index ee1e7f1c..34b84eef 100644 --- a/js/controller/AnimatedPreviewController.js +++ b/js/controller/AnimatedPreviewController.js @@ -8,8 +8,7 @@ this.currentIndex = 0; this.fps = parseInt($("#preview-fps")[0].value, 10); - this.deltaTime = 0; - this.previousTime = 0; + var renderingOptions = { "dpi": dpi }; From 7b90873324f953ef866baf2402ad9215336d099d Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Mon, 10 Sep 2012 19:53:34 +0200 Subject: [PATCH 18/30] Fixed initialization bug + performance issue with jquery pub sub --- js/piskel.js | 2 +- js/rendering/FrameRenderer.js | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/js/piskel.js b/js/piskel.js index 2aee3ebb..01316a6a 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -83,7 +83,7 @@ $.namespace("pskl"); }); $.subscribe('FRAMESHEET_RESET', function(evt, frameId) { - piskel.redraw(); + piskel.render(); }); var drawingLoop = new pskl.rendering.DrawingLoop(); drawingLoop.addCallback(this.render, this); diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 5761f85f..20d42ad4 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -84,11 +84,6 @@ if(color != Constants.TRANSPARENT_COLOR) { context.fillStyle = color; context.fillRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); - } - - if(color != Constants.SELECTION_TRANSPARENT_COLOR) { - // TODO(vincz): Found a better design to update the palette, it's called too frequently. - $.publish(Events.COLOR_USED, [color]); } }; From 873a10caa2b6c55f9c571bd848aa04a4600bae4b Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Sun, 9 Sep 2012 01:35:29 +0200 Subject: [PATCH 19/30] Fix the duplication in the overlay when grid toggl When the grid was toggled, the overlay would actually draw the main drawing frame instead of just redrawing itself with transparent pixels. This was due to the drawingcontroller passing the ref to the same frame object when initialiwing both renders. By the way, the overlay should probably be treated a bit differently as redrawing all its transprent pixels in that case is useless. --- js/controller/DrawingController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index a9a32e3e..63dccdc6 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -35,7 +35,7 @@ "canvas-overlay"); this.renderer.init(this.frame); - this.overlayRenderer.init(this.frame); + this.overlayRenderer.init(this.overlayFrame); // State of drawing controller: this.isClicked = false; From 68c2cae65865a86591304ccb773508d47c1d1439 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 02:34:54 +0200 Subject: [PATCH 20/30] Cleaned FrameRenderer.js FrameRenderer should also keep a reference on the frame it is updating - initially I wanted the renderer to be frame independant, but it doesnt bring much --- js/controller/DrawingController.js | 7 +-- js/drawingtools/Stroke.js | 3 -- js/rendering/FrameRenderer.js | 68 ++++++++++++------------------ 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 63dccdc6..145d83d8 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -206,13 +206,11 @@ this.renderer.updateDPI(newDPI); this.overlayRenderer.updateDPI(newDPI); - this.renderer.render(this.frame); - this.overlayRenderer.render(this.overlayFrame); + this.render(); }; ns.DrawingController.prototype.render = function () { try { - this.renderFrame(); this.renderOverlay(); } catch (e) { @@ -236,12 +234,11 @@ var serializedOverlay = this.overlayFrame.serialize(); if (this.serializedOverlay != serializedOverlay) { this.serializedOverlay = serializedOverlay - this.renderer.render(this.overlayFrame); + this.overlayRenderer.render(this.overlayFrame); } }; ns.DrawingController.prototype.clearOverlay = function () { this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(this.frame); - this.overlayRenderer.clear(); }; })(); \ No newline at end of file diff --git a/js/drawingtools/Stroke.js b/js/drawingtools/Stroke.js index 13dabac3..7a3137c7 100644 --- a/js/drawingtools/Stroke.js +++ b/js/drawingtools/Stroke.js @@ -35,7 +35,6 @@ // The fake canvas where we will draw the preview of the stroke: // Drawing the first point of the stroke in the fake overlay canvas: drawer.overlayFrame.setPixel(col, row, color); - drawer.renderOverlay(); }; ns.Stroke.prototype.moveToolAt = function(col, row, color, drawer) { @@ -59,7 +58,6 @@ } drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color); } - drawer.renderOverlay(); }; /** @@ -78,7 +76,6 @@ } // Draw in canvas: // TODO: Remove that when we have the centralized redraw loop - drawer.renderFrame(); } // For now, we are done with the stroke tool and don't need an overlay anymore: drawer.clearOverlay(); diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index a2f97e44..5761f85f 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -58,33 +58,42 @@ }; ns.FrameRenderer.prototype.render = function (frame) { + this.clear(frame); + var context = this.getCanvas_(frame).getContext('2d'); for(var col = 0, width = frame.getWidth(); col < width; col++) { for(var row = 0, height = frame.getHeight(); row < height; row++) { - this.drawPixel(col, row, frame, this.getCanvas_(frame, col, row), this.dpi); + var color = frame.getPixel(col, row); + this.renderPixel_(color, col, row, context); } } this.lastRenderedFrame = frame; }; ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) { - var context = this.getCanvas_(frame, col, row).getContext('2d'); + var context = this.getCanvas_(frame).getContext('2d'); var color = frame.getPixel(col, row); if(color == Constants.TRANSPARENT_COLOR) { - context.clearRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); - } - else { - if(color != Constants.SELECTION_TRANSPARENT_COLOR) { - // TODO(vincz): Found a better design to update the palette, it's called too frequently. - $.publish(Events.COLOR_USED, [color]); - } - context.fillStyle = color; - context.fillRect(this.getFrameY_(col), this.getFrameY_(row), this.dpi, this.dpi); + context.clearRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); + } else { + this.renderPixel_(color, col, row, context); } this.lastRenderedFrame = frame; }; - ns.FrameRenderer.prototype.clear = function (col, row, frame) { - var canvas = this.getCanvas_(frame, col, row) + ns.FrameRenderer.prototype.renderPixel_ = function (color, col, row, context) { + if(color != Constants.TRANSPARENT_COLOR) { + context.fillStyle = color; + context.fillRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); + } + + if(color != Constants.SELECTION_TRANSPARENT_COLOR) { + // TODO(vincz): Found a better design to update the palette, it's called too frequently. + $.publish(Events.COLOR_USED, [color]); + } + }; + + ns.FrameRenderer.prototype.clear = function (frame) { + var canvas = this.getCanvas_(frame); canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); }; @@ -104,15 +113,8 @@ /** * @private */ - ns.FrameRenderer.prototype.getFrameX_ = function(col) { - return col * this.dpi + ((col - 1) * this.gridStrokeWidth); - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.getFrameY_ = function(row) { - return row * this.dpi + ((row - 1) * this.gridStrokeWidth); + ns.FrameRenderer.prototype.getFramePos_ = function(index) { + return index * this.dpi + ((index - 1) * this.gridStrokeWidth); }; /** @@ -123,14 +125,14 @@ ctx.lineWidth = Constants.GRID_STROKE_WIDTH; ctx.strokeStyle = Constants.GRID_STROKE_COLOR; for(var c=1; c < col; c++) { - ctx.moveTo(this.getFrameX_(c), 0); - ctx.lineTo(this.getFrameX_(c), height); + ctx.moveTo(this.getFramePos_(c), 0); + ctx.lineTo(this.getFramePos_(c), height); ctx.stroke(); } for(var r=1; r < row; r++) { - ctx.moveTo(0, this.getFrameY_(r)); - ctx.lineTo(width, this.getFrameY_(r)); + ctx.moveTo(0, this.getFramePos_(r)); + ctx.lineTo(width, this.getFramePos_(r)); ctx.stroke(); } }; @@ -168,18 +170,4 @@ } return this.canvas; }; - - /** - * @private - */ - ns.FrameRenderer.prototype.createCanvasForFrame_ = function (frame) { - var canvas = document.createElement("canvas"); - canvas.setAttribute("width", frame.getWidth() * this.dpi); - canvas.setAttribute("height", frame.getHeight() * this.dpi); - - canvas.classList.add("canvas"); - if(this.className) canvas.classList.add(this.className); - - return canvas; - }; })(); \ No newline at end of file From 12c9fececbb09f4552583c19a9ef98c2c506b41e Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 9 Sep 2012 11:37:52 +0200 Subject: [PATCH 21/30] Removed 2 useless instance variables in AnimatedPreviewController --- js/controller/AnimatedPreviewController.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/controller/AnimatedPreviewController.js b/js/controller/AnimatedPreviewController.js index ee1e7f1c..34b84eef 100644 --- a/js/controller/AnimatedPreviewController.js +++ b/js/controller/AnimatedPreviewController.js @@ -8,8 +8,7 @@ this.currentIndex = 0; this.fps = parseInt($("#preview-fps")[0].value, 10); - this.deltaTime = 0; - this.previousTime = 0; + var renderingOptions = { "dpi": dpi }; From e1af86b6474f06db00e09163bc379c70b19c53b7 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Mon, 10 Sep 2012 19:53:34 +0200 Subject: [PATCH 22/30] Fixed initialization bug + performance issue with jquery pub sub --- js/piskel.js | 2 +- js/rendering/FrameRenderer.js | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/js/piskel.js b/js/piskel.js index 2aee3ebb..01316a6a 100644 --- a/js/piskel.js +++ b/js/piskel.js @@ -83,7 +83,7 @@ $.namespace("pskl"); }); $.subscribe('FRAMESHEET_RESET', function(evt, frameId) { - piskel.redraw(); + piskel.render(); }); var drawingLoop = new pskl.rendering.DrawingLoop(); drawingLoop.addCallback(this.render, this); diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js index 5761f85f..20d42ad4 100644 --- a/js/rendering/FrameRenderer.js +++ b/js/rendering/FrameRenderer.js @@ -84,11 +84,6 @@ if(color != Constants.TRANSPARENT_COLOR) { context.fillStyle = color; context.fillRect(this.getFramePos_(col), this.getFramePos_(row), this.dpi, this.dpi); - } - - if(color != Constants.SELECTION_TRANSPARENT_COLOR) { - // TODO(vincz): Found a better design to update the palette, it's called too frequently. - $.publish(Events.COLOR_USED, [color]); } }; From 99e9cf885626ca7e7303ae48242cbfd164c65a1d Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Mon, 10 Sep 2012 23:26:12 +0200 Subject: [PATCH 23/30] Fixed FilmPreview bugs. Simplified piskel.js, removed refernce to drawingController from tools --- js/Events.js | 2 - js/HistoryManager.js | 54 +++++++-------- js/LocalStorageService.js | 2 - js/controller/DrawingController.js | 95 +++++++++----------------- js/controller/PreviewFilmController.js | 91 +++++++++++++----------- js/drawingtools/BaseTool.js | 6 +- js/drawingtools/Eraser.js | 4 +- js/drawingtools/Move.js | 12 ++-- js/drawingtools/PaintBucket.js | 7 +- js/drawingtools/Rectangle.js | 19 +++--- js/drawingtools/SimplePen.js | 14 ++-- js/drawingtools/Stroke.js | 22 +++--- js/model/FrameSheet.js | 14 ++-- js/piskel.js | 45 ++---------- 14 files changed, 166 insertions(+), 221 deletions(-) diff --git a/js/Events.js b/js/Events.js index ce13ed7a..e6224a0e 100644 --- a/js/Events.js +++ b/js/Events.js @@ -3,7 +3,6 @@ Events = { TOOL_SELECTED : "TOOL_SELECTED", TOOL_RELEASED : "TOOL_RELEASED", COLOR_SELECTED: "COLOR_SELECTED", - COLOR_USED: "COLOR_USED", /** * When this event is emitted, a request is sent to the localstorage @@ -13,7 +12,6 @@ Events = { LOCALSTORAGE_REQUEST: "LOCALSTORAGE_REQUEST", CANVAS_RIGHT_CLICKED: "CANVAS_RIGHT_CLICKED", - CANVAS_RIGHT_CLICK_RELEASED: "CANVAS_RIGHT_CLICK_RELEASED", /** * Event to request a refresh of the display. diff --git a/js/HistoryManager.js b/js/HistoryManager.js index 4a3c5c4b..d6a92208 100644 --- a/js/HistoryManager.js +++ b/js/HistoryManager.js @@ -1,40 +1,40 @@ (function () { var ns = $.namespace("pskl"); - ns.HistoryManager = function () {}; + ns.HistoryManager = function (framesheet) { + this.framesheet = framesheet; + }; ns.HistoryManager.prototype.init = function () { - document.body.addEventListener('keyup', this.onKeyup.bind(this)); - $.subscribe(Events.TOOL_RELEASED, this.saveState.bind(this)); + document.body.addEventListener('keyup', this.onKeyup.bind(this)); + $.subscribe(Events.TOOL_RELEASED, this.saveState.bind(this)); }; - ns.HistoryManager.prototype.saveState = function () { - piskel.getCurrentFrame().saveState(); - }; + ns.HistoryManager.prototype.saveState = function () { + this.framesheet.getCurrentFrame().saveState(); + }; ns.HistoryManager.prototype.onKeyup = function (evt) { - if (evt.ctrlKey && evt.keyCode == 90) { // CTRL + Z - this.undo(); - } + if (evt.ctrlKey && evt.keyCode == 90) { // CTRL + Z + this.undo(); + } - if (evt.ctrlKey && evt.keyCode == 89) { // CTRL+ Y - this.redo(); - } - }; + if (evt.ctrlKey && evt.keyCode == 89) { // CTRL+ Y + this.redo(); + } + }; - ns.HistoryManager.prototype.undo = function () { - piskel.getCurrentFrame().loadPreviousState(); - this.redraw(); - }; + ns.HistoryManager.prototype.undo = function () { + this.framesheet.getCurrentFrame().loadPreviousState(); + this.redraw(); + }; - ns.HistoryManager.prototype.redo = function () { - piskel.getCurrentFrame().loadNextState(); - this.redraw(); - }; + ns.HistoryManager.prototype.redo = function () { + this.framesheet.getCurrentFrame().loadNextState(); + this.redraw(); + }; - ns.HistoryManager.prototype.redraw = function () { - piskel.drawingController.renderFrame(); - piskel.previewsController.createPreviews(); - }; - - ns.HistoryManager = new ns.HistoryManager(); + ns.HistoryManager.prototype.redraw = function () { + this.framesheet.drawingController.renderFrame(); + this.framesheet.previewsController.createPreviews(); + }; })(); \ No newline at end of file diff --git a/js/LocalStorageService.js b/js/LocalStorageService.js index d697adf7..5397e433 100644 --- a/js/LocalStorageService.js +++ b/js/LocalStorageService.js @@ -43,8 +43,6 @@ pskl.LocalStorageService = (function() { */ var restoreFromLocalStorage_ = function() { frameSheet_.deserialize(window.localStorage['snapShot']); - // Model updated, redraw everything: - $.publish(Events.REFRESH); }; /** diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 145d83d8..1e62ee61 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -1,8 +1,6 @@ (function () { var ns = $.namespace("pskl.controller"); - ns.DrawingController = function (frame, container, dpi) { - this.dpi = dpi; - + ns.DrawingController = function (framesheet, container, dpi) { // TODO(vincz): Store user prefs in a localstorage string ? var renderingOptions = { "dpi": dpi, @@ -12,29 +10,22 @@ /** * @public */ - this.frame = frame; + this.framesheet = framesheet; /** * @public */ - this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); + this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(framesheet.getCurrentFrame()); /** * @private */ this.container = container; - this.renderer = new pskl.rendering.FrameRenderer( - this.container, - renderingOptions, - "drawing-canvas"); - - this.overlayRenderer = new pskl.rendering.FrameRenderer( - this.container, - renderingOptions, - "canvas-overlay"); + this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "drawing-canvas"); + this.overlayRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "canvas-overlay"); - this.renderer.init(this.frame); + this.renderer.init(framesheet.getCurrentFrame()); this.overlayRenderer.init(this.overlayFrame); // State of drawing controller: @@ -48,19 +39,18 @@ this.initMouseBehavior(); $.subscribe(Events.TOOL_SELECTED, $.proxy(function(evt, toolBehavior) { + console.log("Tool selected: ", toolBehavior); + this.currentToolBehavior = toolBehavior; + }, this)); - console.log("Tool selected: ", toolBehavior); - this.currentToolBehavior = toolBehavior; - }, this)); - - $.subscribe(Events.COLOR_SELECTED, $.proxy(function(evt, color, isPrimary) { - console.log("Color selected: ", color); - if (isPrimary) { - this.primaryColor = color; - } else { - this.secondaryColor = color; - } - }, this)); + $.subscribe(Events.COLOR_SELECTED, $.proxy(function(evt, color, isPrimary) { + console.log("Color selected: ", color); + if (isPrimary) { + this.primaryColor = color; + } else { + this.secondaryColor = color; + } + }, this)); }; ns.DrawingController.prototype.initMouseBehavior = function() { @@ -84,14 +74,13 @@ $.publish(Events.CANVAS_RIGHT_CLICKED); } - var spriteCoordinate = this.getSpriteCoordinate(event); - //console.log("mousedown: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); + var coords = this.getSpriteCoordinates(event); this.currentToolBehavior.applyToolAt( - spriteCoordinate.col, - spriteCoordinate.row, + coords.col, coords.row, this.getCurrentColor_(), - this + this.framesheet.getCurrentFrame(), + this.overlayFrame ); $.publish(Events.LOCALSTORAGE_REQUEST); @@ -104,27 +93,20 @@ var currentTime = new Date().getTime(); // Throttling of the mousemove event: if ((currentTime - this.previousMousemoveTime) > 40 ) { - var spriteCoordinate = this.getSpriteCoordinate(event); + var coords = this.getSpriteCoordinates(event); if (this.isClicked) { this.currentToolBehavior.moveToolAt( - spriteCoordinate.col, - spriteCoordinate.row, + coords.col, coords.row, this.getCurrentColor_(), - this + this.framesheet.getCurrentFrame(), + this.overlayFrame ); - //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); - // TODO(vincz): Find a way to move that to the model instead of being at the interaction level. // Eg when drawing, it may make sense to have it here. However for a non drawing tool, // you don't need to draw anything when mousemoving and you request useless localStorage. $.publish(Events.LOCALSTORAGE_REQUEST); - } else { - // debug mode to see the selected pixel - // this.clearOverlay(); - // this.overlayFrame.setPixel( spriteCoordinate.col,spriteCoordinate.row, "#ff0000"); - // this.renderOverlay(); } this.previousMousemoveTime = currentTime; } @@ -139,26 +121,20 @@ // the user was probably drawing on the canvas. // Note: The mousemove movement (and the mouseup) may end up outside // of the drawing canvas. - if(this.isRightClicked) { - $.publish(Events.CANVAS_RIGHT_CLICK_RELEASED); - } - this.isClicked = false; this.isRightClicked = false; - var spriteCoordinate = this.getSpriteCoordinate(event); + + var coords = this.getSpriteCoordinates(event); //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); this.currentToolBehavior.releaseToolAt( - spriteCoordinate.col, - spriteCoordinate.row, + coords.col, coords.row, this.getCurrentColor_(), - this + this.framesheet.getCurrentFrame(), + this.overlayFrame ); $.publish(Events.TOOL_RELEASED); - - // TODO: Remove that when we have the centralized redraw loop - $.publish(Events.REDRAW_PREVIEWFILM); } }, @@ -176,7 +152,7 @@ /** * @private */ - ns.DrawingController.prototype.getSpriteCoordinate = function(event) { + ns.DrawingController.prototype.getSpriteCoordinates = function(event) { var coords = this.getRelativeCoordinates(event.clientX, event.clientY); return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords); }; @@ -219,17 +195,14 @@ }; ns.DrawingController.prototype.renderFrame = function () { - var serializedFrame = this.frame.serialize(); + var frame = this.framesheet.getCurrentFrame(); + var serializedFrame = frame.serialize(); if (this.serializedFrame != serializedFrame) { this.serializedFrame = serializedFrame - this.renderer.render(this.frame); + this.renderer.render(frame); } }; - ns.DrawingController.prototype.renderFramePixel = function (col, row) { - this.renderer.drawPixel(col, row, this.frame); - }; - ns.DrawingController.prototype.renderOverlay = function () { var serializedOverlay = this.overlayFrame.serialize(); if (this.serializedOverlay != serializedOverlay) { diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js index 5ae04e03..389a12f8 100644 --- a/js/controller/PreviewFilmController.js +++ b/js/controller/PreviewFilmController.js @@ -6,11 +6,10 @@ this.framesheet = framesheet; this.container = container; - this.dirty = false; + this.redrawFlag = false; - $.subscribe(Events.REDRAW_PREVIEWFILM, $.proxy(function(evt) { - this.dirty = true; - }, this)); + $.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this)); + $.subscribe(Events.FRAMESHEET_RESET, this.flagForRedraw_.bind(this)); }; ns.PreviewFilmController.prototype.init = function() { @@ -20,19 +19,29 @@ ns.PreviewFilmController.prototype.addFrame = function () { this.framesheet.addEmptyFrame(); - piskel.setActiveFrame(this.framesheet.getFrameCount() - 1); + this.framesheet.setCurrentFrameIndex(this.framesheet.getFrameCount() - 1); + }; + + ns.PreviewFilmController.prototype.flagForRedraw_ = function () { + this.redrawFlag = true; }; ns.PreviewFilmController.prototype.render = function () { - if (!this.dirty) return - // TODO(vincz): Full redraw on any drawing modification, optimize. + if (this.redrawFlag) { + // TODO(vincz): Full redraw on any drawing modification, optimize. + this.createPreviews_(); + this.redrawFlag = false; + } + }; + + ns.PreviewFilmController.prototype.createPreviews_ = function () { this.container.html(""); var frameCount = this.framesheet.getFrameCount(); for (var i = 0, l = frameCount; i < l ; i++) { - this.container.append(this.createInterstitialTile_(i)); - this.container.append(this.createPreviewTile_(i, this.framesheet)); + this.container.append(this.createInterstitialTile_(i)); + this.container.append(this.createPreviewTile_(i)); } this.container.append(this.createInterstitialTile_(frameCount)); @@ -40,19 +49,18 @@ if(needDragndropBehavior) { this.initDragndropBehavior_(); } - this.dirty = false; }; /** * @private */ ns.PreviewFilmController.prototype.createInterstitialTile_ = function (tileNumber) { - var initerstitialTile = document.createElement("div"); - initerstitialTile.className = "interstitial-tile" - initerstitialTile.setAttribute("data-tile-type", "interstitial"); - initerstitialTile.setAttribute("data-inject-drop-tile-at", tileNumber); + var interstitialTile = document.createElement("div"); + interstitialTile.className = "interstitial-tile" + interstitialTile.setAttribute("data-tile-type", "interstitial"); + interstitialTile.setAttribute("data-inject-drop-tile-at", tileNumber); - return initerstitialTile; + return interstitialTile; }; /** @@ -101,8 +109,8 @@ // inside the drag target. We normalize that by taking the correct ancestor: var originTile = $(event.srcElement).closest(".preview-tile"); var originFrameId = parseInt(originTile.data("tile-number"), 10); + var dropTarget = $(event.target); - if(dropTarget.data("tile-type") == "interstitial") { var targetInsertionId = parseInt(dropTarget.data("inject-drop-tile-at"), 10); // In case we drop outside of the tile container @@ -120,8 +128,7 @@ if(activeFrame > (this.framesheet.getFrameCount() - 1)) { activeFrame = targetInsertionId - 1; } - } - else { + } else { var targetSwapId = parseInt(dropTarget.data("tile-number"), 10); // In case we drop outside of the tile container if(isNaN(originFrameId) || isNaN(targetSwapId)) { @@ -135,26 +142,24 @@ $('#preview-list').removeClass("show-interstitial-tiles"); - // TODO(vincz): deprecate. - piskel.setActiveFrame(activeFrame); + this.framesheet.setCurrentFrameIndex(activeFrame); // TODO(vincz): move localstorage request to the model layer? $.publish(Events.LOCALSTORAGE_REQUEST); - }; /** * @private * TODO(vincz): clean this giant rendering function & remove listeners. */ - ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber, framesheet) { + ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) { var currentFrame = this.framesheet.getFrameByIndex(tileNumber); var previewTileRoot = document.createElement("li"); var classname = "preview-tile"; previewTileRoot.setAttribute("data-tile-number", tileNumber); - if (piskel.getActiveFrameIndex() == tileNumber) { + if (this.framesheet.getCurrentFrame() == currentFrame) { classname += " selected"; } previewTileRoot.className = classname; @@ -166,25 +171,14 @@ canvasBackground.className = "canvas-background"; canvasContainer.appendChild(canvasBackground); - previewTileRoot.addEventListener('click', function(evt) { - // has not class tile-action: - if(!evt.target.classList.contains('tile-action')) { - piskel.setActiveFrame(tileNumber); - } - }); + previewTileRoot.addEventListener('click', this.onPreviewClick_.bind(this, tileNumber)); var canvasPreviewDuplicateAction = document.createElement("button"); canvasPreviewDuplicateAction.className = "tile-action" canvasPreviewDuplicateAction.innerHTML = "dup" - canvasPreviewDuplicateAction.addEventListener('click', function(evt) { - framesheet.duplicateFrameByIndex(tileNumber); - $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model - $.publish('SET_ACTIVE_FRAME', [tileNumber + 1]); - }); + canvasPreviewDuplicateAction.addEventListener('click', this.onAddButtonClick_.bind(this, tileNumber)); - //this.renderer.render(this.framesheet.getFrameByIndex(tileNumber), canvasPreview); - // TODO(vincz): Eventually optimize this part by not recreating a FrameRenderer. Note that the real optim // is to make this update function (#createPreviewTile) less aggressive. var renderingOptions = {"dpi": this.dpi }; @@ -198,14 +192,29 @@ var canvasPreviewDeleteAction = document.createElement("button"); canvasPreviewDeleteAction.className = "tile-action" canvasPreviewDeleteAction.innerHTML = "del" - canvasPreviewDeleteAction.addEventListener('click', function(evt) { - framesheet.removeFrameByIndex(tileNumber); - $.publish(Events.FRAMESHEET_RESET); - $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model - }); + canvasPreviewDeleteAction.addEventListener('click', this.onDeleteButtonClick_.bind(this, tileNumber)); previewTileRoot.appendChild(canvasPreviewDeleteAction); } return previewTileRoot; }; + + ns.PreviewFilmController.prototype.onPreviewClick_ = function (index, evt) { + // has not class tile-action: + if(!evt.target.classList.contains('tile-action')) { + this.framesheet.setCurrentFrameIndex(index); + } + }; + + ns.PreviewFilmController.prototype.onDeleteButtonClick_ = function (index, evt) { + this.framesheet.removeFrameByIndex(index); + $.publish(Events.FRAMESHEET_RESET); + $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model + }; + + ns.PreviewFilmController.prototype.onAddButtonClick_ = function (index, evt) { + this.framesheet.duplicateFrameByIndex(index); + $.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model + this.framesheet.setCurrentFrameIndex(index + 1); + }; })(); \ No newline at end of file diff --git a/js/drawingtools/BaseTool.js b/js/drawingtools/BaseTool.js index 905aa162..84f96824 100644 --- a/js/drawingtools/BaseTool.js +++ b/js/drawingtools/BaseTool.js @@ -8,11 +8,11 @@ ns.BaseTool = function() {}; - ns.BaseTool.prototype.applyToolAt = function(col, row, frame) {}; + ns.BaseTool.prototype.applyToolAt = function(col, row, color, frame, overlay) {}; - ns.BaseTool.prototype.moveToolAt = function(col, row, frame) {}; + ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay) {}; - ns.BaseTool.prototype.releaseToolAt = function(col, row, frame) {}; + ns.BaseTool.prototype.releaseToolAt = function(col, row, color, frame, overlay) {}; /** * Bresenham line algorihtm: Get an array of pixels from diff --git a/js/drawingtools/Eraser.js b/js/drawingtools/Eraser.js index e83cf617..064adf85 100644 --- a/js/drawingtools/Eraser.js +++ b/js/drawingtools/Eraser.js @@ -16,7 +16,7 @@ /** * @override */ - ns.Eraser.prototype.applyToolAt = function(col, row, color, drawer) { - this.superclass.applyToolAt.call(this, col, row, Constants.TRANSPARENT_COLOR, drawer); + ns.Eraser.prototype.applyToolAt = function(col, row, color, frame, overlay) { + this.superclass.applyToolAt.call(this, col, row, Constants.TRANSPARENT_COLOR, frame, overlay); }; })(); \ No newline at end of file diff --git a/js/drawingtools/Move.js b/js/drawingtools/Move.js index 23b0f58f..ec120287 100644 --- a/js/drawingtools/Move.js +++ b/js/drawingtools/Move.js @@ -19,16 +19,16 @@ /** * @override */ - ns.Move.prototype.applyToolAt = function(col, row, color, drawer) { + ns.Move.prototype.applyToolAt = function(col, row, color, frame, overlay) { this.startCol = col; this.startRow = row; - this.frameClone = drawer.frame.clone(); + this.frameClone = frame.clone(); }; - ns.Move.prototype.moveToolAt = function(col, row, color, drawer) { + ns.Move.prototype.moveToolAt = function(col, row, color, frame, overlay) { var colDiff = col - this.startCol, rowDiff = row - this.startRow; if (colDiff != 0 || rowDiff != 0) { - this.shiftFrame(colDiff, rowDiff, drawer.frame, this.frameClone); + this.shiftFrame(colDiff, rowDiff, frame, this.frameClone); } }; @@ -49,7 +49,7 @@ /** * @override */ - ns.Move.prototype.releaseToolAt = function(col, row, color, drawer) { - this.moveToolAt(col, row, color, drawer); + ns.Move.prototype.releaseToolAt = function(col, row, color, frame, overlay) { + this.moveToolAt(col, row, color, frame, overlay); }; })(); diff --git a/js/drawingtools/PaintBucket.js b/js/drawingtools/PaintBucket.js index f3c3ccfe..b3176324 100644 --- a/js/drawingtools/PaintBucket.js +++ b/js/drawingtools/PaintBucket.js @@ -15,12 +15,11 @@ /** * @override */ - ns.PaintBucket.prototype.applyToolAt = function(col, row, color, drawer) { + ns.PaintBucket.prototype.applyToolAt = function(col, row, color, frame, overlay) { // Change model: - var targetColor = drawer.frame.getPixel(col, row); - //this.recursiveFloodFill_(frame, col, row, targetColor, color); - this.queueLinearFloodFill_(drawer.frame, col, row, targetColor, color); + var targetColor = frame.getPixel(col, row); + this.queueLinearFloodFill_(frame, col, row, targetColor, color); }; /** diff --git a/js/drawingtools/Rectangle.js b/js/drawingtools/Rectangle.js index 5f2fa7c7..f5fd906d 100644 --- a/js/drawingtools/Rectangle.js +++ b/js/drawingtools/Rectangle.js @@ -19,17 +19,16 @@ /** * @override */ - ns.Rectangle.prototype.applyToolAt = function(col, row, color, drawer) { + ns.Rectangle.prototype.applyToolAt = function(col, row, color, frame, overlay) { this.startCol = col; this.startRow = row; // Drawing the first point of the rectangle in the fake overlay canvas: - drawer.overlayFrame.setPixel(col, row, color); + overlay.setPixel(col, row, color); }; - ns.Rectangle.prototype.moveToolAt = function(col, row, color, drawer) { - // Clean overlay canvas: - drawer.clearOverlay(); + ns.Rectangle.prototype.moveToolAt = function(col, row, color, frame, overlay) { + overlay.clear(); // When the user moussemove (before releasing), we dynamically compute the // pixel to draw the line and draw this line in the overlay : @@ -41,21 +40,21 @@ if(color == Constants.TRANSPARENT_COLOR) { color = Constants.SELECTION_TRANSPARENT_COLOR; } - drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color); + overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color); } }; /** * @override */ - ns.Rectangle.prototype.releaseToolAt = function(col, row, color, drawer) { - drawer.clearOverlay(); + ns.Rectangle.prototype.releaseToolAt = function(col, row, color, frame, overlay) { + overlay.clear(); // If the stroke tool is released outside of the canvas, we cancel the stroke: - if(drawer.frame.containsPixel(col, row)) { + if(frame.containsPixel(col, row)) { var strokePoints = this.getRectanglePixels_(this.startCol, col, this.startRow, row); for(var i = 0; i< strokePoints.length; i++) { // Change model: - drawer.frame.setPixel(strokePoints[i].col, strokePoints[i].row, color); + frame.setPixel(strokePoints[i].col, strokePoints[i].row, color); } // The user released the tool to draw a line. We will compute the pixel coordinate, impact // the model and draw them in the drawing canvas (not the fake overlay anymore) diff --git a/js/drawingtools/SimplePen.js b/js/drawingtools/SimplePen.js index 86065d63..ffc0047f 100644 --- a/js/drawingtools/SimplePen.js +++ b/js/drawingtools/SimplePen.js @@ -18,27 +18,27 @@ /** * @override */ - ns.SimplePen.prototype.applyToolAt = function(col, row, color, drawer) { - if (drawer.frame.containsPixel(col, row)) { + ns.SimplePen.prototype.applyToolAt = function(col, row, color, frame, overlay) { + if (frame.containsPixel(col, row)) { this.previousCol = col; this.previousRow = row; - drawer.frame.setPixel(col, row, color); + frame.setPixel(col, row, color); } }; - ns.SimplePen.prototype.moveToolAt = function(col, row, color, drawer) { - + ns.SimplePen.prototype.moveToolAt = function(col, row, color, frame, overlay) { if((Math.abs(col - this.previousCol) > 1) || (Math.abs(row - this.previousRow) > 1)) { // The pen movement is too fast for the mousemove frequency, there is a gap between the // current point and the previously drawn one. // We fill the gap by calculating missing dots (simple linear interpolation) and draw them. var interpolatedPixels = this.getLinePixels_(col, this.previousCol, row, this.previousRow); for(var i=0, l=interpolatedPixels.length; i Date: Mon, 10 Sep 2012 23:32:34 +0200 Subject: [PATCH 24/30] Added clear method to pskl.model.Frame --- js/controller/DrawingController.js | 4 ---- js/model/Frame.js | 14 +++++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js index 1e62ee61..e77e4e85 100644 --- a/js/controller/DrawingController.js +++ b/js/controller/DrawingController.js @@ -210,8 +210,4 @@ this.overlayRenderer.render(this.overlayFrame); } }; - - ns.DrawingController.prototype.clearOverlay = function () { - this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(this.frame); - }; })(); \ No newline at end of file diff --git a/js/model/Frame.js b/js/model/Frame.js index b8c7a5eb..17652313 100644 --- a/js/model/Frame.js +++ b/js/model/Frame.js @@ -8,6 +8,11 @@ }; ns.Frame.createEmpty = function (width, height) { + var pixels = ns.Frame.createEmptyPixelGrid_(width, height); + return new ns.Frame(pixels); + }; + + ns.Frame.createEmptyPixelGrid_ = function (width, height) { var pixels = []; //new Array(width); for (var columnIndex=0; columnIndex < width; columnIndex++) { var columnArray = []; @@ -16,7 +21,7 @@ } pixels[columnIndex] = columnArray; } - return new ns.Frame(pixels); + return pixels; }; ns.Frame.createEmptyFromFrame = function (frame) { @@ -41,6 +46,13 @@ this.pixels = this.clonePixels_(pixels); }; + + + ns.Frame.prototype.clear = function () { + var pixels = ns.Frame.createEmptyPixelGrid_(this.getWidth(), this.getHeight()); + this.setPixels(pixels); + }; + /** * Clone a set of pixels. Should be static utility method * @private From c81746526084ef34730365d868c241c91ab16bf2 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:14:38 +0200 Subject: [PATCH 25/30] adding a first travis.yml file --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..7f2ef5de --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.6 \ No newline at end of file From 2fbd59b71b9dd0f28dcd9a310b8f0af5622019f1 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:29:52 +0200 Subject: [PATCH 26/30] adding a first package.json file --- package.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 00000000..fd5c110f --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "author": "People", + "name": "piskel", + "description": "Web based 2d animations editor", + "version": "0.1", + "homepage": "http://github.com/juliandescottes/piskel", + "repository": { + "type": "git", + "url": "http://github.com/juliandescottes/piskel.git" + }, + "scripts": { "test": "make test" }, + "devDependencies": { + "jshint": "0.6.1" + } +} \ No newline at end of file From fb8d8c7ce2724e0bb3d900e8302243a67b98e08d Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:31:50 +0200 Subject: [PATCH 27/30] adding a first package.json file --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fd5c110f..3de5a1df 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "People", "name": "piskel", "description": "Web based 2d animations editor", - "version": "0.1", + "version": "0.0.1", "homepage": "http://github.com/juliandescottes/piskel", "repository": { "type": "git", From 5666733f9827c9c56878996cfcc0efbb4709c366 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:34:48 +0200 Subject: [PATCH 28/30] adding Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..786dfd2d --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +test: + jshint js/*.js --config js/.jshintrc \ No newline at end of file From a8394d22b1ca8208d2648e1d7882bc8e73916e27 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:52:09 +0200 Subject: [PATCH 29/30] fixed jshint complaints --- Makefile | 2 +- js/Constants.js | 30 ++++----- js/Events.js | 64 +++++++++--------- js/LocalStorageService.js | 116 ++++++++++++++++---------------- js/Palette.js | 90 ++++++++++++------------- js/ToolSelector.js | 136 ++++++++++++++++++-------------------- js/utils.js | 4 +- 7 files changed, 216 insertions(+), 226 deletions(-) diff --git a/Makefile b/Makefile index 786dfd2d..fd40ada0 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ test: - jshint js/*.js --config js/.jshintrc \ No newline at end of file + jshint js/*.js \ No newline at end of file diff --git a/js/Constants.js b/js/Constants.js index 8ef4e4da..1f676f0e 100644 --- a/js/Constants.js +++ b/js/Constants.js @@ -1,19 +1,19 @@ var Constants = { - DEFAULT_PEN_COLOR : '#000000', - TRANSPARENT_COLOR : 'TRANSPARENT', - - /* - * Fake semi-transparent color used to highlight transparent - * strokes and rectangles: - */ - SELECTION_TRANSPARENT_COLOR: 'rgba(255, 255, 255, 0.6)', - - /* - * Default entry point for piskel web service: - */ - PISKEL_SERVICE_URL: 'http://2.piskel-app.appspot.com', + DEFAULT_PEN_COLOR : '#000000', + TRANSPARENT_COLOR : 'TRANSPARENT', + + /* + * Fake semi-transparent color used to highlight transparent + * strokes and rectangles: + */ + SELECTION_TRANSPARENT_COLOR: 'rgba(255, 255, 255, 0.6)', + + /* + * Default entry point for piskel web service: + */ + PISKEL_SERVICE_URL: 'http://2.piskel-app.appspot.com', - GRID_STROKE_WIDTH: 1, - GRID_STROKE_COLOR: "lightgray" + GRID_STROKE_WIDTH: 1, + GRID_STROKE_COLOR: "lightgray" }; \ No newline at end of file diff --git a/js/Events.js b/js/Events.js index e6224a0e..bb8ea4e5 100644 --- a/js/Events.js +++ b/js/Events.js @@ -1,40 +1,40 @@ Events = { - - TOOL_SELECTED : "TOOL_SELECTED", - TOOL_RELEASED : "TOOL_RELEASED", - COLOR_SELECTED: "COLOR_SELECTED", + + TOOL_SELECTED : "TOOL_SELECTED", + TOOL_RELEASED : "TOOL_RELEASED", + COLOR_SELECTED: "COLOR_SELECTED", - /** - * When this event is emitted, a request is sent to the localstorage - * Service to save the current framesheet. The storage service - * may not immediately store data (internal throttling of requests). - */ - LOCALSTORAGE_REQUEST: "LOCALSTORAGE_REQUEST", + /** + * When this event is emitted, a request is sent to the localstorage + * Service to save the current framesheet. The storage service + * may not immediately store data (internal throttling of requests). + */ + LOCALSTORAGE_REQUEST: "LOCALSTORAGE_REQUEST", - CANVAS_RIGHT_CLICKED: "CANVAS_RIGHT_CLICKED", + CANVAS_RIGHT_CLICKED: "CANVAS_RIGHT_CLICKED", - /** - * Event to request a refresh of the display. - * A bit overkill but, it's just workaround in our current drawing system. - * TODO: Remove or rework when redraw system is refactored. - */ - REFRESH: "REFRESH", + /** + * Event to request a refresh of the display. + * A bit overkill but, it's just workaround in our current drawing system. + * TODO: Remove or rework when redraw system is refactored. + */ + REFRESH: "REFRESH", - /** - * Temporary event to bind the redraw of right preview film to the canvas. - * This redraw should be driven by model updates. - * TODO(vincz): Remove. - */ - REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM", + /** + * Temporary event to bind the redraw of right preview film to the canvas. + * This redraw should be driven by model updates. + * TODO(vincz): Remove. + */ + REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM", - GRID_DISPLAY_STATE_CHANGED: "GRID_DISPLAY_STATE_CHANGED", + GRID_DISPLAY_STATE_CHANGED: "GRID_DISPLAY_STATE_CHANGED", - /** - * The framesheet was reseted and is now probably drastically different. - * Number of frames, content of frames, color used for the palette may have changed. - */ - FRAMESHEET_RESET: "FRAMESHEET_RESET", - - SHOW_NOTIFICATION: "SHOW_NOTIFICATION", - HIDE_NOTIFICATION: "HIDE_NOTIFICATION" + /** + * The framesheet was reseted and is now probably drastically different. + * Number of frames, content of frames, color used for the palette may have changed. + */ + FRAMESHEET_RESET: "FRAMESHEET_RESET", + + SHOW_NOTIFICATION: "SHOW_NOTIFICATION", + HIDE_NOTIFICATION: "HIDE_NOTIFICATION" }; \ No newline at end of file diff --git a/js/LocalStorageService.js b/js/LocalStorageService.js index 5397e433..dcac97bb 100644 --- a/js/LocalStorageService.js +++ b/js/LocalStorageService.js @@ -8,20 +8,20 @@ $.namespace("pskl"); pskl.LocalStorageService = (function() { - var frameSheet_; + var frameSheet_; - /** - * @private - */ - var localStorageThrottler_ = null; - - /** - * @private - */ - var persistToLocalStorageRequest_ = function() { + /** + * @private + */ + var localStorageThrottler_ = null; + + /** + * @private + */ + var persistToLocalStorageRequest_ = function() { // Persist to localStorage when drawing. We throttle localStorage accesses // for high frequency drawing (eg mousemove). - if(localStorageThrottler_ != null) { + if(localStorageThrottler_ !== null) { window.clearTimeout(localStorageThrottler_); } localStorageThrottler_ = window.setTimeout(function() { @@ -31,63 +31,63 @@ pskl.LocalStorageService = (function() { }; /** - * @private - */ - var persistToLocalStorage_ = function() { - console.log('[LocalStorage service]: Snapshot stored') - window.localStorage['snapShot'] = frameSheet_.serialize(); + * @private + */ + var persistToLocalStorage_ = function() { + console.log('[LocalStorage service]: Snapshot stored'); + window.localStorage.snapShot = frameSheet_.serialize(); }; /** - * @private - */ - var restoreFromLocalStorage_ = function() { - frameSheet_.deserialize(window.localStorage['snapShot']); + * @private + */ + var restoreFromLocalStorage_ = function() { + frameSheet_.deserialize(window.localStorage.snapShot); }; /** - * @private - */ - var cleanLocalStorage_ = function() { - console.log('[LocalStorage service]: Snapshot removed') - delete window.localStorage['snapShot']; + * @private + */ + var cleanLocalStorage_ = function() { + console.log('[LocalStorage service]: Snapshot removed'); + delete window.localStorage.snapShot; }; - return { - init: function(frameSheet) { + return { + init: function(frameSheet) { - if(frameSheet == undefined) { - throw "Bad LocalStorageService initialization: " - } - frameSheet_ = frameSheet; + if(frameSheet === undefined) { + throw "Bad LocalStorageService initialization: "; + } + frameSheet_ = frameSheet; - $.subscribe(Events.LOCALSTORAGE_REQUEST, persistToLocalStorageRequest_); - }, + $.subscribe(Events.LOCALSTORAGE_REQUEST, persistToLocalStorageRequest_); + }, - // TODO(vincz): Find a good place to put this UI rendering, a service should not render UI. - displayRestoreNotification: function() { - if(window.localStorage && window.localStorage['snapShot']) { - var reloadLink = "reload"; - var discardLink = "discard"; - var content = "Non saved version found. " + reloadLink + " or " + discardLink; + // TODO(vincz): Find a good place to put this UI rendering, a service should not render UI. + displayRestoreNotification: function() { + if(window.localStorage && window.localStorage['snapShot']) { + var reloadLink = "reload"; + var discardLink = "discard"; + var content = "Non saved version found. " + reloadLink + " or " + discardLink; - $.publish(Events.SHOW_NOTIFICATION, [{ - "content": content, - "behavior": function(rootNode) { - rootNode = $(rootNode); - rootNode.click(function(evt) { - var target = $(evt.target); - if(target.hasClass("localstorage-restore")) { - restoreFromLocalStorage_(); - } - else if (target.hasClass("localstorage-discard")) { - cleanLocalStorage_(); - } - $.publish(Events.HIDE_NOTIFICATION); - }); - } - }]); - } - } - }; + $.publish(Events.SHOW_NOTIFICATION, [{ + "content": content, + "behavior": function(rootNode) { + rootNode = $(rootNode); + rootNode.click(function(evt) { + var target = $(evt.target); + if(target.hasClass("localstorage-restore")) { + restoreFromLocalStorage_(); + } + else if (target.hasClass("localstorage-discard")) { + cleanLocalStorage_(); + } + $.publish(Events.HIDE_NOTIFICATION); + }); + } + }]); + } + } + }; })(); \ No newline at end of file diff --git a/js/Palette.js b/js/Palette.js index 7f1ffb6c..8460e398 100644 --- a/js/Palette.js +++ b/js/Palette.js @@ -7,37 +7,37 @@ $.namespace("pskl"); pskl.Palette = (function() { - - var paletteRoot, - paletteColors = []; + + var paletteRoot, + paletteColors = []; - /** - * @private - */ - var onPickerChange_ = function(evt, isPrimary) { + /** + * @private + */ + var onPickerChange_ = function(evt, isPrimary) { var inputPicker = $(evt.target); $.publish(Events.COLOR_SELECTED, [inputPicker.val(), evt.data.isPrimary]); - }; + }; - /** - * @private - */ - var createPalette_ = function (colors) { - // Always adding transparent color - paletteRoot.html(''); - for(var color in colors) { - if(color != Constants.TRANSPARENT_COLOR) { - addColorToPalette_(color); - } - } - }; + /** + * @private + */ + var createPalette_ = function (colors) { + // Always adding transparent color + paletteRoot.html(''); + for(var color in colors) { + if(color != Constants.TRANSPARENT_COLOR) { + addColorToPalette_(color); + } + } + }; - /** - * @private - */ - var addColorToPalette_ = function (color) { + /** + * @private + */ + var addColorToPalette_ = function (color) { if (paletteColors.indexOf(color) == -1 && color != Constants.TRANSPARENT_COLOR) { - var colorEl = document.createElement("li"); + var colorEl = document.createElement("li"); colorEl.className = "palette-color"; colorEl.setAttribute("data-color", color); colorEl.setAttribute("title", color); @@ -77,37 +77,37 @@ pskl.Palette = (function() { } else { colorPicker[0].color.fromString(color); } - } + }; - return { - init: function(framesheet) { - - paletteRoot = $("#palette"); + return { + init: function(framesheet) { + + paletteRoot = $("#palette"); - // Initialize palette: - createPalette_(framesheet.getUsedColors()); + // Initialize palette: + createPalette_(framesheet.getUsedColors()); - $.subscribe(Events.FRAMESHEET_RESET, function(evt) { - createPalette_(framesheet.getUsedColors()); - }); + $.subscribe(Events.FRAMESHEET_RESET, function(evt) { + createPalette_(framesheet.getUsedColors()); + }); - paletteRoot.mouseup(onPaletteColorClick_); - $.subscribe(Events.COLOR_SELECTED, function(evt, color) { - addColorToPalette_(color); - }); + paletteRoot.mouseup(onPaletteColorClick_); + $.subscribe(Events.COLOR_SELECTED, function(evt, color) { + addColorToPalette_(color); + }); - // Initialize colorpicker: - var colorPicker = $('#color-picker'); - colorPicker.val(Constants.DEFAULT_PEN_COLOR); - colorPicker.change({isPrimary : true}, onPickerChange_); + // Initialize colorpicker: + var colorPicker = $('#color-picker'); + colorPicker.val(Constants.DEFAULT_PEN_COLOR); + colorPicker.change({isPrimary : true}, onPickerChange_); var secondaryColorPicker = $('#secondary-color-picker'); secondaryColorPicker.val(Constants.TRANSPARENT_COLOR); secondaryColorPicker.change({isPrimary : false}, onPickerChange_); - } - }; + } + }; })(); diff --git a/js/ToolSelector.js b/js/ToolSelector.js index ed0c51e0..f9f05eb7 100644 --- a/js/ToolSelector.js +++ b/js/ToolSelector.js @@ -8,93 +8,83 @@ $.namespace("pskl"); pskl.ToolSelector = (function() { - - var toolInstances = { - "simplePen" : new pskl.drawingtools.SimplePen(), - "eraser" : new pskl.drawingtools.Eraser(), - "paintBucket" : new pskl.drawingtools.PaintBucket(), - "stroke" : new pskl.drawingtools.Stroke(), - "rectangle" : new pskl.drawingtools.Rectangle(), - "move" : new pskl.drawingtools.Move() - }; - var currentSelectedTool = toolInstances.simplePen; - var previousSelectedTool = toolInstances.simplePen; + + var toolInstances = { + "simplePen" : new pskl.drawingtools.SimplePen(), + "eraser" : new pskl.drawingtools.Eraser(), + "paintBucket" : new pskl.drawingtools.PaintBucket(), + "stroke" : new pskl.drawingtools.Stroke(), + "rectangle" : new pskl.drawingtools.Rectangle(), + "move" : new pskl.drawingtools.Move() + }; + var currentSelectedTool = toolInstances.simplePen; + var previousSelectedTool = toolInstances.simplePen; - var selectTool_ = function(tool) { - var maincontainer = $("body"); - var previousSelectedToolClass = maincontainer.data("selected-tool-class"); - if(previousSelectedToolClass) { - maincontainer.removeClass(previousSelectedToolClass); - } - maincontainer.addClass(toolBehavior.toolId); - $("#drawing-canvas-container").data("selected-tool-class", toolBehavior.toolId); - }; - - var activateToolOnStage_ = function(tool) { - var stage = $("body"); + var activateToolOnStage_ = function(tool) { + var stage = $("body"); var previousSelectedToolClass = stage.data("selected-tool-class"); if(previousSelectedToolClass) { stage.removeClass(previousSelectedToolClass); } stage.addClass(tool.toolId); stage.data("selected-tool-class", tool.toolId); - }; + }; - var selectTool_ = function(tool) { - console.log("Selecting Tool:" , currentSelectedTool); - currentSelectedTool = tool; - activateToolOnStage_(currentSelectedTool); - $.publish(Events.TOOL_SELECTED, [tool]); - }; + var selectTool_ = function(tool) { + console.log("Selecting Tool:" , currentSelectedTool); + currentSelectedTool = tool; + activateToolOnStage_(currentSelectedTool); + $.publish(Events.TOOL_SELECTED, [tool]); + }; - /** - * @private - */ - var onToolIconClicked_ = function(evt) { - var target = $(evt.target); - var clickedTool = target.closest(".tool-icon"); + /** + * @private + */ + var onToolIconClicked_ = function(evt) { + var target = $(evt.target); + var clickedTool = target.closest(".tool-icon"); - if(clickedTool.length) { - for(var tool in toolInstances) { - if (toolInstances[tool].toolId == clickedTool.data()["toolId"]) { - selectTool_(toolInstances[tool]); + if(clickedTool.length) { + for(var tool in toolInstances) { + if (toolInstances[tool].toolId == clickedTool.data().toolId) { + selectTool_(toolInstances[tool]); - // Show tool as selected: - $("#tools-container .tool-icon.selected").removeClass("selected"); - clickedTool.addClass("selected"); - } - } - } - }; + // Show tool as selected: + $("#tools-container .tool-icon.selected").removeClass("selected"); + clickedTool.addClass("selected"); + } + } + } + }; - /** - * Get state for the checkbox that control the display of the grid - * on the drawing canvas. - * @private - */ - var isShowGridChecked_ = function() { - var showGridCheckbox = $('#show-grid'); - var isChecked = showGridCheckbox.is(':checked'); - return isChecked; - }; + /** + * Get state for the checkbox that control the display of the grid + * on the drawing canvas. + * @private + */ + var isShowGridChecked_ = function() { + var showGridCheckbox = $('#show-grid'); + var isChecked = showGridCheckbox.is(':checked'); + return isChecked; + }; - return { - init: function() { - - // Initialize tool: - // Set SimplePen as default selected tool: - selectTool_(toolInstances.simplePen); - // Activate listener on tool panel: - $("#tools-container").click(onToolIconClicked_); + return { + init: function() { + + // Initialize tool: + // Set SimplePen as default selected tool: + selectTool_(toolInstances.simplePen); + // Activate listener on tool panel: + $("#tools-container").click(onToolIconClicked_); - // Show/hide the grid on drawing canvas: - $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [isShowGridChecked_()]) - $('#show-grid').change(function(evt) { - var checked = isShowGridChecked_(); - $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]) - }); - } - }; + // Show/hide the grid on drawing canvas: + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [isShowGridChecked_()]) + $('#show-grid').change(function(evt) { + var checked = isShowGridChecked_(); + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]) + }); + } + }; })(); diff --git a/js/utils.js b/js/utils.js index 2b475b1a..9fb8da68 100644 --- a/js/utils.js +++ b/js/utils.js @@ -16,7 +16,7 @@ jQuery.namespace = function() { * * @require Constants */ -(function(ns) { // namespace: pskl.utils +(function() { // namespace: pskl.utils var ns = $.namespace("pskl.utils"); @@ -35,5 +35,5 @@ jQuery.namespace = function() { //prototypeskl.ToolBehavior.Eraser.prototype.constructor = pskl.ToolBehavior.Eraser; }; -})() +})(); From 11dda9da9ca1efb0834e75a7e652c3898258cd38 Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Tue, 11 Sep 2012 00:54:06 +0200 Subject: [PATCH 30/30] fixed jshint complaints --- js/LocalStorageService.js | 2 +- js/ToolSelector.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/js/LocalStorageService.js b/js/LocalStorageService.js index dcac97bb..63cc3b59 100644 --- a/js/LocalStorageService.js +++ b/js/LocalStorageService.js @@ -66,7 +66,7 @@ pskl.LocalStorageService = (function() { // TODO(vincz): Find a good place to put this UI rendering, a service should not render UI. displayRestoreNotification: function() { - if(window.localStorage && window.localStorage['snapShot']) { + if(window.localStorage && window.localStorage.snapShot) { var reloadLink = "reload"; var discardLink = "discard"; var content = "Non saved version found. " + reloadLink + " or " + discardLink; diff --git a/js/ToolSelector.js b/js/ToolSelector.js index f9f05eb7..e2a9befa 100644 --- a/js/ToolSelector.js +++ b/js/ToolSelector.js @@ -78,10 +78,10 @@ pskl.ToolSelector = (function() { $("#tools-container").click(onToolIconClicked_); // Show/hide the grid on drawing canvas: - $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [isShowGridChecked_()]) + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [isShowGridChecked_()]); $('#show-grid').change(function(evt) { var checked = isShowGridChecked_(); - $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]) + $.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]); }); } };