mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Merge branch 'master' into gh-pages
This commit is contained in:
@@ -73,10 +73,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drawing-canvas {
|
.drawing-canvas {
|
||||||
position: absolute;
|
float: left;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas-overlay {
|
.canvas-overlay {
|
||||||
|
|||||||
@@ -91,10 +91,10 @@
|
|||||||
<!-- Application libraries-->
|
<!-- Application libraries-->
|
||||||
<script src="js/model/Frame.js"></script>
|
<script src="js/model/Frame.js"></script>
|
||||||
<script src="js/model/FrameSheet.js"></script>
|
<script src="js/model/FrameSheet.js"></script>
|
||||||
|
<script src="js/rendering/FrameRenderer.js"></script>
|
||||||
<script src="js/controller/DrawingController.js"></script>
|
<script src="js/controller/DrawingController.js"></script>
|
||||||
<script src="js/controller/PreviewFilmController.js"></script>
|
<script src="js/controller/PreviewFilmController.js"></script>
|
||||||
<script src="js/controller/AnimatedPreviewController.js"></script>
|
<script src="js/controller/AnimatedPreviewController.js"></script>
|
||||||
<script src="js/rendering/FrameRenderer.js"></script>
|
|
||||||
<script src="js/LocalStorageService.js"></script>
|
<script src="js/LocalStorageService.js"></script>
|
||||||
<script src="js/HistoryManager.js"></script>
|
<script src="js/HistoryManager.js"></script>
|
||||||
<script src="js/Palette.js"></script>
|
<script src="js/Palette.js"></script>
|
||||||
|
|||||||
@@ -1,36 +1,27 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.controller");
|
var ns = $.namespace("pskl.controller");
|
||||||
ns.AnimatedPreviewController = function (framesheet, container, dpi) {
|
ns.AnimatedPreviewController = function (framesheet, container, dpi) {
|
||||||
this.dpi = dpi;
|
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.animIndex = 0;
|
this.animIndex = 0;
|
||||||
|
|
||||||
this.fps = parseInt($("#preview-fps")[0].value, 10);
|
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 () {
|
ns.AnimatedPreviewController.prototype.init = function () {
|
||||||
this.initDom();
|
this.initDom();
|
||||||
|
|
||||||
|
this.renderer.init(this.framesheet.getFrameByIndex(this.animIndex));
|
||||||
|
|
||||||
this.startAnimationTimer();
|
this.startAnimationTimer();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnimatedPreviewController.prototype.initDom = function () {
|
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));
|
$("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,8 +45,7 @@
|
|||||||
if (!this.framesheet.hasFrameAtIndex(this.animIndex)) {
|
if (!this.framesheet.hasFrameAtIndex(this.animIndex)) {
|
||||||
this.animIndex = 0;
|
this.animIndex = 0;
|
||||||
}
|
}
|
||||||
|
this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex));
|
||||||
this.renderer.render(this.framesheet.getFrameByIndex(this.animIndex), this.previewCanvas, this.dpi);
|
|
||||||
this.animIndex++;
|
this.animIndex++;
|
||||||
this.startAnimationTimer();
|
this.startAnimationTimer();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,62 +3,46 @@
|
|||||||
ns.DrawingController = function (frame, container, dpi) {
|
ns.DrawingController = function (frame, container, dpi) {
|
||||||
this.dpi = dpi;
|
this.dpi = dpi;
|
||||||
|
|
||||||
|
var renderingOptions = {
|
||||||
|
"dpi": dpi,
|
||||||
|
"displayGrid": true // Retrieve from localsotrage config
|
||||||
|
}
|
||||||
|
|
||||||
// Public
|
// Public
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.overlay = pskl.model.Frame.createEmptyFromFrame(frame);
|
this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); // Type is frame
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.mainCanvas = this.createMainCanvas();
|
this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "drawing-canvas");
|
||||||
this.overlayCanvas = this.createOverlayCanvas();
|
this.overlayRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "canvas-overlay");
|
||||||
this.renderer = new pskl.rendering.FrameRenderer();
|
|
||||||
|
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 () {
|
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) {
|
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 () {
|
ns.DrawingController.prototype.renderOverlay = function () {
|
||||||
this.renderer.render(this.overlay, this.overlayCanvas, this.dpi);
|
this.overlayRenderer.render(this.overlayFrame);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingController.prototype.clearOverlay = function () {
|
ns.DrawingController.prototype.clearOverlay = function () {
|
||||||
this.overlay = pskl.model.Frame.createEmptyFromFrame(this.frame);
|
this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(this.frame);
|
||||||
this.overlayCanvas.getContext("2d").clearRect(0, 0, this.overlayCanvas.width, this.overlayCanvas.height);
|
this.overlayRenderer.clear();
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
@@ -5,14 +5,14 @@
|
|||||||
this.dpi = dpi;
|
this.dpi = dpi;
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
this.renderer = new pskl.rendering.FrameRenderer();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.init = function() {
|
ns.PreviewFilmController.prototype.init = function() {
|
||||||
var addFrameButton = $('#add-frame-button')[0];
|
var addFrameButton = $('#add-frame-button')[0];
|
||||||
addFrameButton.addEventListener('mousedown', this.addFrame.bind(this));
|
addFrameButton.addEventListener('mousedown', this.addFrame.bind(this));
|
||||||
this.createPreviews();
|
this.createPreviews();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.addFrame = function () {
|
ns.PreviewFilmController.prototype.addFrame = function () {
|
||||||
@@ -92,7 +92,10 @@
|
|||||||
*/
|
*/
|
||||||
ns.PreviewFilmController.prototype.onDrop_ = function( event, ui ) {
|
ns.PreviewFilmController.prototype.onDrop_ = function( event, ui ) {
|
||||||
var activeFrame;
|
var activeFrame;
|
||||||
var originFrameId = parseInt($(event.srcElement).data("tile-number"), 10);
|
// When we drag from an element, the drag could start from a nested DOM element
|
||||||
|
// 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);
|
var dropTarget = $(event.target);
|
||||||
|
|
||||||
if(dropTarget.data("tile-type") == "interstitial") {
|
if(dropTarget.data("tile-type") == "interstitial") {
|
||||||
@@ -101,7 +104,7 @@
|
|||||||
if(isNaN(originFrameId) || isNaN(targetInsertionId)) {
|
if(isNaN(originFrameId) || isNaN(targetInsertionId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("origin-frame: "+originFrameId+" - targetInsertionId: "+ targetInsertionId)
|
//console.log("origin-frame: "+originFrameId+" - targetInsertionId: "+ targetInsertionId)
|
||||||
this.framesheet.moveFrame(originFrameId, targetInsertionId);
|
this.framesheet.moveFrame(originFrameId, targetInsertionId);
|
||||||
|
|
||||||
activeFrame = targetInsertionId;
|
activeFrame = targetInsertionId;
|
||||||
@@ -119,7 +122,7 @@
|
|||||||
if(isNaN(originFrameId) || isNaN(targetSwapId)) {
|
if(isNaN(originFrameId) || isNaN(targetSwapId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("origin-frame: "+originFrameId+" - targetSwapId: "+ targetSwapId)
|
//console.log("origin-frame: "+originFrameId+" - targetSwapId: "+ targetSwapId)
|
||||||
this.framesheet.swapFrames(originFrameId, targetSwapId);
|
this.framesheet.swapFrames(originFrameId, targetSwapId);
|
||||||
activeFrame = targetSwapId;
|
activeFrame = targetSwapId;
|
||||||
}
|
}
|
||||||
@@ -140,9 +143,9 @@
|
|||||||
* TODO(vincz): clean this giant rendering function & remove listeners.
|
* TODO(vincz): clean this giant rendering function & remove listeners.
|
||||||
*/
|
*/
|
||||||
ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) {
|
ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) {
|
||||||
var frame = this.framesheet.getFrameByIndex(tileNumber);
|
var currentFrame = this.framesheet.getFrameByIndex(tileNumber);
|
||||||
var width = frame.getWidth() * this.dpi,
|
//var width = frame.getWidth() * this.dpi,
|
||||||
height = frame.getHeight() * this.dpi;
|
// height = frame.getHeight() * this.dpi;
|
||||||
|
|
||||||
var previewTileRoot = document.createElement("li");
|
var previewTileRoot = document.createElement("li");
|
||||||
var classname = "preview-tile";
|
var classname = "preview-tile";
|
||||||
@@ -155,18 +158,19 @@
|
|||||||
|
|
||||||
var canvasContainer = document.createElement("div");
|
var canvasContainer = document.createElement("div");
|
||||||
canvasContainer.className = "canvas-container";
|
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");
|
var canvasBackground = document.createElement("div");
|
||||||
canvasBackground.className = "canvas-background";
|
canvasBackground.className = "canvas-background";
|
||||||
canvasContainer.appendChild(canvasBackground);
|
canvasContainer.appendChild(canvasBackground);
|
||||||
|
/*
|
||||||
var canvasPreview = document.createElement("canvas");
|
var canvasPreview = document.createElement("canvas");
|
||||||
canvasPreview.className = "canvas tile-view"
|
canvasPreview.className = "canvas tile-view"
|
||||||
|
|
||||||
canvasPreview.setAttribute('width', width);
|
canvasPreview.setAttribute('width', width);
|
||||||
canvasPreview.setAttribute('height', height);
|
canvasPreview.setAttribute('height', height);
|
||||||
|
*/
|
||||||
|
|
||||||
previewTileRoot.addEventListener('click', function(evt) {
|
previewTileRoot.addEventListener('click', function(evt) {
|
||||||
// has not class tile-action:
|
// has not class tile-action:
|
||||||
if(!evt.target.classList.contains('tile-action')) {
|
if(!evt.target.classList.contains('tile-action')) {
|
||||||
@@ -182,8 +186,14 @@
|
|||||||
piskel.duplicateFrame(tileNumber);
|
piskel.duplicateFrame(tileNumber);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.renderer.render(this.framesheet.getFrameByIndex(tileNumber), canvasPreview, this.dpi);
|
//this.renderer.render(this.framesheet.getFrameByIndex(tileNumber), canvasPreview);
|
||||||
canvasContainer.appendChild(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(canvasContainer);
|
||||||
previewTileRoot.appendChild(canvasPreviewDuplicateAction);
|
previewTileRoot.appendChild(canvasPreviewDuplicateAction);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
this.startRow = row;
|
this.startRow = row;
|
||||||
|
|
||||||
// Drawing the first point of the rectangle in the fake overlay canvas:
|
// 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();
|
drawer.renderOverlay();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
if(color == Constants.TRANSPARENT_COLOR) {
|
||||||
color = Constants.SELECTION_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();
|
drawer.renderOverlay();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
// The fake canvas where we will draw the preview of the stroke:
|
// The fake canvas where we will draw the preview of the stroke:
|
||||||
// Drawing the first point of the stroke in the fake overlay canvas:
|
// 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();
|
drawer.renderOverlay();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
// eg deleting the equivalent of a stroke.
|
// eg deleting the equivalent of a stroke.
|
||||||
color = Constants.SELECTION_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();
|
drawer.renderOverlay();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
ns.Frame = function (pixels) {
|
ns.Frame = function (pixels) {
|
||||||
this.pixels = pixels;
|
this.pixels = pixels;
|
||||||
this.previousStates = [this._clonePixels()];
|
this.previousStates = [this.getPixels()];
|
||||||
this.stateIndex = 0;
|
this.stateIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,12 +27,30 @@
|
|||||||
return new ns.Frame(this._clonePixels());
|
return new ns.Frame(this._clonePixels());
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype._clonePixels = function () {
|
/**
|
||||||
var pixels = [];
|
* Returns a copy of the pixels used by the frame
|
||||||
for (var col = 0 ; col < this.getWidth() ; col++) {
|
*/
|
||||||
pixels[col] = this.pixels[col].slice(0 , this.getHeight());
|
ns.Frame.prototype.getPixels = function () {
|
||||||
|
return this.clonePixels_(this.pixels)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the passed pixels into the frame.
|
||||||
|
*/
|
||||||
|
ns.Frame.prototype.setPixels = function (pixels) {
|
||||||
|
this.pixels = this.clonePixels_(pixels);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone a set of pixels. Should be static utility method
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.Frame.prototype.clonePixels_ = function (pixels) {
|
||||||
|
var clonedPixels = [];
|
||||||
|
for (var col = 0 ; col < pixels.length ; col++) {
|
||||||
|
clonedPixels[col] = pixels[col].slice(0 , this.getHeight());
|
||||||
}
|
}
|
||||||
return pixels;
|
return clonedPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.serialize = function () {
|
ns.Frame.prototype.serialize = function () {
|
||||||
@@ -63,7 +81,7 @@
|
|||||||
// remove all states past current state
|
// remove all states past current state
|
||||||
this.previousStates.length = this.stateIndex + 1;
|
this.previousStates.length = this.stateIndex + 1;
|
||||||
// push new state
|
// push new state
|
||||||
this.previousStates.push(this._clonePixels());
|
this.previousStates.push(this.getPixels());
|
||||||
// set the stateIndex to latest saved state
|
// set the stateIndex to latest saved state
|
||||||
this.stateIndex = this.previousStates.length - 1;
|
this.stateIndex = this.previousStates.length - 1;
|
||||||
};
|
};
|
||||||
@@ -71,14 +89,14 @@
|
|||||||
ns.Frame.prototype.loadPreviousState = function () {
|
ns.Frame.prototype.loadPreviousState = function () {
|
||||||
if (this.stateIndex > 0) {
|
if (this.stateIndex > 0) {
|
||||||
this.stateIndex--;
|
this.stateIndex--;
|
||||||
this.pixels = this.previousStates[this.stateIndex];
|
this.setPixels(this.previousStates[this.stateIndex]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.loadNextState = function () {
|
ns.Frame.prototype.loadNextState = function () {
|
||||||
if (this.stateIndex < this.previousStates.length - 1) {
|
if (this.stateIndex < this.previousStates.length - 1) {
|
||||||
this.stateIndex++;
|
this.stateIndex++;
|
||||||
this.pixels = this.previousStates[this.stateIndex];
|
this.setPixels(this.previousStates[this.stateIndex]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
71
js/piskel.js
71
js/piskel.js
@@ -11,23 +11,18 @@ $.namespace("pskl");
|
|||||||
*/
|
*/
|
||||||
var frameSheet,
|
var frameSheet,
|
||||||
|
|
||||||
// Temporary zoom implementation to easily get bigger canvases to
|
|
||||||
// see how good perform critical algorithms on big canvas.
|
|
||||||
zoom = 1,
|
|
||||||
|
|
||||||
// Configuration:
|
// Configuration:
|
||||||
// Canvas size in pixel size (not dpi related)
|
// Canvas size in pixel size (not dpi related)
|
||||||
framePixelWidth = 32 * zoom,
|
framePixelWidth = 32,
|
||||||
framePixelHeight = 32 * zoom,
|
framePixelHeight = 32,
|
||||||
|
|
||||||
|
|
||||||
// Scaling factors for a given frameSheet rendering:
|
// Scaling factors for a given frameSheet rendering:
|
||||||
// Main drawing area:
|
// Main drawing area:
|
||||||
drawingCanvasDpi = Math.ceil(20/ zoom),
|
drawingCanvasDpi = 20,
|
||||||
// Canvas previous in the slideshow:
|
// Canvas preview film canvases:
|
||||||
previewTileCanvasDpi = Math.ceil(4 / zoom),
|
previewTileCanvasDpi = 4,
|
||||||
// Ainmated canvas preview:
|
// Animated canvas preview:
|
||||||
previewAnimationCanvasDpi = Math.ceil(8 / zoom),
|
previewAnimationCanvasDpi = 8,
|
||||||
|
|
||||||
// DOM references:
|
// DOM references:
|
||||||
drawingAreaContainer,
|
drawingAreaContainer,
|
||||||
@@ -53,6 +48,9 @@ $.namespace("pskl");
|
|||||||
var piskel = {
|
var piskel = {
|
||||||
|
|
||||||
init : function () {
|
init : function () {
|
||||||
|
|
||||||
|
piskel.initDPIs_();
|
||||||
|
|
||||||
frameSheet = new pskl.model.FrameSheet(framePixelWidth, framePixelHeight);
|
frameSheet = new pskl.model.FrameSheet(framePixelWidth, framePixelHeight);
|
||||||
frameSheet.addEmptyFrame();
|
frameSheet.addEmptyFrame();
|
||||||
|
|
||||||
@@ -95,6 +93,53 @@ $.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(),
|
||||||
|
availableViewportWidth = $('.main-panel').width(),
|
||||||
|
previewHeight = $(".preview-container").height(),
|
||||||
|
previewWidth = $(".preview-container").width();
|
||||||
|
|
||||||
|
var heightBoundDpi = Math.floor(availableViewportHeight / framePixelHeight),
|
||||||
|
widthBoundDpi = Math.floor(availableViewportWidth / framePixelWidth);
|
||||||
|
|
||||||
|
var dpi = Math.min(heightBoundDpi, widthBoundDpi);
|
||||||
|
|
||||||
|
var drawingCanvasHeight = dpi * framePixelHeight;
|
||||||
|
var drawingCanvasWidth = dpi * framePixelWidth;
|
||||||
|
|
||||||
|
// Check if preview and drawing canvas overlap
|
||||||
|
var heightGap = drawingCanvasHeight + previewHeight - availableViewportHeight,
|
||||||
|
widthGap = drawingCanvasWidth + previewWidth - availableViewportWidth;
|
||||||
|
if (heightGap > 0 && widthGap > 0) {
|
||||||
|
// Calculate the DPI change needed to bridge height and width gap
|
||||||
|
var heightGapDpi = Math.ceil(heightGap / framePixelHeight),
|
||||||
|
widthGapDpi = Math.ceil(widthGap / framePixelWidth);
|
||||||
|
|
||||||
|
// substract smallest dpi change to initial dpi
|
||||||
|
dpi -= Math.min(heightGapDpi, widthGapDpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dpi;
|
||||||
|
},
|
||||||
|
|
||||||
finishInit : function () {
|
finishInit : function () {
|
||||||
|
|
||||||
$.subscribe(Events.TOOL_SELECTED, function(evt, toolBehavior) {
|
$.subscribe(Events.TOOL_SELECTED, function(evt, toolBehavior) {
|
||||||
@@ -186,8 +231,6 @@ $.namespace("pskl");
|
|||||||
document.body.addEventListener('mouseup', this.onMouseup.bind(this));
|
document.body.addEventListener('mouseup', this.onMouseup.bind(this));
|
||||||
drawingAreaContainer.addEventListener('mousedown', this.onMousedown.bind(this));
|
drawingAreaContainer.addEventListener('mousedown', this.onMousedown.bind(this));
|
||||||
drawingAreaContainer.addEventListener('mousemove', this.onMousemove.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);
|
document.body.addEventListener('contextmenu', this.onCanvasContextMenu);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,49 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.rendering");
|
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. <container> undefined.";
|
||||||
|
}
|
||||||
|
this.container = container;
|
||||||
|
|
||||||
|
if(renderingOptions == undefined || renderingOptions.dpi == undefined || isNaN(dpi)) {
|
||||||
|
throw "Bad FrameRenderer initialization. <dpi> 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 col = 0, width = frame.getWidth(); col < width; col++) {
|
||||||
for(var row = 0, height = frame.getHeight(); row < height; row++) {
|
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) {
|
ns.FrameRenderer.prototype.drawPixel = function (col, row, frame) {
|
||||||
var context = canvas.getContext('2d');
|
var context = this.getCanvas_(frame).getContext('2d');
|
||||||
var color = frame.getPixel(col, row);
|
var color = frame.getPixel(col, row);
|
||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
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 {
|
else {
|
||||||
if(color != Constants.SELECTION_TRANSPARENT_COLOR) {
|
if(color != Constants.SELECTION_TRANSPARENT_COLOR) {
|
||||||
@@ -22,7 +51,39 @@
|
|||||||
$.publish(Events.COLOR_USED, [color]);
|
$.publish(Events.COLOR_USED, [color]);
|
||||||
}
|
}
|
||||||
context.fillStyle = 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;
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
Reference in New Issue
Block a user