Merge from master + bugfixing on b64

This commit is contained in:
jdescottes 2013-08-10 14:47:26 +02:00
commit c23de31e07
42 changed files with 2259 additions and 2223 deletions

View File

@ -19,6 +19,14 @@ module.exports = function (grunt) {
"smarttabs": true,
"eqnull": true
},*/
options: {
indent:2,
undef : true,
latedef : true,
browser : true,
jquery : true,
globals : {'pskl':true, 'Events':true, 'Constants':true, 'console' : true, 'module':true, 'require':true}
},
files: [
'Gruntfile.js',
'package.json',
@ -69,13 +77,23 @@ module.exports = function (grunt) {
}
});
grunt.config.set('leadingIndent.indentation', 'spaces');
grunt.config.set('leadingIndent.jsFiles', {
src: ['js/**/*.js','!js/lib/**/*.js']
});
grunt.config.set('leadingIndent.cssFiles', {
src: ['css/**/*.css']
});
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-ghost');
grunt.loadNpmTasks('grunt-leading-indent');
grunt.registerTask('lint', ['leadingIndent:jsFiles', 'leadingIndent:cssFiles', 'jshint']);
grunt.registerTask('test', ['leadingIndent:jsFiles', 'leadingIndent:cssFiles', 'jshint', 'connect', 'ghost']);
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
grunt.registerTask('lint', ['jshint']);
grunt.registerTask('test', ['jshint', 'connect', 'ghost']);
};

View File

@ -8,6 +8,8 @@ var Constants = {
MAX_HEIGHT : 128,
MAX_WIDTH : 128,
PREVIEW_FILM_SIZE : 120,
DEFAULT_PEN_COLOR : '#000000',
TRANSPARENT_COLOR : 'TRANSPARENT',

View File

@ -25,8 +25,6 @@
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(framesheet.getCurrentFrame());
this.overlayRenderer.init(this.overlayFrame);
// State of drawing controller:
this.isClicked = false;
@ -35,12 +33,18 @@
this.currentToolBehavior = null;
this.primaryColor = Constants.DEFAULT_PEN_COLOR;
this.secondaryColor = Constants.TRANSPARENT_COLOR;
};
ns.DrawingController.prototype.init = function () {
this.renderer.render(this.framesheet.getCurrentFrame());
this.overlayRenderer.render(this.overlayFrame);
this.initMouseBehavior();
$.subscribe(Events.TOOL_SELECTED, $.proxy(function(evt, toolBehavior) {
console.log("Tool selected: ", toolBehavior);
this.currentToolBehavior = toolBehavior;
this.overlayFrame.clear();
}, this));
/**
@ -179,7 +183,7 @@
$.publish(Events.TOOL_RELEASED);
}
},
};
/**
* @private
@ -192,7 +196,7 @@
evtInfo.button = Constants.RIGHT_BUTTON;
}
return evtInfo;
},
};
/**
* @private

View File

@ -7,7 +7,9 @@
this.dpi = this.calculateDPI_();
this.redrawFlag = true;
};
ns.PreviewFilmController.prototype.init = function() {
$.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this));
$.subscribe(Events.FRAMESHEET_RESET, this.flagForRedraw_.bind(this));
$.subscribe(Events.FRAMESHEET_RESET, this.refreshDPI_.bind(this));
@ -16,8 +18,6 @@
this.updateScrollerOverflows();
};
ns.PreviewFilmController.prototype.init = function() {};
ns.PreviewFilmController.prototype.addFrame = function () {
this.framesheet.addEmptyFrame();
this.framesheet.setCurrentFrameIndex(this.framesheet.getFrameCount() - 1);
@ -155,7 +155,7 @@
// 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);
currentFrameRenderer.render(currentFrame);
previewTileRoot.appendChild(canvasContainer);
@ -207,11 +207,14 @@
* Calculate the preview DPI depending on the framesheet size
*/
ns.PreviewFilmController.prototype.calculateDPI_ = function () {
var previewSize = 120,
framePixelHeight = this.framesheet.getCurrentFrame().getHeight(),
framePixelWidth = this.framesheet.getCurrentFrame().getWidth();
// TODO (julz) : should have a utility to get a Size from framesheet easily (what about empty framesheets though ?)
var curFrame = this.framesheet.getCurrentFrame(),
frameHeight = curFrame.getHeight(),
frameWidth = curFrame.getWidth(),
maxFrameDim = Math.max(frameWidth, frameHeight);
return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth);
var previewHeight = Constants.PREVIEW_FILM_SIZE * frameHeight / maxFrameDim;
var previewWidth = Constants.PREVIEW_FILM_SIZE * frameWidth / maxFrameDim;
return pskl.PixelUtils.calculateDPI(previewHeight, previewWidth, frameHeight, frameWidth) || 1;
};
})();

