diff --git a/css/style.css b/css/style.css
index 63e082c9..fb44b886 100644
--- a/css/style.css
+++ b/css/style.css
@@ -73,10 +73,7 @@
}
.drawing-canvas {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 1;
+ float: left;
}
.canvas-overlay {
diff --git a/index.html b/index.html
index 8cfdadac..91efbe58 100644
--- a/index.html
+++ b/index.html
@@ -91,10 +91,10 @@
+
-
diff --git a/js/controller/AnimatedPreviewController.js b/js/controller/AnimatedPreviewController.js
index fd99578b..c8b7f51a 100644
--- a/js/controller/AnimatedPreviewController.js
+++ b/js/controller/AnimatedPreviewController.js
@@ -1,36 +1,27 @@
(function () {
var ns = $.namespace("pskl.controller");
ns.AnimatedPreviewController = function (framesheet, container, dpi) {
- this.dpi = dpi;
this.framesheet = framesheet;
this.container = container;
this.animIndex = 0;
this.fps = parseInt($("#preview-fps")[0].value, 10);
- this.renderer = new pskl.rendering.FrameRenderer();
+ var renderingOptions = {
+ "dpi": dpi
+ };
+ this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions);
};
ns.AnimatedPreviewController.prototype.init = function () {
this.initDom();
+
+ this.renderer.init(this.framesheet.getFrameByIndex(this.animIndex));
+
this.startAnimationTimer();
};
ns.AnimatedPreviewController.prototype.initDom = function () {
- var frame = this.framesheet.getFrameByIndex(0);
- var height = frame.getHeight() * this.dpi,
- width = frame.getWidth() * this.dpi;
-
- previewCanvas = document.createElement('canvas');
- previewCanvas.className = 'canvas';
-
- this.container.setAttribute('style', 'width:' + width + 'px; height:' + height + 'px;');
- previewCanvas.setAttribute('width', width);
- previewCanvas.setAttribute('height', height);
-
- this.container.appendChild(previewCanvas);
- this.previewCanvas = previewCanvas;
-
$("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this));
};
@@ -54,8 +45,7 @@
if (!this.framesheet.hasFrameAtIndex(this.animIndex)) {
this.animIndex = 0;
}
-
- this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex), this.previewCanvas, this.dpi);
+ this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex));
this.animIndex++;
this.startAnimationTimer();
};
diff --git a/js/controller/DrawingController.js b/js/controller/DrawingController.js
index 3752bd52..f6043669 100644
--- a/js/controller/DrawingController.js
+++ b/js/controller/DrawingController.js
@@ -3,62 +3,46 @@
ns.DrawingController = function (frame, container, dpi) {
this.dpi = dpi;
+ var renderingOptions = {
+ "dpi": dpi,
+ "displayGrid": true // Retrieve from localsotrage config
+ }
+
// Public
this.frame = frame;
- this.overlay = pskl.model.Frame.createEmptyFromFrame(frame);
+ this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); // Type is frame
// Private
this.container = container;
- this.mainCanvas = this.createMainCanvas();
- this.overlayCanvas = this.createOverlayCanvas();
- this.renderer = new pskl.rendering.FrameRenderer();
+ 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.overlayRenderer.init(this.frame);
+ };
+
+ ns.DrawingController.prototype.updateDPI = function (newDPI) {
+ this.renderer.updateDPI(newDPI);
+ this.overlayRenderer.updateDPI(newDPI);
+
+ this.renderer.render(this.frame);
+ this.overlayRenderer.render(this.frame);
};
ns.DrawingController.prototype.renderFrame = function () {
- this.renderer.render(this.frame, this.mainCanvas, this.dpi);
+ this.renderer.render(this.frame);
};
ns.DrawingController.prototype.renderFramePixel = function (col, row) {
- this.renderer.drawPixel(col, row, this.frame, this.mainCanvas, this.dpi);
+ this.renderer.drawPixel(col, row, this.frame);
};
ns.DrawingController.prototype.renderOverlay = function () {
- this.renderer.render(this.overlay, this.overlayCanvas, this.dpi);
+ this.overlayRenderer.render(this.overlayFrame);
};
ns.DrawingController.prototype.clearOverlay = function () {
- this.overlay = pskl.model.Frame.createEmptyFromFrame(this.frame);
- this.overlayCanvas.getContext("2d").clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
- };
-
- ns.DrawingController.prototype.createMainCanvas = function () {
- var mainCanvas = this.createCanvas();
- mainCanvas.className = "drawing-canvas";
- this.container.appendChild(mainCanvas);
- return mainCanvas;
- };
-
- // For some tools, we need a fake canvas that overlay the drawing canvas. These tools are
- // generally 'drap and release' based tools (stroke, selection, etc) and the fake canvas
- // will help to visualize the tool interaction (without modifying the canvas).
- ns.DrawingController.prototype.createOverlayCanvas = function () {
- var overlayCanvas = this.createCanvas();
- overlayCanvas.className = "canvas-overlay";
- this.container.appendChild(overlayCanvas);
- return overlayCanvas;
- };
-
- // For some tools, we need a fake canvas that overlay the drawing canvas. These tools are
- // generally 'drap and release' based tools (stroke, selection, etc) and the fake canvas
- // will help to visualize the tool interaction (without modifying the canvas).
- ns.DrawingController.prototype.createCanvas = function () {
- var width = this.frame.getWidth(),
- height = this.frame.getHeight();
-
- var canvas = document.createElement("canvas");
- canvas.setAttribute("width", width * this.dpi);
- canvas.setAttribute("height", height * this.dpi);
-
- return canvas;
+ this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(this.frame);
+ this.overlayRenderer.clear();
};
})();
\ No newline at end of file
diff --git a/js/controller/PreviewFilmController.js b/js/controller/PreviewFilmController.js
index 4da2be07..8317066e 100644
--- a/js/controller/PreviewFilmController.js
+++ b/js/controller/PreviewFilmController.js
@@ -5,14 +5,14 @@
this.dpi = dpi;
this.framesheet = framesheet;
this.container = container;
-
- this.renderer = new pskl.rendering.FrameRenderer();
};
ns.PreviewFilmController.prototype.init = function() {
var addFrameButton = $('#add-frame-button')[0];
addFrameButton.addEventListener('mousedown', this.addFrame.bind(this));
this.createPreviews();
+
+
};
ns.PreviewFilmController.prototype.addFrame = function () {
@@ -140,9 +140,9 @@
* TODO(vincz): clean this giant rendering function & remove listeners.
*/
ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) {
- var frame = this.framesheet.getFrameByIndex(tileNumber);
- var width = frame.getWidth() * this.dpi,
- height = frame.getHeight() * this.dpi;
+ 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";
@@ -155,18 +155,19 @@
var canvasContainer = document.createElement("div");
canvasContainer.className = "canvas-container";
- canvasContainer.setAttribute('style', 'width:' + width + 'px; height:' + height + 'px;');
+ //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:
if(!evt.target.classList.contains('tile-action')) {
@@ -182,8 +183,14 @@
piskel.duplicateFrame(tileNumber);
});
- this.renderer.render(this.framesheet.getFrameByIndex(tileNumber), canvasPreview, this.dpi);
- canvasContainer.appendChild(canvasPreview);
+ //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 };
+ var currentFrameRenderer = new pskl.rendering.FrameRenderer(canvasContainer, renderingOptions, "tile-view");
+ currentFrameRenderer.init(currentFrame);
+
previewTileRoot.appendChild(canvasContainer);
previewTileRoot.appendChild(canvasPreviewDuplicateAction);
diff --git a/js/drawingtools/Rectangle.js b/js/drawingtools/Rectangle.js
index 87709026..36967878 100644
--- a/js/drawingtools/Rectangle.js
+++ b/js/drawingtools/Rectangle.js
@@ -24,7 +24,7 @@
this.startRow = row;
// Drawing the first point of the rectangle in the fake overlay canvas:
- drawer.overlay.setPixel(col, row, color);
+ drawer.overlayFrame.setPixel(col, row, color);
drawer.renderOverlay();
};
@@ -42,7 +42,7 @@
if(color == Constants.TRANSPARENT_COLOR) {
color = Constants.SELECTION_TRANSPARENT_COLOR;
}
- drawer.overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color);
+ drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
}
drawer.renderOverlay();
};
diff --git a/js/drawingtools/Stroke.js b/js/drawingtools/Stroke.js
index 92bb8450..13dabac3 100644
--- a/js/drawingtools/Stroke.js
+++ b/js/drawingtools/Stroke.js
@@ -34,7 +34,7 @@
// 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.overlay.setPixel(col, row, color);
+ drawer.overlayFrame.setPixel(col, row, color);
drawer.renderOverlay();
};
@@ -57,7 +57,7 @@
// eg deleting the equivalent of a stroke.
color = Constants.SELECTION_TRANSPARENT_COLOR;
}
- drawer.overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color);
+ drawer.overlayFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
}
drawer.renderOverlay();
};
diff --git a/js/piskel.js b/js/piskel.js
index e195c05d..af4f7a79 100644
--- a/js/piskel.js
+++ b/js/piskel.js
@@ -11,23 +11,18 @@ $.namespace("pskl");
*/
var frameSheet,
- // Temporary zoom implementation to easily get bigger canvases to
- // see how good perform critical algorithms on big canvas.
- zoom = 1,
-
// Configuration:
// Canvas size in pixel size (not dpi related)
- framePixelWidth = 32 * zoom,
- framePixelHeight = 32 * zoom,
-
+ framePixelWidth = 32,
+ framePixelHeight = 32,
// Scaling factors for a given frameSheet rendering:
// Main drawing area:
- drawingCanvasDpi = Math.ceil(20/ zoom),
- // Canvas previous in the slideshow:
- previewTileCanvasDpi = Math.ceil(4 / zoom),
- // Ainmated canvas preview:
- previewAnimationCanvasDpi = Math.ceil(8 / zoom),
+ drawingCanvasDpi = 20,
+ // Canvas preview film canvases:
+ previewTileCanvasDpi = 4,
+ // Animated canvas preview:
+ previewAnimationCanvasDpi = 8,
// DOM references:
drawingAreaContainer,
@@ -53,6 +48,9 @@ $.namespace("pskl");
var piskel = {
init : function () {
+
+ piskel.initDPIs_();
+
frameSheet = new pskl.model.FrameSheet(framePixelWidth, framePixelHeight);
frameSheet.addEmptyFrame();
@@ -95,6 +93,29 @@ $.namespace("pskl");
}
},
+ /**
+ * Override default DPIs.
+ * @private
+ */
+ initDPIs_ : function() {
+
+ drawingCanvasDpi = piskel.calculateDPIsForDrawingCanvas_();
+ // TODO(vincz): Add throttling on window.resize event.
+ $(window).resize($.proxy(function() {
+ drawingCanvasDpi = piskel.calculateDPIsForDrawingCanvas_();
+ this.drawingController.updateDPI(drawingCanvasDpi);
+ }, this));
+ // TODO(vincz): Check for user settings eventually from localstorage.
+ },
+
+ /**
+ * @private
+ */
+ calculateDPIsForDrawingCanvas_ : function() {
+ var availableViewportHeight = $('.main-panel').height();
+ return Math.floor(availableViewportHeight / framePixelHeight);
+ },
+
finishInit : function () {
$.subscribe(Events.TOOL_SELECTED, function(evt, toolBehavior) {
@@ -186,8 +207,6 @@ $.namespace("pskl");
document.body.addEventListener('mouseup', this.onMouseup.bind(this));
drawingAreaContainer.addEventListener('mousedown', this.onMousedown.bind(this));
drawingAreaContainer.addEventListener('mousemove', this.onMousemove.bind(this));
- drawingAreaContainer.style.width = framePixelWidth * drawingCanvasDpi + "px";
- drawingAreaContainer.style.height = framePixelHeight * drawingCanvasDpi + "px";
document.body.addEventListener('contextmenu', this.onCanvasContextMenu);
},
diff --git a/js/rendering/FrameRenderer.js b/js/rendering/FrameRenderer.js
index 8b630579..63b96533 100644
--- a/js/rendering/FrameRenderer.js
+++ b/js/rendering/FrameRenderer.js
@@ -1,20 +1,49 @@
(function () {
var ns = $.namespace("pskl.rendering");
- ns.FrameRenderer = function () {};
- ns.FrameRenderer.prototype.render = function (frame, canvas, dpi) {
+ 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)) {
+ throw "Bad FrameRenderer initialization. not well defined.";
+ }
+
+ this.displayGrid = !!renderingOptions.displayGrid;
+ this.dpi = renderingOptions.dpi;
+ this.className = className;
+
+ // Flag to know if the config was altered
+ this.canvasConfigDirty = true;
+ };
+
+ ns.FrameRenderer.prototype.init = function (frame) {
+ this.render(frame);
+ };
+
+ ns.FrameRenderer.prototype.updateDPI = function (newDPI) {
+ this.dpi = newDPI;
+ this.canvasConfigDirty = true;
+ };
+
+ 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, canvas, dpi);
+ this.drawPixel(col, row, frame, this.getCanvas_(frame), this.dpi);
}
}
};
- ns.FrameRenderer.prototype.drawPixel = function (col, row, frame, canvas, dpi) {
- var context = canvas.getContext('2d');
+ ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) {
+ var context = this.getCanvas_(frame).getContext('2d');
var color = frame.getPixel(col, row);
if(color == Constants.TRANSPARENT_COLOR) {
- context.clearRect(col * dpi, row * dpi, dpi, dpi);
+ context.clearRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi);
}
else {
if(color != Constants.SELECTION_TRANSPARENT_COLOR) {
@@ -22,7 +51,39 @@
$.publish(Events.COLOR_USED, [color]);
}
context.fillStyle = color;
- context.fillRect(col * dpi, row * dpi, dpi, dpi);
+ context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi);
}
};
+
+ ns.FrameRenderer.prototype.clear = function (col, row, frame) {
+ var canvas = this.getCanvas_(frame)
+ canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
+ };
+
+ /**
+ * @private
+ */
+ 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.container.appendChild(this.canvas);
+
+ this.canvasConfigDirty = false;
+ }
+ return this.canvas;
+ };
})();
\ No newline at end of file