View File

@ -22,6 +22,19 @@
this.previousSelectedTool = this.toolInstances.simplePen;
};
/**
* @public
*/
ns.ToolController.prototype.init = function() {
this.createToolMarkup_();
// Initialize tool:
// Set SimplePen as default selected tool:
this.selectTool_(this.toolInstances.simplePen);
// Activate listener on tool panel:
$("#tool-section").click($.proxy(this.onToolIconClicked_, this));
};
/**
* @private
*/
@ -53,16 +66,25 @@
var clickedTool = target.closest(".tool-icon");
if(clickedTool.length) {
for(var tool in this.toolInstances) {
if (this.toolInstances[tool].toolId == clickedTool.data().toolId) {
this.selectTool_(this.toolInstances[tool]);
var toolId = clickedTool.data().toolId;
var tool = this.getToolById_(toolId);
if (tool) {
this.selectTool_(tool);
// Show tool as selected:
$('#tool-section .tool-icon.selected').removeClass('selected');
clickedTool.addClass('selected');
}
}
};
ns.ToolController.prototype.getToolById_ = function (toolId) {
for(var key in this.toolInstances) {
if (this.toolInstances[key].toolId == toolId) {
return this.toolInstances[key];
}
}
return null;
};
/**
@ -82,18 +104,4 @@
}
$('#tools-container').html(toolMarkup);
};
/**
* @public
*/
ns.ToolController.prototype.init = function() {
this.createToolMarkup_();
// Initialize tool:
// Set SimplePen as default selected tool:
this.selectTool_(this.toolInstances.simplePen);
// Activate listener on tool panel:
$("#tool-section").click($.proxy(this.onToolIconClicked_, this));
};
})();

View File

@ -63,7 +63,6 @@
*/
ns.BaseSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
if(this.mode == "select") {
this.onSelectEnd_(col, row, color, frame, overlay);
} else if(this.mode == "moveSelection") {
@ -90,6 +89,17 @@
}
};
/**
* For each pixel in the selection draw it in white transparent on the tool overlay
* @protected
*/
ns.BaseSelect.prototype.drawSelectionOnOverlay_ = function (selection, overlay) {
var pixels = selection.pixels;
for(var i=0, l=pixels.length; i<l; i++) {
overlay.setPixel(pixels[i].col, pixels[i].row, Constants.SELECTION_TRANSPARENT_COLOR);
}
};
/**
* Move the overlay frame filled with semi-transparent pixels that represent the selection.
* @private
@ -125,6 +135,7 @@
// we clone it to have a reference for the later shifting process.
this.overlayFrameReference = overlay.clone();
};
/** @private */
ns.BaseSelect.prototype.onSelectionDrag_ = function (col, row, color, frame, overlay) {
var deltaCol = col - this.lastCol;
@ -141,10 +152,9 @@
this.lastCol = col;
this.lastRow = row;
};
/** @private */
ns.BaseSelect.prototype.onSelectionDragEnd_ = function (col, row, color, frame, overlay) {
this.onSelectionDrag_(col, row, color, frame, overlay);
};
})();

View File

@ -38,6 +38,7 @@
var selection = new pskl.selection.RectangularSelection(
this.startCol, this.startRow, col, row);
$.publish(Events.SELECTION_CREATED, [selection]);
this.drawSelectionOnOverlay_(selection, overlay);
}
};

View File

@ -15,7 +15,6 @@
pskl.utils.inherit(ns.ShapeSelect, ns.BaseSelect);
/**
* For the shape select tool, you just need to click one time to create a selection.
* So we jsut need to implement onSelectStart_ (no need for onSelect_ & onSelectEnd_)
@ -24,11 +23,14 @@
ns.ShapeSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {
// Clean previous selection:
$.publish(Events.SELECTION_DISMISSED);
overlay.clear();
// From the pixel cliked, get shape using an algorithm similar to the paintbucket one:
var pixels = pskl.PixelUtils.getSimilarConnectedPixelsFromFrame(frame, col, row);
var selection = new pskl.selection.ShapeSelection(pixels);
$.publish(Events.SELECTION_CREATED, [selection]);
this.drawSelectionOnOverlay_(selection, overlay);
};
})();

View File

@ -16,7 +16,7 @@
//import flash.net.URLRequest;
//import flash.net.navigateToURL;
GIFEncoder = function()
window.GIFEncoder = function()
{
for(var i = 0, chr = {}; i < 256; i++)
chr[i] = String.fromCharCode(i);

View File

@ -1,4 +1,4 @@
function encode64(input) {
window.encode64 = function(input) {
var output = "", i = 0, l = input.length,
key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
chr1, chr2, chr3, enc1, enc2, enc3, enc4;
@ -15,4 +15,4 @@ function encode64(input) {
output = output + key.charAt(enc1) + key.charAt(enc2) + key.charAt(enc3) + key.charAt(enc4);
}
return output;
}
};

View File

@ -17,6 +17,7 @@
var frameSize = this.readSizeFromURL_();
frameSheet = new pskl.model.FrameSheet(frameSize.height, frameSize.width);
frameSheet.addEmptyFrame();
frameSheet.setCurrentFrameIndex(0);
/**
* True when piskel is running in static mode (no back end needed).
@ -25,26 +26,20 @@
this.isStaticVersion = !pskl.appEngineToken_;
this.drawingController = new pskl.controller.DrawingController(frameSheet, $('#drawing-canvas-container'));
this.drawingController.init();
this.animationController = new pskl.controller.AnimatedPreviewController(frameSheet, $('#preview-canvas-container'));
this.previewsController = new pskl.controller.PreviewFilmController(frameSheet, $('#preview-list'));
this.settingsController = new pskl.controller.SettingsController();
// To catch the current active frame, the selection manager have to be initialized before
// the 'frameSheet.setCurrentFrameIndex(0);' line below.
// TODO(vincz): Slice each constructor to have:
// - an event(s) listening init
// - an event(s) triggering init
// All listeners will be hook in a first step, then all event triggering inits will be called
// in a second batch.
this.selectionManager = new pskl.selection.SelectionManager(frameSheet, this.drawingController.overlayFrame);
// DO NOT MOVE THIS LINE (see comment above)
frameSheet.setCurrentFrameIndex(0);
this.animationController.init();
this.previewsController = new pskl.controller.PreviewFilmController(frameSheet, $('#preview-list'));
this.previewsController.init();
this.settingsController = new pskl.controller.SettingsController();
this.settingsController.init();
this.selectionManager = new pskl.selection.SelectionManager(frameSheet);
this.selectionManager.init();
this.historyService = new pskl.service.HistoryService(frameSheet);
this.historyService.init();
@ -57,24 +52,11 @@
this.localStorageService = new pskl.service.LocalStorageService(frameSheet);
this.localStorageService.init();
if (this.isStaticVersion) {
var framesheetId = this.readFramesheetIdFromURL_();
if (framesheetId) {
$.publish(Events.SHOW_NOTIFICATION, [{
"content" : "Loading animation with id : [" + framesheetId + "]"
}]);
this.loadFramesheetFromService(framesheetId);
} else {
this.finishInit();
this.localStorageService.displayRestoreNotification();
}
} else {
if (pskl.framesheetData_ && pskl.framesheetData_.content) {
frameSheet.load(pskl.framesheetData_.content);
pskl.app.animationController.setFPS(pskl.framesheetData_.fps);
}
this.finishInit();
}
this.toolController = new pskl.controller.ToolController();
this.toolController.init();
this.paletteController = new pskl.controller.PaletteController();
this.paletteController.init(frameSheet);
var drawingLoop = new pskl.rendering.DrawingLoop();
drawingLoop.addCallback(this.render, this);
@ -84,6 +66,30 @@
$('body').tooltip({
selector: '[rel=tooltip]'
});
/**
* True when piskel is running in static mode (no back end needed).
* When started from APP Engine, appEngineToken_ (Boolean) should be set on window.pskl
*/
this.isStaticVersion = !pskl.appEngineToken_;
if (this.isStaticVersion) {
var framesheetId = this.readFramesheetIdFromURL_();
if (framesheetId) {
$.publish(Events.SHOW_NOTIFICATION, [{
"content" : "Loading animation with id : [" + framesheetId + "]"
}]);
this.loadFramesheetFromService(framesheetId);
} else {
this.localStorageService.displayRestoreNotification();
}
} else {
if (pskl.framesheetData_ && pskl.framesheetData_.content) {
frameSheet.load(pskl.framesheetData_.content);
pskl.app.animationController.setFPS(pskl.framesheetData_.fps);
}
}
},
render : function (delta) {
@ -92,14 +98,6 @@
this.previewsController.render(delta);
},
finishInit : function () {
var toolController = new pskl.controller.ToolController();
toolController.init();
var paletteController = new pskl.controller.PaletteController();
paletteController.init(frameSheet);
},
readSizeFromURL_ : function () {
var sizeParam = this.readUrlParameter_("size"),
size;
@ -130,7 +128,7 @@
for (i = 0; i < params.length; i++) {
val = params[i].split("=");
if (val[0] == paramName) {
return unescape(val[1]);
return window.unescape(val[1]);
}
}
return "";
@ -146,12 +144,10 @@
frameSheet.load(res.framesheet);
pskl.app.animationController.setFPS(res.fps);
$.publish(Events.HIDE_NOTIFICATION);
pskl.app.finishInit();
};
xhr.onerror = function () {
$.publish(Events.HIDE_NOTIFICATION);
pskl.app.finishInit();
};
xhr.send();

View File

@ -29,11 +29,6 @@
$.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this));
};
ns.FrameRenderer.prototype.init = function (frame) {
this.render(frame);
this.lastRenderedFrame = frame;
};
ns.FrameRenderer.prototype.updateDPI = function (newDPI) {
this.dpi = newDPI;
this.canvasConfigDirty = true;

View File

@ -16,7 +16,7 @@
};
ns.SpritesheetRenderer.prototype.renderAsImageDataAnimatedGIF = function (fps) {
var encoder = new GIFEncoder(), dpi = 10;
var encoder = new window.GIFEncoder(), dpi = 10;
encoder.setRepeat(0);
encoder.setDelay(1000/fps);
@ -29,7 +29,7 @@
}
encoder.finish();
var imageData = 'data:image/gif;base64,' + encode64(encoder.stream().getData());
var imageData = 'data:image/gif;base64,' + window.encode64(encoder.stream().getData());
return imageData;
};

View File

@ -1,14 +1,14 @@
(function () {
var ns = $.namespace("pskl.selection");
ns.SelectionManager = function (framesheet, overlayFrame) {
ns.SelectionManager = function (framesheet) {
this.framesheet = framesheet;
this.overlayFrame = overlayFrame;
this.currentSelection = null;
};
ns.SelectionManager.prototype.init = function () {
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
@ -23,11 +23,10 @@
/**
* @private
*/
ns.SelectionManager.prototype.cleanSelection_ = function(selection) {
ns.SelectionManager.prototype.cleanSelection_ = function() {
if(this.currentSelection) {
this.currentSelection.reset();
}
this.overlayFrame.clear();
};
/**
@ -106,12 +105,7 @@
ns.SelectionManager.prototype.onSelectionCreated_ = function(evt, selection) {
if(selection) {
this.currentSelection = selection;
var pixels = selection.pixels;
for(var i=0, l=pixels.length; i<l; i++) {
this.overlayFrame.setPixel(pixels[i].col, pixels[i].row, Constants.SELECTION_TRANSPARENT_COLOR);
}
}
else {
} else {
throw "No selection set in SelectionManager";
}
};

View File

@ -41,8 +41,10 @@
*/
getOrderedRectangleCoordinates : function (x0, y0, x1, y1) {
return {
x0 : Math.min(x0, x1), y0 : Math.min(y0, y1),
x1 : Math.max(x0, x1), y1 : Math.max(y0, y1),
x0 : Math.min(x0, x1),
y0 : Math.min(y0, y1),
x1 : Math.max(x0, x1),
y1 : Math.max(y0, y1),
};
},

View File

@ -16,7 +16,8 @@
"grunt-contrib-connect": "0.3.0",
"grunt-contrib-jshint": "0.5.4",
"grunt-contrib-uglify": "0.2.2",
"grunt-contrib-concat": "0.1.2",
"grunt-ghost": "1.0.12",
"grunt-contrib-concat": "0.1.2"
"grunt-leading-indent" : "0.1.0"
}
}