mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Dev environment:force indentation to 2 spaces. Added new grunt module, grunt-leading-indent to check space consistency, and modified jshint options to enforce 2 spaces
This commit is contained in:
95
Gruntfile.js
95
Gruntfile.js
@ -5,56 +5,69 @@
|
|||||||
* - run a grunt target defined in Gruntfiles.js, ex: 'grunt lint'
|
* - run a grunt target defined in Gruntfiles.js, ex: 'grunt lint'
|
||||||
*
|
*
|
||||||
* Note: The 'ghost' grunt task have special deps on CasperJS and phantomjs.
|
* Note: The 'ghost' grunt task have special deps on CasperJS and phantomjs.
|
||||||
* For now, It's configured to run only on TravisCI where these deps are
|
* For now, It's configured to run only on TravisCI where these deps are
|
||||||
* correctly defined.
|
* correctly defined.
|
||||||
* If you run this task locally, it may require some env set up first.
|
* If you run this task locally, it may require some env set up first.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
jshint: {
|
jshint: {
|
||||||
/*options: {
|
/*options: {
|
||||||
"evil": true,
|
"evil": true,
|
||||||
"asi": true,
|
"asi": true,
|
||||||
"smarttabs": true,
|
"smarttabs": true,
|
||||||
"eqnull": true
|
"eqnull": true
|
||||||
},*/
|
},*/
|
||||||
files: [
|
options: {
|
||||||
'Gruntfile.js',
|
indent:2
|
||||||
'package.json',
|
},
|
||||||
'js/**/*.js',
|
files: [
|
||||||
'!js/lib/**/*.js' // Exclude lib folder (note the leading !)
|
'Gruntfile.js',
|
||||||
]
|
'package.json',
|
||||||
},
|
'js/**/*.js',
|
||||||
connect: {
|
'!js/lib/**/*.js' // Exclude lib folder (note the leading !)
|
||||||
www: {
|
]
|
||||||
options: {
|
},
|
||||||
base: '.',
|
connect: {
|
||||||
port: 4545
|
www: {
|
||||||
}
|
options: {
|
||||||
}
|
base: '.',
|
||||||
},
|
port: 4545
|
||||||
ghost: {
|
}
|
||||||
dist: {
|
}
|
||||||
filesSrc: ['tests/integration/casperjs/*_test.js'],
|
},
|
||||||
options: {
|
ghost: {
|
||||||
args: {
|
dist: {
|
||||||
baseUrl: 'http://localhost:' +
|
filesSrc: ['tests/integration/casperjs/*_test.js'],
|
||||||
'<%= connect.www.options.port %>/'
|
options: {
|
||||||
},
|
args: {
|
||||||
direct: false,
|
baseUrl: 'http://localhost:' + '<%= connect.www.options.port %>/'
|
||||||
logLevel: 'error',
|
},
|
||||||
printCommand: false,
|
direct: false,
|
||||||
printFilePaths: true
|
logLevel: 'error',
|
||||||
}
|
printCommand: false,
|
||||||
}
|
printFilePaths: true
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
grunt.config.set('leadingIndent.indentation', 'spaces');
|
||||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
grunt.config.set('leadingIndent.jsFiles', {
|
||||||
grunt.loadNpmTasks('grunt-ghost');
|
src: ['js/**/*.js','!js/lib/**/*.js']
|
||||||
|
});
|
||||||
|
grunt.config.set('leadingIndent.cssFiles', {
|
||||||
|
src: ['css/**/*.css']
|
||||||
|
});
|
||||||
|
|
||||||
grunt.registerTask('lint', ['jshint']);
|
|
||||||
grunt.registerTask('test', ['jshint', 'connect', 'ghost']);
|
grunt.loadNpmTasks('grunt-leading-indent');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
grunt.loadNpmTasks('grunt-ghost');
|
||||||
|
|
||||||
|
grunt.registerTask('check-indent', ['leadingIndent:jsFiles', 'leadingIndent:cssFiles']);
|
||||||
|
grunt.registerTask('lint', ['jshint']);
|
||||||
|
grunt.registerTask('test', ['leadingIndent:jsFiles', 'leadingIndent:cssFiles', 'jshint', 'connect', 'ghost']);
|
||||||
};
|
};
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
// TODO(grosbouddha): put under pskl namespace.
|
// TODO(grosbouddha): put under pskl namespace.
|
||||||
var Constants = {
|
var Constants = {
|
||||||
DEFAULT_SIZE : {
|
DEFAULT_SIZE : {
|
||||||
height : 32,
|
height : 32,
|
||||||
width : 32
|
width : 32
|
||||||
},
|
},
|
||||||
|
|
||||||
MAX_HEIGHT : 128,
|
MAX_HEIGHT : 128,
|
||||||
MAX_WIDTH : 128,
|
MAX_WIDTH : 128,
|
||||||
|
|
||||||
DEFAULT_PEN_COLOR : '#000000',
|
DEFAULT_PEN_COLOR : '#000000',
|
||||||
TRANSPARENT_COLOR : 'TRANSPARENT',
|
TRANSPARENT_COLOR : 'TRANSPARENT',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fake semi-transparent color used to highlight transparent
|
* Fake semi-transparent color used to highlight transparent
|
||||||
* strokes and rectangles:
|
* strokes and rectangles:
|
||||||
*/
|
*/
|
||||||
SELECTION_TRANSPARENT_COLOR: 'rgba(255, 255, 255, 0.6)',
|
SELECTION_TRANSPARENT_COLOR: 'rgba(255, 255, 255, 0.6)',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a tool is hovering the drawing canvas, we highlight the eventual
|
* When a tool is hovering the drawing canvas, we highlight the eventual
|
||||||
* pixel target with this color:
|
* pixel target with this color:
|
||||||
*/
|
*/
|
||||||
TOOL_TARGET_HIGHLIGHT_COLOR: 'rgba(255, 255, 255, 0.2)',
|
TOOL_TARGET_HIGHLIGHT_COLOR: 'rgba(255, 255, 255, 0.2)',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default entry point for piskel web service:
|
* Default entry point for piskel web service:
|
||||||
*/
|
*/
|
||||||
PISKEL_SERVICE_URL: 'http://3.piskel-app.appspot.com',
|
PISKEL_SERVICE_URL: 'http://3.piskel-app.appspot.com',
|
||||||
|
|
||||||
GRID_STROKE_WIDTH: 1,
|
GRID_STROKE_WIDTH: 1,
|
||||||
GRID_STROKE_COLOR: "lightgray",
|
GRID_STROKE_COLOR: "lightgray",
|
||||||
|
|
||||||
LEFT_BUTTON : "left_button_1",
|
LEFT_BUTTON : "left_button_1",
|
||||||
RIGHT_BUTTON : "right_button_2"
|
RIGHT_BUTTON : "right_button_2"
|
||||||
};
|
};
|
104
js/Events.js
104
js/Events.js
@ -1,64 +1,64 @@
|
|||||||
// TODO(grosbouddha): put under pskl namespace.
|
// TODO(grosbouddha): put under pskl namespace.
|
||||||
Events = {
|
Events = {
|
||||||
|
|
||||||
TOOL_SELECTED : "TOOL_SELECTED",
|
TOOL_SELECTED : "TOOL_SELECTED",
|
||||||
TOOL_RELEASED : "TOOL_RELEASED",
|
TOOL_RELEASED : "TOOL_RELEASED",
|
||||||
PRIMARY_COLOR_SELECTED: "PRIMARY_COLOR_SELECTED",
|
PRIMARY_COLOR_SELECTED: "PRIMARY_COLOR_SELECTED",
|
||||||
PRIMARY_COLOR_UPDATED: "PRIMARY_COLOR_UPDATED",
|
PRIMARY_COLOR_UPDATED: "PRIMARY_COLOR_UPDATED",
|
||||||
SECONDARY_COLOR_SELECTED: "SECONDARY_COLOR_SELECTED",
|
SECONDARY_COLOR_SELECTED: "SECONDARY_COLOR_SELECTED",
|
||||||
SECONDARY_COLOR_UPDATED: "SECONDARY_COLOR_UPDATED",
|
SECONDARY_COLOR_UPDATED: "SECONDARY_COLOR_UPDATED",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When this event is emitted, a request is sent to the localstorage
|
* When this event is emitted, a request is sent to the localstorage
|
||||||
* Service to save the current framesheet. The storage service
|
* Service to save the current framesheet. The storage service
|
||||||
* may not immediately store data (internal throttling of requests).
|
* may not immediately store data (internal throttling of requests).
|
||||||
*/
|
*/
|
||||||
LOCALSTORAGE_REQUEST: "LOCALSTORAGE_REQUEST",
|
LOCALSTORAGE_REQUEST: "LOCALSTORAGE_REQUEST",
|
||||||
|
|
||||||
CANVAS_RIGHT_CLICKED: "CANVAS_RIGHT_CLICKED",
|
CANVAS_RIGHT_CLICKED: "CANVAS_RIGHT_CLICKED",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event to request a refresh of the display.
|
* Event to request a refresh of the display.
|
||||||
* A bit overkill but, it's just workaround in our current drawing system.
|
* A bit overkill but, it's just workaround in our current drawing system.
|
||||||
* TODO: Remove or rework when redraw system is refactored.
|
* TODO: Remove or rework when redraw system is refactored.
|
||||||
*/
|
*/
|
||||||
REFRESH: "REFRESH",
|
REFRESH: "REFRESH",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary event to bind the redraw of right preview film to the canvas.
|
* Temporary event to bind the redraw of right preview film to the canvas.
|
||||||
* This redraw should be driven by model updates.
|
* This redraw should be driven by model updates.
|
||||||
* TODO(vincz): Remove.
|
* TODO(vincz): Remove.
|
||||||
*/
|
*/
|
||||||
REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM",
|
REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired each time a user setting change.
|
* Fired each time a user setting change.
|
||||||
* The payload will be:
|
* The payload will be:
|
||||||
* 1st argument: Name of the settings
|
* 1st argument: Name of the settings
|
||||||
* 2nd argument: New value
|
* 2nd argument: New value
|
||||||
*/
|
*/
|
||||||
USER_SETTINGS_CHANGED: "USER_SETTINGS_CHANGED",
|
USER_SETTINGS_CHANGED: "USER_SETTINGS_CHANGED",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The framesheet was reseted and is now probably drastically different.
|
* The framesheet was reseted and is now probably drastically different.
|
||||||
* Number of frames, content of frames, color used for the palette may have changed.
|
* Number of frames, content of frames, color used for the palette may have changed.
|
||||||
*/
|
*/
|
||||||
FRAMESHEET_RESET: "FRAMESHEET_RESET",
|
FRAMESHEET_RESET: "FRAMESHEET_RESET",
|
||||||
|
|
||||||
FRAME_SIZE_CHANGED : "FRAME_SIZE_CHANGED",
|
FRAME_SIZE_CHANGED : "FRAME_SIZE_CHANGED",
|
||||||
|
|
||||||
CURRENT_FRAME_SET: "CURRENT_FRAME_SET",
|
CURRENT_FRAME_SET: "CURRENT_FRAME_SET",
|
||||||
|
|
||||||
SELECTION_CREATED: "SELECTION_CREATED",
|
SELECTION_CREATED: "SELECTION_CREATED",
|
||||||
SELECTION_MOVE_REQUEST: "SELECTION_MOVE_REQUEST",
|
SELECTION_MOVE_REQUEST: "SELECTION_MOVE_REQUEST",
|
||||||
SELECTION_DISMISSED: "SELECTION_DISMISSED",
|
SELECTION_DISMISSED: "SELECTION_DISMISSED",
|
||||||
|
|
||||||
SHOW_NOTIFICATION: "SHOW_NOTIFICATION",
|
SHOW_NOTIFICATION: "SHOW_NOTIFICATION",
|
||||||
HIDE_NOTIFICATION: "HIDE_NOTIFICATION",
|
HIDE_NOTIFICATION: "HIDE_NOTIFICATION",
|
||||||
|
|
||||||
UNDO: "UNDO",
|
UNDO: "UNDO",
|
||||||
REDO: "REDO",
|
REDO: "REDO",
|
||||||
CUT: "CUT",
|
CUT: "CUT",
|
||||||
COPY: "COPY",
|
COPY: "COPY",
|
||||||
PASTE: "PASTE"
|
PASTE: "PASTE"
|
||||||
};
|
};
|
@ -1,67 +1,67 @@
|
|||||||
(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.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
this.elapsedTime = 0;
|
this.elapsedTime = 0;
|
||||||
|
this.currentIndex = 0;
|
||||||
|
|
||||||
|
this.fps = parseInt($("#preview-fps")[0].value, 10);
|
||||||
|
|
||||||
|
var renderingOptions = {
|
||||||
|
"dpi": this.calculateDPI_()
|
||||||
|
};
|
||||||
|
this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions);
|
||||||
|
|
||||||
|
$.subscribe(Events.FRAME_SIZE_CHANGED, this.updateDPI_.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.AnimatedPreviewController.prototype.init = function () {
|
||||||
|
// the oninput event won't work on IE10 unfortunately, but at least will provide a
|
||||||
|
// consistent behavior across all other browsers that support the input type range
|
||||||
|
// see https://bugzilla.mozilla.org/show_bug.cgi?id=853670
|
||||||
|
$("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.AnimatedPreviewController.prototype.onFPSSliderChange = function (evt) {
|
||||||
|
this.setFPS(parseInt($("#preview-fps")[0].value, 10));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.AnimatedPreviewController.prototype.setFPS = function (fps) {
|
||||||
|
this.fps = fps;
|
||||||
|
$("#preview-fps").val(this.fps);
|
||||||
|
$("#display-fps").html(this.fps + " FPS");
|
||||||
|
};
|
||||||
|
|
||||||
|
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.currentIndex = 0;
|
||||||
|
this.elapsedTime = 0;
|
||||||
|
}
|
||||||
|
this.renderer.render(this.framesheet.getFrameByIndex(this.currentIndex));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.fps = parseInt($("#preview-fps")[0].value, 10);
|
/**
|
||||||
|
* Calculate the preview DPI depending on the framesheet size
|
||||||
var renderingOptions = {
|
*/
|
||||||
"dpi": this.calculateDPI_()
|
ns.AnimatedPreviewController.prototype.calculateDPI_ = function () {
|
||||||
};
|
var previewSize = 200,
|
||||||
this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions);
|
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 ?)
|
||||||
|
|
||||||
|
//return pskl.PixelUtils.calculateDPIForContainer($(".preview-container"), framePixelHeight, framePixelWidth);
|
||||||
|
return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth);
|
||||||
|
};
|
||||||
|
|
||||||
$.subscribe(Events.FRAME_SIZE_CHANGED, this.updateDPI_.bind(this));
|
ns.AnimatedPreviewController.prototype.updateDPI_ = function () {
|
||||||
};
|
this.dpi = this.calculateDPI_();
|
||||||
|
this.renderer.updateDPI(this.dpi);
|
||||||
ns.AnimatedPreviewController.prototype.init = function () {
|
};
|
||||||
// the oninput event won't work on IE10 unfortunately, but at least will provide a
|
|
||||||
// consistent behavior across all other browsers that support the input type range
|
|
||||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=853670
|
|
||||||
$("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AnimatedPreviewController.prototype.onFPSSliderChange = function (evt) {
|
|
||||||
this.setFPS(parseInt($("#preview-fps")[0].value, 10));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AnimatedPreviewController.prototype.setFPS = function (fps) {
|
|
||||||
this.fps = fps;
|
|
||||||
$("#preview-fps").val(this.fps);
|
|
||||||
$("#display-fps").html(this.fps + " FPS");
|
|
||||||
};
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the preview DPI depending on the framesheet size
|
|
||||||
*/
|
|
||||||
ns.AnimatedPreviewController.prototype.calculateDPI_ = function () {
|
|
||||||
var previewSize = 200,
|
|
||||||
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 ?)
|
|
||||||
|
|
||||||
//return pskl.PixelUtils.calculateDPIForContainer($(".preview-container"), framePixelHeight, framePixelWidth);
|
|
||||||
return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AnimatedPreviewController.prototype.updateDPI_ = function () {
|
|
||||||
this.dpi = this.calculateDPI_();
|
|
||||||
this.renderer.updateDPI(this.dpi);
|
|
||||||
};
|
|
||||||
})();
|
})();
|
@ -68,21 +68,21 @@
|
|||||||
|
|
||||||
ns.DrawingController.prototype.initMouseBehavior = function() {
|
ns.DrawingController.prototype.initMouseBehavior = function() {
|
||||||
var body = $('body');
|
var body = $('body');
|
||||||
this.container.mousedown($.proxy(this.onMousedown_, this));
|
this.container.mousedown($.proxy(this.onMousedown_, this));
|
||||||
this.container.mousemove($.proxy(this.onMousemove_, this));
|
this.container.mousemove($.proxy(this.onMousemove_, this));
|
||||||
body.mouseup($.proxy(this.onMouseup_, this));
|
body.mouseup($.proxy(this.onMouseup_, this));
|
||||||
|
|
||||||
// Deactivate right click:
|
// Deactivate right click:
|
||||||
body.contextmenu(this.onCanvasContextMenu_);
|
body.contextmenu(this.onCanvasContextMenu_);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ns.DrawingController.prototype.startDPIUpdateTimer_ = function () {
|
ns.DrawingController.prototype.startDPIUpdateTimer_ = function () {
|
||||||
if (this.dpiUpdateTimer) {
|
if (this.dpiUpdateTimer) {
|
||||||
window.clearInterval(this.dpiUpdateTimer);
|
window.clearInterval(this.dpiUpdateTimer);
|
||||||
}
|
}
|
||||||
this.dpiUpdateTimer = window.setTimeout($.proxy(this.updateDPI_, this), 200);
|
this.dpiUpdateTimer = window.setTimeout($.proxy(this.updateDPI_, this), 200);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,144 +98,144 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.DrawingController.prototype.onMousedown_ = function (event) {
|
ns.DrawingController.prototype.onMousedown_ = function (event) {
|
||||||
this.isClicked = true;
|
this.isClicked = true;
|
||||||
|
|
||||||
if(event.button == 2) { // right click
|
if(event.button == 2) { // right click
|
||||||
this.isRightClicked = true;
|
this.isRightClicked = true;
|
||||||
$.publish(Events.CANVAS_RIGHT_CLICKED);
|
$.publish(Events.CANVAS_RIGHT_CLICKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
var coords = this.getSpriteCoordinates(event);
|
var coords = this.getSpriteCoordinates(event);
|
||||||
|
|
||||||
|
this.currentToolBehavior.applyToolAt(
|
||||||
|
coords.col, coords.row,
|
||||||
|
this.getCurrentColor_(),
|
||||||
|
this.framesheet.getCurrentFrame(),
|
||||||
|
this.overlayFrame,
|
||||||
|
this.wrapEvtInfo_(event)
|
||||||
|
);
|
||||||
|
|
||||||
this.currentToolBehavior.applyToolAt(
|
$.publish(Events.LOCALSTORAGE_REQUEST);
|
||||||
coords.col, coords.row,
|
};
|
||||||
this.getCurrentColor_(),
|
|
||||||
this.framesheet.getCurrentFrame(),
|
|
||||||
this.overlayFrame,
|
|
||||||
this.wrapEvtInfo_(event)
|
|
||||||
);
|
|
||||||
|
|
||||||
$.publish(Events.LOCALSTORAGE_REQUEST);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.DrawingController.prototype.onMousemove_ = function (event) {
|
ns.DrawingController.prototype.onMousemove_ = function (event) {
|
||||||
var currentTime = new Date().getTime();
|
var currentTime = new Date().getTime();
|
||||||
// Throttling of the mousemove event:
|
// Throttling of the mousemove event:
|
||||||
if ((currentTime - this.previousMousemoveTime) > 40 ) {
|
if ((currentTime - this.previousMousemoveTime) > 40 ) {
|
||||||
var coords = this.getSpriteCoordinates(event);
|
var coords = this.getSpriteCoordinates(event);
|
||||||
if (this.isClicked) {
|
if (this.isClicked) {
|
||||||
|
|
||||||
this.currentToolBehavior.moveToolAt(
|
this.currentToolBehavior.moveToolAt(
|
||||||
coords.col, coords.row,
|
|
||||||
this.getCurrentColor_(),
|
|
||||||
this.framesheet.getCurrentFrame(),
|
|
||||||
this.overlayFrame,
|
|
||||||
this.wrapEvtInfo_(event)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
|
|
||||||
this.currentToolBehavior.moveUnactiveToolAt(
|
|
||||||
coords.col, coords.row,
|
|
||||||
this.getCurrentColor_(),
|
|
||||||
this.framesheet.getCurrentFrame(),
|
|
||||||
this.overlayFrame,
|
|
||||||
this.wrapEvtInfo_(event)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
|
|
||||||
this.isClicked = false;
|
|
||||||
this.isRightClicked = false;
|
|
||||||
|
|
||||||
var coords = this.getSpriteCoordinates(event);
|
|
||||||
//console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row);
|
|
||||||
this.currentToolBehavior.releaseToolAt(
|
|
||||||
coords.col, coords.row,
|
coords.col, coords.row,
|
||||||
this.getCurrentColor_(),
|
this.getCurrentColor_(),
|
||||||
this.framesheet.getCurrentFrame(),
|
this.framesheet.getCurrentFrame(),
|
||||||
this.overlayFrame,
|
this.overlayFrame,
|
||||||
this.wrapEvtInfo_(event)
|
this.wrapEvtInfo_(event)
|
||||||
);
|
);
|
||||||
|
|
||||||
$.publish(Events.TOOL_RELEASED);
|
// 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);
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.DrawingController.prototype.wrapEvtInfo_ = function (event) {
|
|
||||||
var evtInfo = {};
|
|
||||||
if (event.button === 0) {
|
|
||||||
evtInfo.button = Constants.LEFT_BUTTON;
|
|
||||||
} else if (event.button == 2) {
|
|
||||||
evtInfo.button = Constants.RIGHT_BUTTON;
|
|
||||||
}
|
|
||||||
return evtInfo;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.getSpriteCoordinates = function(event) {
|
|
||||||
var coords = this.getRelativeCoordinates(event.clientX, event.clientY);
|
|
||||||
return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.DrawingController.prototype.getCurrentColor_ = function () {
|
|
||||||
if(this.isRightClicked) {
|
|
||||||
return this.secondaryColor;
|
|
||||||
} else {
|
} else {
|
||||||
return this.primaryColor;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
this.currentToolBehavior.moveUnactiveToolAt(
|
||||||
* @private
|
coords.col, coords.row,
|
||||||
*/
|
this.getCurrentColor_(),
|
||||||
ns.DrawingController.prototype.onCanvasContextMenu_ = function (event) {
|
this.framesheet.getCurrentFrame(),
|
||||||
if ($(event.target).closest('#drawing-canvas-container').length) {
|
this.overlayFrame,
|
||||||
// Deactivate right click on drawing canvas only.
|
this.wrapEvtInfo_(event)
|
||||||
event.preventDefault();
|
);
|
||||||
event.stopPropagation();
|
}
|
||||||
event.cancelBubble = true;
|
this.previousMousemoveTime = currentTime;
|
||||||
return false;
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
||||||
|
|
||||||
|
this.isClicked = false;
|
||||||
|
this.isRightClicked = false;
|
||||||
|
|
||||||
|
var coords = this.getSpriteCoordinates(event);
|
||||||
|
//console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row);
|
||||||
|
this.currentToolBehavior.releaseToolAt(
|
||||||
|
coords.col, coords.row,
|
||||||
|
this.getCurrentColor_(),
|
||||||
|
this.framesheet.getCurrentFrame(),
|
||||||
|
this.overlayFrame,
|
||||||
|
this.wrapEvtInfo_(event)
|
||||||
|
);
|
||||||
|
|
||||||
|
$.publish(Events.TOOL_RELEASED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.DrawingController.prototype.wrapEvtInfo_ = function (event) {
|
||||||
|
var evtInfo = {};
|
||||||
|
if (event.button === 0) {
|
||||||
|
evtInfo.button = Constants.LEFT_BUTTON;
|
||||||
|
} else if (event.button == 2) {
|
||||||
|
evtInfo.button = Constants.RIGHT_BUTTON;
|
||||||
|
}
|
||||||
|
return evtInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.getSpriteCoordinates = function(event) {
|
||||||
|
var coords = this.getRelativeCoordinates(event.clientX, event.clientY);
|
||||||
|
return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.DrawingController.prototype.getCurrentColor_ = function () {
|
||||||
|
if(this.isRightClicked) {
|
||||||
|
return this.secondaryColor;
|
||||||
|
} else {
|
||||||
|
return this.primaryColor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.DrawingController.prototype.onCanvasContextMenu_ = function (event) {
|
||||||
|
if ($(event.target).closest('#drawing-canvas-container').length) {
|
||||||
|
// Deactivate right click on drawing canvas only.
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
event.cancelBubble = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ns.DrawingController.prototype.render = function () {
|
ns.DrawingController.prototype.render = function () {
|
||||||
this.renderFrame();
|
this.renderFrame();
|
||||||
@ -271,11 +271,11 @@
|
|||||||
*/
|
*/
|
||||||
ns.DrawingController.prototype.calculateDPI_ = function() {
|
ns.DrawingController.prototype.calculateDPI_ = function() {
|
||||||
var availableViewportHeight = $('#main-wrapper').height(),
|
var availableViewportHeight = $('#main-wrapper').height(),
|
||||||
leftSectionWidth = $('.left-column').outerWidth(true),
|
leftSectionWidth = $('.left-column').outerWidth(true),
|
||||||
rightSectionWidth = $('.right-column').outerWidth(true),
|
rightSectionWidth = $('.right-column').outerWidth(true),
|
||||||
availableViewportWidth = $('#main-wrapper').width() - leftSectionWidth - rightSectionWidth,
|
availableViewportWidth = $('#main-wrapper').width() - leftSectionWidth - rightSectionWidth,
|
||||||
framePixelHeight = this.framesheet.getCurrentFrame().getHeight(),
|
framePixelHeight = this.framesheet.getCurrentFrame().getHeight(),
|
||||||
framePixelWidth = this.framesheet.getCurrentFrame().getWidth();
|
framePixelWidth = this.framesheet.getCurrentFrame().getWidth();
|
||||||
|
|
||||||
if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) {
|
if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) {
|
||||||
availableViewportWidth = availableViewportWidth - (framePixelWidth * Constants.GRID_STROKE_WIDTH);
|
availableViewportWidth = availableViewportWidth - (framePixelWidth * Constants.GRID_STROKE_WIDTH);
|
||||||
@ -299,7 +299,7 @@
|
|||||||
var currentFrameHeight = this.framesheet.getCurrentFrame().getHeight();
|
var currentFrameHeight = this.framesheet.getCurrentFrame().getHeight();
|
||||||
var canvasHeight = currentFrameHeight * dpi;
|
var canvasHeight = currentFrameHeight * dpi;
|
||||||
if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) {
|
if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) {
|
||||||
canvasHeight += Constants.GRID_STROKE_WIDTH * currentFrameHeight;
|
canvasHeight += Constants.GRID_STROKE_WIDTH * currentFrameHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - canvasHeight) / 2);
|
var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - canvasHeight) / 2);
|
||||||
|
@ -1,217 +1,217 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.controller");
|
var ns = $.namespace("pskl.controller");
|
||||||
ns.PreviewFilmController = function (framesheet, container, dpi) {
|
ns.PreviewFilmController = function (framesheet, container, dpi) {
|
||||||
|
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.dpi = this.calculateDPI_();
|
this.dpi = this.calculateDPI_();
|
||||||
|
|
||||||
this.redrawFlag = true;
|
this.redrawFlag = true;
|
||||||
|
|
||||||
$.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this));
|
$.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this));
|
||||||
$.subscribe(Events.FRAMESHEET_RESET, this.flagForRedraw_.bind(this));
|
$.subscribe(Events.FRAMESHEET_RESET, this.flagForRedraw_.bind(this));
|
||||||
$.subscribe(Events.FRAMESHEET_RESET, this.refreshDPI_.bind(this));
|
$.subscribe(Events.FRAMESHEET_RESET, this.refreshDPI_.bind(this));
|
||||||
|
|
||||||
$('#preview-list-scroller').scroll(this.updateScrollerOverflows.bind(this));
|
$('#preview-list-scroller').scroll(this.updateScrollerOverflows.bind(this));
|
||||||
this.updateScrollerOverflows();
|
this.updateScrollerOverflows();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.init = function() {};
|
ns.PreviewFilmController.prototype.init = function() {};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.addFrame = function () {
|
ns.PreviewFilmController.prototype.addFrame = function () {
|
||||||
this.framesheet.addEmptyFrame();
|
this.framesheet.addEmptyFrame();
|
||||||
this.framesheet.setCurrentFrameIndex(this.framesheet.getFrameCount() - 1);
|
this.framesheet.setCurrentFrameIndex(this.framesheet.getFrameCount() - 1);
|
||||||
this.updateScrollerOverflows();
|
this.updateScrollerOverflows();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.flagForRedraw_ = function () {
|
ns.PreviewFilmController.prototype.flagForRedraw_ = function () {
|
||||||
this.redrawFlag = true;
|
this.redrawFlag = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.refreshDPI_ = function () {
|
ns.PreviewFilmController.prototype.refreshDPI_ = function () {
|
||||||
this.dpi = this.calculateDPI_();
|
this.dpi = this.calculateDPI_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.render = function () {
|
ns.PreviewFilmController.prototype.render = function () {
|
||||||
if (this.redrawFlag) {
|
if (this.redrawFlag) {
|
||||||
// TODO(vincz): Full redraw on any drawing modification, optimize.
|
// TODO(vincz): Full redraw on any drawing modification, optimize.
|
||||||
this.createPreviews_();
|
this.createPreviews_();
|
||||||
this.redrawFlag = false;
|
this.redrawFlag = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.updateScrollerOverflows = function () {
|
ns.PreviewFilmController.prototype.updateScrollerOverflows = function () {
|
||||||
var scroller = $('#preview-list-scroller');
|
var scroller = $('#preview-list-scroller');
|
||||||
var scrollerHeight = scroller.height();
|
var scrollerHeight = scroller.height();
|
||||||
var scrollTop = scroller.scrollTop();
|
var scrollTop = scroller.scrollTop();
|
||||||
var scrollerContentHeight = $('#preview-list').height();
|
var scrollerContentHeight = $('#preview-list').height();
|
||||||
var treshold = $('.top-overflow').height();
|
var treshold = $('.top-overflow').height();
|
||||||
var overflowTop = false,
|
var overflowTop = false,
|
||||||
overflowBottom = false;
|
overflowBottom = false;
|
||||||
if (scrollerHeight < scrollerContentHeight) {
|
if (scrollerHeight < scrollerContentHeight) {
|
||||||
if (scrollTop > treshold) {
|
if (scrollTop > treshold) {
|
||||||
overflowTop = true;
|
overflowTop = true;
|
||||||
}
|
}
|
||||||
var scrollBottom = (scrollerContentHeight - scrollTop) - scrollerHeight;
|
var scrollBottom = (scrollerContentHeight - scrollTop) - scrollerHeight;
|
||||||
if (scrollBottom > treshold) {
|
if (scrollBottom > treshold) {
|
||||||
overflowBottom = true;
|
overflowBottom = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var wrapper = $('#preview-list-wrapper');
|
var wrapper = $('#preview-list-wrapper');
|
||||||
wrapper.toggleClass('top-overflow-visible', overflowTop);
|
wrapper.toggleClass('top-overflow-visible', overflowTop);
|
||||||
wrapper.toggleClass('bottom-overflow-visible', overflowBottom);
|
wrapper.toggleClass('bottom-overflow-visible', overflowBottom);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.createPreviews_ = function () {
|
ns.PreviewFilmController.prototype.createPreviews_ = function () {
|
||||||
|
|
||||||
this.container.html("");
|
this.container.html("");
|
||||||
// Manually remove tooltips since mouseout events were shortcut by the DOM refresh:
|
// Manually remove tooltips since mouseout events were shortcut by the DOM refresh:
|
||||||
$(".tooltip").remove();
|
$(".tooltip").remove();
|
||||||
|
|
||||||
var frameCount = this.framesheet.getFrameCount();
|
var frameCount = this.framesheet.getFrameCount();
|
||||||
|
|
||||||
for (var i = 0, l = frameCount; i < l ; i++) {
|
for (var i = 0, l = frameCount; i < l ; i++) {
|
||||||
this.container.append(this.createPreviewTile_(i));
|
this.container.append(this.createPreviewTile_(i));
|
||||||
}
|
}
|
||||||
// Append 'new empty frame' button
|
// Append 'new empty frame' button
|
||||||
var newFrameButton = document.createElement("div");
|
var newFrameButton = document.createElement("div");
|
||||||
newFrameButton.id = "add-frame-action";
|
newFrameButton.id = "add-frame-action";
|
||||||
newFrameButton.className = "add-frame-action";
|
newFrameButton.className = "add-frame-action";
|
||||||
newFrameButton.innerHTML = "<p class='label'>Add new frame</p>";
|
newFrameButton.innerHTML = "<p class='label'>Add new frame</p>";
|
||||||
this.container.append(newFrameButton);
|
this.container.append(newFrameButton);
|
||||||
|
|
||||||
$(newFrameButton).click(this.addFrame.bind(this));
|
$(newFrameButton).click(this.addFrame.bind(this));
|
||||||
|
|
||||||
var needDragndropBehavior = (frameCount > 1);
|
var needDragndropBehavior = (frameCount > 1);
|
||||||
if(needDragndropBehavior) {
|
if(needDragndropBehavior) {
|
||||||
this.initDragndropBehavior_();
|
this.initDragndropBehavior_();
|
||||||
}
|
}
|
||||||
this.updateScrollerOverflows();
|
this.updateScrollerOverflows();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.PreviewFilmController.prototype.initDragndropBehavior_ = function () {
|
ns.PreviewFilmController.prototype.initDragndropBehavior_ = function () {
|
||||||
|
|
||||||
$("#preview-list").sortable({
|
$("#preview-list").sortable({
|
||||||
placeholder: "preview-tile-drop-proxy",
|
placeholder: "preview-tile-drop-proxy",
|
||||||
update: $.proxy(this.onUpdate_, this),
|
update: $.proxy(this.onUpdate_, this),
|
||||||
items: ".preview-tile"
|
items: ".preview-tile"
|
||||||
});
|
});
|
||||||
$("#preview-list").disableSelection();
|
$("#preview-list").disableSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.PreviewFilmController.prototype.onUpdate_ = function( event, ui ) {
|
ns.PreviewFilmController.prototype.onUpdate_ = function( event, ui ) {
|
||||||
var originFrameId = parseInt(ui.item.data("tile-number"), 10);
|
var originFrameId = parseInt(ui.item.data("tile-number"), 10);
|
||||||
var targetInsertionId = $('.preview-tile').index(ui.item);
|
var targetInsertionId = $('.preview-tile').index(ui.item);
|
||||||
|
|
||||||
this.framesheet.moveFrame(originFrameId, targetInsertionId);
|
this.framesheet.moveFrame(originFrameId, targetInsertionId);
|
||||||
this.framesheet.setCurrentFrameIndex(targetInsertionId);
|
this.framesheet.setCurrentFrameIndex(targetInsertionId);
|
||||||
|
|
||||||
// TODO(grosbouddha): move localstorage request to the model layer?
|
// TODO(grosbouddha): move localstorage request to the model layer?
|
||||||
$.publish(Events.LOCALSTORAGE_REQUEST);
|
$.publish(Events.LOCALSTORAGE_REQUEST);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* 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 currentFrame = this.framesheet.getFrameByIndex(tileNumber);
|
var currentFrame = this.framesheet.getFrameByIndex(tileNumber);
|
||||||
|
|
||||||
var previewTileRoot = document.createElement("li");
|
var previewTileRoot = document.createElement("li");
|
||||||
var classname = "preview-tile";
|
var classname = "preview-tile";
|
||||||
previewTileRoot.setAttribute("data-tile-number", tileNumber);
|
previewTileRoot.setAttribute("data-tile-number", tileNumber);
|
||||||
|
|
||||||
if (this.framesheet.getCurrentFrame() == currentFrame) {
|
if (this.framesheet.getCurrentFrame() == currentFrame) {
|
||||||
classname += " selected";
|
classname += " selected";
|
||||||
}
|
}
|
||||||
previewTileRoot.className = classname;
|
previewTileRoot.className = classname;
|
||||||
|
|
||||||
var canvasContainer = document.createElement("div");
|
var canvasContainer = document.createElement("div");
|
||||||
canvasContainer.className = "canvas-container";
|
canvasContainer.className = "canvas-container";
|
||||||
|
|
||||||
var canvasBackground = document.createElement("div");
|
var canvasBackground = document.createElement("div");
|
||||||
canvasBackground.className = "canvas-background";
|
canvasBackground.className = "canvas-background";
|
||||||
canvasContainer.appendChild(canvasBackground);
|
canvasContainer.appendChild(canvasBackground);
|
||||||
|
|
||||||
previewTileRoot.addEventListener('click', this.onPreviewClick_.bind(this, tileNumber));
|
previewTileRoot.addEventListener('click', this.onPreviewClick_.bind(this, tileNumber));
|
||||||
|
|
||||||
var cloneFrameButton = document.createElement("button");
|
var cloneFrameButton = document.createElement("button");
|
||||||
cloneFrameButton.setAttribute('rel', 'tooltip');
|
cloneFrameButton.setAttribute('rel', 'tooltip');
|
||||||
cloneFrameButton.setAttribute('data-placement', 'right');
|
cloneFrameButton.setAttribute('data-placement', 'right');
|
||||||
cloneFrameButton.setAttribute('title', 'Duplicate this frame');
|
cloneFrameButton.setAttribute('title', 'Duplicate this frame');
|
||||||
cloneFrameButton.className = "tile-overlay duplicate-frame-action";
|
cloneFrameButton.className = "tile-overlay duplicate-frame-action";
|
||||||
previewTileRoot.appendChild(cloneFrameButton);
|
previewTileRoot.appendChild(cloneFrameButton);
|
||||||
cloneFrameButton.addEventListener('click', this.onAddButtonClick_.bind(this, tileNumber));
|
cloneFrameButton.addEventListener('click', this.onAddButtonClick_.bind(this, tileNumber));
|
||||||
|
|
||||||
// TODO(vincz): Eventually optimize this part by not recreating a FrameRenderer. Note that the real optim
|
// 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.
|
// is to make this update function (#createPreviewTile) less aggressive.
|
||||||
var renderingOptions = {"dpi": this.dpi };
|
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);
|
currentFrameRenderer.init(currentFrame);
|
||||||
|
|
||||||
previewTileRoot.appendChild(canvasContainer);
|
previewTileRoot.appendChild(canvasContainer);
|
||||||
|
|
||||||
if(tileNumber > 0 || this.framesheet.getFrameCount() > 1) {
|
if(tileNumber > 0 || this.framesheet.getFrameCount() > 1) {
|
||||||
// Add 'remove frame' button.
|
// Add 'remove frame' button.
|
||||||
var deleteButton = document.createElement("button");
|
var deleteButton = document.createElement("button");
|
||||||
deleteButton.setAttribute('rel', 'tooltip');
|
deleteButton.setAttribute('rel', 'tooltip');
|
||||||
deleteButton.setAttribute('data-placement', 'right');
|
deleteButton.setAttribute('data-placement', 'right');
|
||||||
deleteButton.setAttribute('title', 'Delete this frame');
|
deleteButton.setAttribute('title', 'Delete this frame');
|
||||||
deleteButton.className = "tile-overlay delete-frame-action";
|
deleteButton.className = "tile-overlay delete-frame-action";
|
||||||
deleteButton.addEventListener('click', this.onDeleteButtonClick_.bind(this, tileNumber));
|
deleteButton.addEventListener('click', this.onDeleteButtonClick_.bind(this, tileNumber));
|
||||||
previewTileRoot.appendChild(deleteButton);
|
previewTileRoot.appendChild(deleteButton);
|
||||||
|
|
||||||
// Add 'dragndrop handle'.
|
// Add 'dragndrop handle'.
|
||||||
var dndHandle = document.createElement("div");
|
var dndHandle = document.createElement("div");
|
||||||
dndHandle.className = "tile-overlay dnd-action";
|
dndHandle.className = "tile-overlay dnd-action";
|
||||||
previewTileRoot.appendChild(dndHandle);
|
previewTileRoot.appendChild(dndHandle);
|
||||||
}
|
}
|
||||||
var tileCount = document.createElement("div");
|
var tileCount = document.createElement("div");
|
||||||
tileCount.className = "tile-overlay tile-count";
|
tileCount.className = "tile-overlay tile-count";
|
||||||
tileCount.innerHTML = tileNumber;
|
tileCount.innerHTML = tileNumber;
|
||||||
previewTileRoot.appendChild(tileCount);
|
previewTileRoot.appendChild(tileCount);
|
||||||
|
|
||||||
|
|
||||||
return previewTileRoot;
|
return previewTileRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.onPreviewClick_ = function (index, evt) {
|
ns.PreviewFilmController.prototype.onPreviewClick_ = function (index, evt) {
|
||||||
// has not class tile-action:
|
// has not class tile-action:
|
||||||
if(!evt.target.classList.contains('tile-overlay')) {
|
if(!evt.target.classList.contains('tile-overlay')) {
|
||||||
this.framesheet.setCurrentFrameIndex(index);
|
this.framesheet.setCurrentFrameIndex(index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.onDeleteButtonClick_ = function (index, evt) {
|
ns.PreviewFilmController.prototype.onDeleteButtonClick_ = function (index, evt) {
|
||||||
this.framesheet.removeFrameByIndex(index);
|
this.framesheet.removeFrameByIndex(index);
|
||||||
$.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model
|
$.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model
|
||||||
this.updateScrollerOverflows();
|
this.updateScrollerOverflows();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PreviewFilmController.prototype.onAddButtonClick_ = function (index, evt) {
|
ns.PreviewFilmController.prototype.onAddButtonClick_ = function (index, evt) {
|
||||||
this.framesheet.duplicateFrameByIndex(index);
|
this.framesheet.duplicateFrameByIndex(index);
|
||||||
$.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model
|
$.publish(Events.LOCALSTORAGE_REQUEST); // Should come from model
|
||||||
this.framesheet.setCurrentFrameIndex(index + 1);
|
this.framesheet.setCurrentFrameIndex(index + 1);
|
||||||
this.updateScrollerOverflows();
|
this.updateScrollerOverflows();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the preview DPI depending on the framesheet size
|
* Calculate the preview DPI depending on the framesheet size
|
||||||
*/
|
*/
|
||||||
ns.PreviewFilmController.prototype.calculateDPI_ = function () {
|
ns.PreviewFilmController.prototype.calculateDPI_ = function () {
|
||||||
var previewSize = 120,
|
var previewSize = 120,
|
||||||
framePixelHeight = this.framesheet.getCurrentFrame().getHeight(),
|
framePixelHeight = this.framesheet.getCurrentFrame().getHeight(),
|
||||||
framePixelWidth = this.framesheet.getCurrentFrame().getWidth();
|
framePixelWidth = this.framesheet.getCurrentFrame().getWidth();
|
||||||
// TODO (julz) : should have a utility to get a Size from framesheet easily (what about empty framesheets though ?)
|
// TODO (julz) : should have a utility to get a Size from framesheet easily (what about empty framesheets though ?)
|
||||||
|
|
||||||
return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth);
|
return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,45 +1,45 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.controller");
|
var ns = $.namespace("pskl.controller");
|
||||||
|
|
||||||
ns.SettingsController = function () {};
|
ns.SettingsController = function () {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
ns.SettingsController.prototype.init = function() {
|
ns.SettingsController.prototype.init = function() {
|
||||||
|
|
||||||
// Highlight selected background picker:
|
// Highlight selected background picker:
|
||||||
var backgroundClass = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);
|
var backgroundClass = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);
|
||||||
$('#background-picker-wrapper')
|
$('#background-picker-wrapper')
|
||||||
.find('.background-picker[data-background-class=' + backgroundClass + ']')
|
.find('.background-picker[data-background-class=' + backgroundClass + ']')
|
||||||
.addClass('selected');
|
.addClass('selected');
|
||||||
|
|
||||||
// Initial state for grid display:
|
// Initial state for grid display:
|
||||||
var show_grid = pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID);
|
var show_grid = pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID);
|
||||||
$('#show-grid').prop('checked', show_grid);
|
$('#show-grid').prop('checked', show_grid);
|
||||||
|
|
||||||
// Expand drawer when clicking 'Settings' tab.
|
// Expand drawer when clicking 'Settings' tab.
|
||||||
$('#settings').click(function(evt) {
|
$('#settings').click(function(evt) {
|
||||||
$('.right-sticky-section').toggleClass('expanded');
|
$('.right-sticky-section').toggleClass('expanded');
|
||||||
$('#settings').toggleClass('has-expanded-drawer');
|
$('#settings').toggleClass('has-expanded-drawer');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle grid display changes:
|
// Handle grid display changes:
|
||||||
$('#show-grid').change($.proxy(function(evt) {
|
$('#show-grid').change($.proxy(function(evt) {
|
||||||
var checked = $('#show-grid').prop('checked');
|
var checked = $('#show-grid').prop('checked');
|
||||||
pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked);
|
pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked);
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
// Handle canvas background changes:
|
// Handle canvas background changes:
|
||||||
$('#background-picker-wrapper').click(function(evt) {
|
$('#background-picker-wrapper').click(function(evt) {
|
||||||
var target = $(evt.target).closest('.background-picker');
|
var target = $(evt.target).closest('.background-picker');
|
||||||
if (target.length) {
|
if (target.length) {
|
||||||
var backgroundClass = target.data('background-class');
|
var backgroundClass = target.data('background-class');
|
||||||
pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass);
|
pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass);
|
||||||
|
|
||||||
$('.background-picker').removeClass('selected');
|
$('.background-picker').removeClass('selected');
|
||||||
target.addClass('selected');
|
target.addClass('selected');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,99 +1,99 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.controller");
|
var ns = $.namespace("pskl.controller");
|
||||||
|
|
||||||
|
|
||||||
ns.ToolController = function () {
|
ns.ToolController = function () {
|
||||||
|
|
||||||
this.toolInstances = {
|
this.toolInstances = {
|
||||||
"simplePen" : new pskl.drawingtools.SimplePen(),
|
"simplePen" : new pskl.drawingtools.SimplePen(),
|
||||||
"verticalMirrorPen" : new pskl.drawingtools.VerticalMirrorPen(),
|
"verticalMirrorPen" : new pskl.drawingtools.VerticalMirrorPen(),
|
||||||
"eraser" : new pskl.drawingtools.Eraser(),
|
"eraser" : new pskl.drawingtools.Eraser(),
|
||||||
"paintBucket" : new pskl.drawingtools.PaintBucket(),
|
"paintBucket" : new pskl.drawingtools.PaintBucket(),
|
||||||
"stroke" : new pskl.drawingtools.Stroke(),
|
"stroke" : new pskl.drawingtools.Stroke(),
|
||||||
"rectangle" : new pskl.drawingtools.Rectangle(),
|
"rectangle" : new pskl.drawingtools.Rectangle(),
|
||||||
"circle" : new pskl.drawingtools.Circle(),
|
"circle" : new pskl.drawingtools.Circle(),
|
||||||
"move" : new pskl.drawingtools.Move(),
|
"move" : new pskl.drawingtools.Move(),
|
||||||
"rectangleSelect" : new pskl.drawingtools.RectangleSelect(),
|
"rectangleSelect" : new pskl.drawingtools.RectangleSelect(),
|
||||||
"shapeSelect" : new pskl.drawingtools.ShapeSelect(),
|
"shapeSelect" : new pskl.drawingtools.ShapeSelect(),
|
||||||
"colorPicker" : new pskl.drawingtools.ColorPicker()
|
"colorPicker" : new pskl.drawingtools.ColorPicker()
|
||||||
};
|
|
||||||
|
|
||||||
this.currentSelectedTool = this.toolInstances.simplePen;
|
|
||||||
this.previousSelectedTool = this.toolInstances.simplePen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
this.currentSelectedTool = this.toolInstances.simplePen;
|
||||||
* @private
|
this.previousSelectedTool = this.toolInstances.simplePen;
|
||||||
*/
|
};
|
||||||
ns.ToolController.prototype.activateToolOnStage_ = function(tool) {
|
|
||||||
var stage = $("body");
|
/**
|
||||||
var previousSelectedToolClass = stage.data("selected-tool-class");
|
* @private
|
||||||
if(previousSelectedToolClass) {
|
*/
|
||||||
stage.removeClass(previousSelectedToolClass);
|
ns.ToolController.prototype.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);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.ToolController.prototype.selectTool_ = function(tool) {
|
||||||
|
console.log("Selecting Tool:" , this.currentSelectedTool);
|
||||||
|
this.currentSelectedTool = tool;
|
||||||
|
this.activateToolOnStage_(this.currentSelectedTool);
|
||||||
|
$.publish(Events.TOOL_SELECTED, [tool]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.ToolController.prototype.onToolIconClicked_ = function(evt) {
|
||||||
|
var target = $(evt.target);
|
||||||
|
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]);
|
||||||
|
|
||||||
|
// Show tool as selected:
|
||||||
|
$('#tool-section .tool-icon.selected').removeClass('selected');
|
||||||
|
clickedTool.addClass('selected');
|
||||||
}
|
}
|
||||||
stage.addClass(tool.toolId);
|
}
|
||||||
stage.data("selected-tool-class", tool.toolId);
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.ToolController.prototype.selectTool_ = function(tool) {
|
ns.ToolController.prototype.createToolMarkup_ = function() {
|
||||||
console.log("Selecting Tool:" , this.currentSelectedTool);
|
var currentTool, toolMarkup = '', extraClass;
|
||||||
this.currentSelectedTool = tool;
|
// TODO(vincz): Tools rendering order is not enforced by the data stucture (this.toolInstances), fix that.
|
||||||
this.activateToolOnStage_(this.currentSelectedTool);
|
for (var toolKey in this.toolInstances) {
|
||||||
$.publish(Events.TOOL_SELECTED, [tool]);
|
currentTool = this.toolInstances[toolKey];
|
||||||
};
|
extraClass = currentTool.toolId;
|
||||||
|
if (this.currentSelectedTool == currentTool) {
|
||||||
|
extraClass = extraClass + " selected";
|
||||||
|
}
|
||||||
|
toolMarkup += '<li rel="tooltip" data-placement="right" class="tool-icon ' + extraClass + '" data-tool-id="' + currentTool.toolId +
|
||||||
|
'" title="' + currentTool.helpText + '"></li>';
|
||||||
|
}
|
||||||
|
$('#tools-container').html(toolMarkup);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @public
|
||||||
*/
|
*/
|
||||||
ns.ToolController.prototype.onToolIconClicked_ = function(evt) {
|
ns.ToolController.prototype.init = function() {
|
||||||
var target = $(evt.target);
|
|
||||||
var clickedTool = target.closest(".tool-icon");
|
|
||||||
|
|
||||||
if(clickedTool.length) {
|
this.createToolMarkup_();
|
||||||
for(var tool in this.toolInstances) {
|
|
||||||
if (this.toolInstances[tool].toolId == clickedTool.data().toolId) {
|
|
||||||
this.selectTool_(this.toolInstances[tool]);
|
|
||||||
|
|
||||||
// Show tool as selected:
|
// Initialize tool:
|
||||||
$('#tool-section .tool-icon.selected').removeClass('selected');
|
// Set SimplePen as default selected tool:
|
||||||
clickedTool.addClass('selected');
|
this.selectTool_(this.toolInstances.simplePen);
|
||||||
}
|
// Activate listener on tool panel:
|
||||||
}
|
$("#tool-section").click($.proxy(this.onToolIconClicked_, this));
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.ToolController.prototype.createToolMarkup_ = function() {
|
|
||||||
var currentTool, toolMarkup = '', extraClass;
|
|
||||||
// TODO(vincz): Tools rendering order is not enforced by the data stucture (this.toolInstances), fix that.
|
|
||||||
for (var toolKey in this.toolInstances) {
|
|
||||||
currentTool = this.toolInstances[toolKey];
|
|
||||||
extraClass = currentTool.toolId;
|
|
||||||
if (this.currentSelectedTool == currentTool) {
|
|
||||||
extraClass = extraClass + " selected";
|
|
||||||
}
|
|
||||||
toolMarkup += '<li rel="tooltip" data-placement="right" class="tool-icon ' + extraClass + '" data-tool-id="' + currentTool.toolId +
|
|
||||||
'" title="' + currentTool.helpText + '"></li>';
|
|
||||||
}
|
|
||||||
$('#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));
|
|
||||||
};
|
|
||||||
})();
|
})();
|
@ -4,69 +4,69 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.BaseTool = function() {};
|
ns.BaseTool = function() {};
|
||||||
|
|
||||||
ns.BaseTool.prototype.applyToolAt = function(col, row, color, frame, overlay) {};
|
ns.BaseTool.prototype.applyToolAt = function(col, row, color, frame, overlay) {};
|
||||||
|
|
||||||
ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay) {};
|
ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay) {};
|
||||||
|
|
||||||
ns.BaseTool.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay) {
|
ns.BaseTool.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay) {
|
||||||
if (overlay.containsPixel(col, row)) {
|
if (overlay.containsPixel(col, row)) {
|
||||||
if (!isNaN(this.highlightedPixelCol) &&
|
if (!isNaN(this.highlightedPixelCol) &&
|
||||||
!isNaN(this.highlightedPixelRow) &&
|
!isNaN(this.highlightedPixelRow) &&
|
||||||
(this.highlightedPixelRow != row ||
|
(this.highlightedPixelRow != row ||
|
||||||
this.highlightedPixelCol != col)) {
|
this.highlightedPixelCol != col)) {
|
||||||
|
|
||||||
// Clean the previously highlighted pixel:
|
// Clean the previously highlighted pixel:
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the current pixel targeted by the tool:
|
// Show the current pixel targeted by the tool:
|
||||||
overlay.setPixel(col, row, Constants.TOOL_TARGET_HIGHLIGHT_COLOR);
|
overlay.setPixel(col, row, Constants.TOOL_TARGET_HIGHLIGHT_COLOR);
|
||||||
|
|
||||||
this.highlightedPixelCol = col;
|
this.highlightedPixelCol = col;
|
||||||
this.highlightedPixelRow = row;
|
this.highlightedPixelRow = row;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseTool.prototype.releaseToolAt = function(col, row, color, frame, overlay) {};
|
ns.BaseTool.prototype.releaseToolAt = function(col, row, color, frame, overlay) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bresenham line algorihtm: Get an array of pixels from
|
* Bresenham line algorihtm: Get an array of pixels from
|
||||||
* start and end coordinates.
|
* start and end coordinates.
|
||||||
*
|
*
|
||||||
* http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
* http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||||
* http://stackoverflow.com/questions/4672279/bresenham-algorithm-in-javascript
|
* http://stackoverflow.com/questions/4672279/bresenham-algorithm-in-javascript
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.BaseTool.prototype.getLinePixels_ = function(x0, x1, y0, y1) {
|
ns.BaseTool.prototype.getLinePixels_ = function(x0, x1, y0, y1) {
|
||||||
|
|
||||||
var pixels = [];
|
var pixels = [];
|
||||||
var dx = Math.abs(x1-x0);
|
var dx = Math.abs(x1-x0);
|
||||||
var dy = Math.abs(y1-y0);
|
var dy = Math.abs(y1-y0);
|
||||||
var sx = (x0 < x1) ? 1 : -1;
|
var sx = (x0 < x1) ? 1 : -1;
|
||||||
var sy = (y0 < y1) ? 1 : -1;
|
var sy = (y0 < y1) ? 1 : -1;
|
||||||
var err = dx-dy;
|
var err = dx-dy;
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
|
|
||||||
// Do what you need to for this
|
// Do what you need to for this
|
||||||
pixels.push({"col": x0, "row": y0});
|
pixels.push({"col": x0, "row": y0});
|
||||||
|
|
||||||
if ((x0==x1) && (y0==y1)) break;
|
if ((x0==x1) && (y0==y1)) break;
|
||||||
var e2 = 2*err;
|
var e2 = 2*err;
|
||||||
if (e2>-dy){
|
if (e2>-dy){
|
||||||
err -= dy;
|
err -= dy;
|
||||||
x0 += sx;
|
x0 += sx;
|
||||||
}
|
}
|
||||||
if (e2 < dx) {
|
if (e2 < dx) {
|
||||||
err += dx;
|
err += dx;
|
||||||
y0 += sy;
|
y0 += sy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,82 +4,82 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.Circle = function() {
|
ns.Circle = function() {
|
||||||
this.toolId = "tool-circle";
|
this.toolId = "tool-circle";
|
||||||
this.helpText = "Circle tool";
|
this.helpText = "Circle tool";
|
||||||
|
|
||||||
// Circle's first point coordinates (set in applyToolAt)
|
// Circle's first point coordinates (set in applyToolAt)
|
||||||
this.startCol = null;
|
this.startCol = null;
|
||||||
this.startRow = null;
|
this.startRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.Circle, ns.BaseTool);
|
pskl.utils.inherit(ns.Circle, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Circle.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.Circle.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.startCol = col;
|
this.startCol = col;
|
||||||
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:
|
||||||
overlay.setPixel(col, row, color);
|
overlay.setPixel(col, row, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Circle.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.Circle.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
if(color == Constants.TRANSPARENT_COLOR) {
|
||||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw in overlay
|
// draw in overlay
|
||||||
this.drawCircle_(col, row, color, overlay);
|
this.drawCircle_(col, row, color, overlay);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Circle.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
ns.Circle.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
||||||
// draw in frame to finalize
|
// draw in frame to finalize
|
||||||
this.drawCircle_(col, row, color, frame);
|
this.drawCircle_(col, row, color, frame);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Circle.prototype.drawCircle_ = function (col, row, color, targetFrame) {
|
ns.Circle.prototype.drawCircle_ = function (col, row, color, targetFrame) {
|
||||||
var circlePoints = this.getCirclePixels_(this.startCol, this.startRow, col, row);
|
var circlePoints = this.getCirclePixels_(this.startCol, this.startRow, col, row);
|
||||||
for(var i = 0; i< circlePoints.length; i++) {
|
for(var i = 0; i< circlePoints.length; i++) {
|
||||||
// Change model:
|
// Change model:
|
||||||
targetFrame.setPixel(circlePoints[i].col, circlePoints[i].row, color);
|
targetFrame.setPixel(circlePoints[i].col, circlePoints[i].row, color);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Circle.prototype.getCirclePixels_ = function (x0, y0, x1, y1) {
|
ns.Circle.prototype.getCirclePixels_ = function (x0, y0, x1, y1) {
|
||||||
var coords = pskl.PixelUtils.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
var coords = pskl.PixelUtils.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
||||||
var xC = (coords.x0 + coords.x1)/2;
|
var xC = (coords.x0 + coords.x1)/2;
|
||||||
var yC = (coords.y0 + coords.y1)/2;
|
var yC = (coords.y0 + coords.y1)/2;
|
||||||
|
|
||||||
var rX = coords.x1 - xC;
|
var rX = coords.x1 - xC;
|
||||||
var rY = coords.y1 - yC;
|
var rY = coords.y1 - yC;
|
||||||
|
|
||||||
var pixels = [];
|
var pixels = [];
|
||||||
var x, y, angle;
|
var x, y, angle;
|
||||||
for (x = coords.x0 ; x < coords.x1 ; x++) {
|
for (x = coords.x0 ; x < coords.x1 ; x++) {
|
||||||
angle = Math.acos((x - xC)/rX);
|
angle = Math.acos((x - xC)/rX);
|
||||||
y = Math.round(rY * Math.sin(angle) + yC);
|
y = Math.round(rY * Math.sin(angle) + yC);
|
||||||
pixels.push({"col": x, "row": y});
|
pixels.push({"col": x, "row": y});
|
||||||
pixels.push({"col": 2*xC - x, "row": 2*yC - y});
|
pixels.push({"col": 2*xC - x, "row": 2*yC - y});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = coords.y0 ; y < coords.y1 ; y++) {
|
for (y = coords.y0 ; y < coords.y1 ; y++) {
|
||||||
angle = Math.asin((y - yC)/rY);
|
angle = Math.asin((y - yC)/rY);
|
||||||
x = Math.round(rX * Math.cos(angle) + xC);
|
x = Math.round(rX * Math.cos(angle) + xC);
|
||||||
pixels.push({"col": x, "row": y});
|
pixels.push({"col": x, "row": y});
|
||||||
pixels.push({"col": 2*xC - x, "row": 2*yC - y});
|
pixels.push({"col": 2*xC - x, "row": 2*yC - y});
|
||||||
}
|
}
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,26 +4,26 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.ColorPicker = function() {
|
ns.ColorPicker = function() {
|
||||||
this.toolId = "tool-colorpicker";
|
this.toolId = "tool-colorpicker";
|
||||||
this.helpText = "Color picker";
|
this.helpText = "Color picker";
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.ColorPicker, ns.BaseTool);
|
pskl.utils.inherit(ns.ColorPicker, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.ColorPicker.prototype.applyToolAt = function(col, row, color, frame, overlay, context) {
|
ns.ColorPicker.prototype.applyToolAt = function(col, row, color, frame, overlay, context) {
|
||||||
if (frame.containsPixel(col, row)) {
|
if (frame.containsPixel(col, row)) {
|
||||||
var sampledColor = frame.getPixel(col, row);
|
var sampledColor = frame.getPixel(col, row);
|
||||||
if (context.button == Constants.LEFT_BUTTON) {
|
if (context.button == Constants.LEFT_BUTTON) {
|
||||||
$.publish(Events.PRIMARY_COLOR_SELECTED, [sampledColor]);
|
$.publish(Events.PRIMARY_COLOR_SELECTED, [sampledColor]);
|
||||||
} else if (context.button == Constants.RIGHT_BUTTON) {
|
} else if (context.button == Constants.RIGHT_BUTTON) {
|
||||||
$.publish(Events.SECONDARY_COLOR_SELECTED, [sampledColor]);
|
$.publish(Events.SECONDARY_COLOR_SELECTED, [sampledColor]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,20 +4,20 @@
|
|||||||
* @require Constants
|
* @require Constants
|
||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.Eraser = function() {
|
ns.Eraser = function() {
|
||||||
this.toolId = "tool-eraser";
|
this.toolId = "tool-eraser";
|
||||||
this.helpText = "Eraser tool";
|
this.helpText = "Eraser tool";
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.Eraser, ns.SimplePen);
|
pskl.utils.inherit(ns.Eraser, ns.SimplePen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Eraser.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.Eraser.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.superclass.applyToolAt.call(this, col, row, Constants.TRANSPARENT_COLOR, frame, overlay);
|
this.superclass.applyToolAt.call(this, col, row, Constants.TRANSPARENT_COLOR, frame, overlay);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -4,51 +4,51 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.Move = function() {
|
ns.Move = function() {
|
||||||
this.toolId = "tool-move";
|
this.toolId = "tool-move";
|
||||||
this.helpText = "Move tool";
|
this.helpText = "Move tool";
|
||||||
|
|
||||||
// Stroke's first point coordinates (set in applyToolAt)
|
// Stroke's first point coordinates (set in applyToolAt)
|
||||||
this.startCol = null;
|
this.startCol = null;
|
||||||
this.startRow = null;
|
this.startRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.Move, ns.BaseTool);
|
pskl.utils.inherit(ns.Move, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Move.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.Move.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.startCol = col;
|
this.startCol = col;
|
||||||
this.startRow = row;
|
this.startRow = row;
|
||||||
this.frameClone = frame.clone();
|
this.frameClone = frame.clone();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Move.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.Move.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
var colDiff = col - this.startCol, rowDiff = row - this.startRow;
|
var colDiff = col - this.startCol, rowDiff = row - this.startRow;
|
||||||
this.shiftFrame(colDiff, rowDiff, frame, this.frameClone);
|
this.shiftFrame(colDiff, rowDiff, frame, this.frameClone);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Move.prototype.shiftFrame = function (colDiff, rowDiff, frame, reference) {
|
ns.Move.prototype.shiftFrame = function (colDiff, rowDiff, frame, reference) {
|
||||||
var color;
|
var color;
|
||||||
for (var col = 0 ; col < frame.getWidth() ; col++) {
|
for (var col = 0 ; col < frame.getWidth() ; col++) {
|
||||||
for (var row = 0 ; row < frame.getHeight() ; row++) {
|
for (var row = 0 ; row < frame.getHeight() ; row++) {
|
||||||
if (reference.containsPixel(col - colDiff, row - rowDiff)) {
|
if (reference.containsPixel(col - colDiff, row - rowDiff)) {
|
||||||
color = reference.getPixel(col - colDiff, row - rowDiff);
|
color = reference.getPixel(col - colDiff, row - rowDiff);
|
||||||
} else {
|
} else {
|
||||||
color = Constants.TRANSPARENT_COLOR;
|
color = Constants.TRANSPARENT_COLOR;
|
||||||
}
|
}
|
||||||
frame.setPixel(col, row, color);
|
frame.setPixel(col, row, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Move.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
ns.Move.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.moveToolAt(col, row, color, frame, overlay);
|
this.moveToolAt(col, row, color, frame, overlay);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,22 +4,22 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.PaintBucket = function() {
|
ns.PaintBucket = function() {
|
||||||
this.toolId = "tool-paint-bucket";
|
this.toolId = "tool-paint-bucket";
|
||||||
this.helpText = "Paint bucket tool";
|
this.helpText = "Paint bucket tool";
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.PaintBucket, ns.BaseTool);
|
pskl.utils.inherit(ns.PaintBucket, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.PaintBucket.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.PaintBucket.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
|
|
||||||
pskl.PixelUtils.paintSimilarConnectedPixelsFromFrame(frame, col, row, color);
|
pskl.PixelUtils.paintSimilarConnectedPixelsFromFrame(frame, col, row, color);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,56 +4,56 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.Rectangle = function() {
|
ns.Rectangle = function() {
|
||||||
this.toolId = "tool-rectangle";
|
this.toolId = "tool-rectangle";
|
||||||
this.helpText = "Rectangle tool";
|
this.helpText = "Rectangle tool";
|
||||||
|
|
||||||
// Rectangle's first point coordinates (set in applyToolAt)
|
// Rectangle's first point coordinates (set in applyToolAt)
|
||||||
this.startCol = null;
|
this.startCol = null;
|
||||||
this.startRow = null;
|
this.startRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.Rectangle, ns.BaseTool);
|
pskl.utils.inherit(ns.Rectangle, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Rectangle.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.Rectangle.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.startCol = col;
|
this.startCol = col;
|
||||||
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:
|
||||||
overlay.setPixel(col, row, color);
|
overlay.setPixel(col, row, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Rectangle.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.Rectangle.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
if(color == Constants.TRANSPARENT_COLOR) {
|
||||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw in overlay
|
// draw in overlay
|
||||||
this.drawRectangle_(col, row, color, overlay);
|
this.drawRectangle_(col, row, color, overlay);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Rectangle.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
ns.Rectangle.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
||||||
// draw in frame to finalize
|
// draw in frame to finalize
|
||||||
this.drawRectangle_(col, row, color, frame);
|
this.drawRectangle_(col, row, color, frame);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Rectangle.prototype.drawRectangle_ = function (col, row, color, targetFrame) {
|
ns.Rectangle.prototype.drawRectangle_ = function (col, row, color, targetFrame) {
|
||||||
var strokePoints = pskl.PixelUtils.getBoundRectanglePixels(this.startCol, this.startRow, col, row);
|
var strokePoints = pskl.PixelUtils.getBoundRectanglePixels(this.startCol, this.startRow, col, row);
|
||||||
for(var i = 0; i< strokePoints.length; i++) {
|
for(var i = 0; i< strokePoints.length; i++) {
|
||||||
// Change model:
|
// Change model:
|
||||||
targetFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
targetFrame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,46 +4,46 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.SimplePen = function() {
|
ns.SimplePen = function() {
|
||||||
this.toolId = "tool-pen";
|
this.toolId = "tool-pen";
|
||||||
this.helpText = "Pen tool";
|
this.helpText = "Pen tool";
|
||||||
|
|
||||||
this.previousCol = null;
|
this.previousCol = null;
|
||||||
this.previousRow = null;
|
this.previousRow = null;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.SimplePen, ns.BaseTool);
|
pskl.utils.inherit(ns.SimplePen, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.SimplePen.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.SimplePen.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
if (frame.containsPixel(col, row)) {
|
if (frame.containsPixel(col, row)) {
|
||||||
frame.setPixel(col, row, color);
|
frame.setPixel(col, row, color);
|
||||||
}
|
}
|
||||||
this.previousCol = col;
|
this.previousCol = col;
|
||||||
this.previousRow = row;
|
this.previousRow = row;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SimplePen.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.SimplePen.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
if((Math.abs(col - this.previousCol) > 1) || (Math.abs(row - this.previousRow) > 1)) {
|
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
|
// The pen movement is too fast for the mousemove frequency, there is a gap between the
|
||||||
// current point and the previously drawn one.
|
// current point and the previously drawn one.
|
||||||
// We fill the gap by calculating missing dots (simple linear interpolation) and draw them.
|
// We fill the gap by calculating missing dots (simple linear interpolation) and draw them.
|
||||||
var interpolatedPixels = this.getLinePixels_(col, this.previousCol, row, this.previousRow);
|
var interpolatedPixels = this.getLinePixels_(col, this.previousCol, row, this.previousRow);
|
||||||
for(var i=0, l=interpolatedPixels.length; i<l; i++) {
|
for(var i=0, l=interpolatedPixels.length; i<l; i++) {
|
||||||
var coords = interpolatedPixels[i];
|
var coords = interpolatedPixels[i];
|
||||||
this.applyToolAt(coords.col, coords.row, color, frame, overlay);
|
this.applyToolAt(coords.col, coords.row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.applyToolAt(col, row, color, frame, overlay);
|
this.applyToolAt(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.previousCol = col;
|
this.previousCol = col;
|
||||||
this.previousRow = row;
|
this.previousRow = row;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,77 +4,77 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.Stroke = function() {
|
ns.Stroke = function() {
|
||||||
this.toolId = "tool-stroke";
|
this.toolId = "tool-stroke";
|
||||||
this.helpText = "Stroke tool";
|
this.helpText = "Stroke tool";
|
||||||
|
|
||||||
// Stroke's first point coordinates (set in applyToolAt)
|
// Stroke's first point coordinates (set in applyToolAt)
|
||||||
this.startCol = null;
|
this.startCol = null;
|
||||||
this.startRow = null;
|
this.startRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.Stroke, ns.BaseTool);
|
pskl.utils.inherit(ns.Stroke, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Stroke.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.Stroke.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.startCol = col;
|
this.startCol = col;
|
||||||
this.startRow = row;
|
this.startRow = row;
|
||||||
|
|
||||||
// When drawing a stroke we don't change the model instantly, since the
|
// When drawing a stroke we don't change the model instantly, since the
|
||||||
// user can move his cursor to change the stroke direction and length
|
// user can move his cursor to change the stroke direction and length
|
||||||
// dynamically. Instead we draw the (preview) stroke in a fake canvas that
|
// dynamically. Instead we draw the (preview) stroke in a fake canvas that
|
||||||
// overlay the drawing canvas.
|
// overlay the drawing canvas.
|
||||||
// We wait for the releaseToolAt callback to impact both the
|
// We wait for the releaseToolAt callback to impact both the
|
||||||
// frame model and canvas rendering.
|
// frame model and canvas rendering.
|
||||||
|
|
||||||
// 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:
|
||||||
overlay.setPixel(col, row, color);
|
overlay.setPixel(col, row, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Stroke.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.Stroke.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
|
|
||||||
// When the user moussemove (before releasing), we dynamically compute the
|
// When the user moussemove (before releasing), we dynamically compute the
|
||||||
// pixel to draw the line and draw this line in the overlay canvas:
|
// pixel to draw the line and draw this line in the overlay canvas:
|
||||||
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
||||||
|
|
||||||
// Drawing current stroke:
|
// Drawing current stroke:
|
||||||
for(var i = 0; i< strokePoints.length; i++) {
|
for(var i = 0; i< strokePoints.length; i++) {
|
||||||
|
|
||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
if(color == Constants.TRANSPARENT_COLOR) {
|
||||||
// When mousemoving the stroke tool, we draw in the canvas overlay above the drawing canvas.
|
// When mousemoving the stroke tool, we draw in the canvas overlay above the drawing canvas.
|
||||||
// If the stroke color is transparent, we won't be
|
// If the stroke color is transparent, we won't be
|
||||||
// able to see it during the movement.
|
// able to see it during the movement.
|
||||||
// We set it to a semi-opaque white during the tool mousemove allowing to see colors below the stroke.
|
// We set it to a semi-opaque white during the tool mousemove allowing to see colors below the stroke.
|
||||||
// When the stroke tool will be released, It will draw a transparent stroke,
|
// When the stroke tool will be released, It will draw a transparent stroke,
|
||||||
// eg deleting the equivalent of a stroke.
|
// eg deleting the equivalent of a stroke.
|
||||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||||
}
|
}
|
||||||
overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.Stroke.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
ns.Stroke.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
||||||
// If the stroke tool is released outside of the canvas, we cancel the stroke:
|
// If the stroke tool is released outside of the canvas, we cancel the stroke:
|
||||||
// TODO: Mutualize this check in common method
|
// TODO: Mutualize this check in common method
|
||||||
if(frame.containsPixel(col, row)) {
|
if(frame.containsPixel(col, row)) {
|
||||||
// The user released the tool to draw a line. We will compute the pixel coordinate, impact
|
// 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)
|
// the model and draw them in the drawing canvas (not the fake overlay anymore)
|
||||||
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
||||||
for(var i = 0; i< strokePoints.length; i++) {
|
for(var i = 0; i< strokePoints.length; i++) {
|
||||||
// Change model:
|
// Change model:
|
||||||
frame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
frame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For now, we are done with the stroke tool and don't need an overlay anymore:
|
// For now, we are done with the stroke tool and don't need an overlay anymore:
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -1,46 +1,46 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.VerticalMirrorPen = function() {
|
ns.VerticalMirrorPen = function() {
|
||||||
this.toolId = "tool-vertical-mirror-pen";
|
this.toolId = "tool-vertical-mirror-pen";
|
||||||
this.helpText = "vertical mirror pen tool";
|
this.helpText = "vertical mirror pen tool";
|
||||||
|
|
||||||
this.swap = null;
|
this.swap = null;
|
||||||
this.mirroredPreviousCol = null;
|
this.mirroredPreviousCol = null;
|
||||||
this.mirroredPreviousRow = null;
|
this.mirroredPreviousRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.VerticalMirrorPen, ns.SimplePen);
|
pskl.utils.inherit(ns.VerticalMirrorPen, ns.SimplePen);
|
||||||
|
|
||||||
|
|
||||||
ns.VerticalMirrorPen.prototype.setMirrorContext = function() {
|
ns.VerticalMirrorPen.prototype.setMirrorContext = function() {
|
||||||
this.swap = this.previousCol;
|
this.swap = this.previousCol;
|
||||||
this.previousCol = this.mirroredPreviousCol;
|
this.previousCol = this.mirroredPreviousCol;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.VerticalMirrorPen.prototype.unsetMirrorContext = function() {
|
ns.VerticalMirrorPen.prototype.unsetMirrorContext = function() {
|
||||||
this.mirroredPreviousCol = this.previousCol;
|
this.mirroredPreviousCol = this.previousCol;
|
||||||
this.previousCol = this.swap;
|
this.previousCol = this.swap;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.VerticalMirrorPen.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.VerticalMirrorPen.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.superclass.applyToolAt.call(this, col, row, color, frame, overlay);
|
this.superclass.applyToolAt.call(this, col, row, color, frame, overlay);
|
||||||
|
|
||||||
var mirroredCol = this.getSymmetricCol_(col, frame);
|
var mirroredCol = this.getSymmetricCol_(col, frame);
|
||||||
this.mirroredPreviousCol = mirroredCol;
|
this.mirroredPreviousCol = mirroredCol;
|
||||||
|
|
||||||
this.setMirrorContext();
|
this.setMirrorContext();
|
||||||
this.superclass.applyToolAt.call(this, mirroredCol, row, color, frame, overlay);
|
this.superclass.applyToolAt.call(this, mirroredCol, row, color, frame, overlay);
|
||||||
this.unsetMirrorContext();
|
this.unsetMirrorContext();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.VerticalMirrorPen.prototype.getSymmetricCol_ = function(col, frame) {
|
ns.VerticalMirrorPen.prototype.getSymmetricCol_ = function(col, frame) {
|
||||||
return frame.getWidth() - col - 1;
|
return frame.getWidth() - col - 1;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -4,147 +4,147 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.BaseSelect = function() {
|
ns.BaseSelect = function() {
|
||||||
this.secondaryToolId = "tool-move";
|
this.secondaryToolId = "tool-move";
|
||||||
this.BodyRoot = $('body');
|
this.BodyRoot = $('body');
|
||||||
|
|
||||||
// Select's first point coordinates (set in applyToolAt)
|
// Select's first point coordinates (set in applyToolAt)
|
||||||
this.startCol = null;
|
this.startCol = null;
|
||||||
this.startRow = null;
|
this.startRow = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.BaseSelect, ns.BaseTool);
|
pskl.utils.inherit(ns.BaseSelect, ns.BaseTool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.BaseSelect.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.applyToolAt = function(col, row, color, frame, overlay) {
|
||||||
this.startCol = col;
|
this.startCol = col;
|
||||||
this.startRow = row;
|
this.startRow = row;
|
||||||
|
|
||||||
this.lastCol = col;
|
this.lastCol = col;
|
||||||
this.lastRow = row;
|
this.lastRow = row;
|
||||||
|
|
||||||
// The select tool can be in two different state.
|
// The select tool can be in two different state.
|
||||||
// If the inital click of the tool is not on a selection, we go in "select"
|
// If the inital click of the tool is not on a selection, we go in "select"
|
||||||
// mode to create a selection.
|
// mode to create a selection.
|
||||||
// If the initial click is on a previous selection, we go in "moveSelection"
|
// If the initial click is on a previous selection, we go in "moveSelection"
|
||||||
// mode to allow to move the selection by drag'n dropping it.
|
// mode to allow to move the selection by drag'n dropping it.
|
||||||
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
||||||
|
|
||||||
this.mode = "select";
|
this.mode = "select";
|
||||||
this.onSelectStart_(col, row, color, frame, overlay);
|
this.onSelectStart_(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
this.mode = "moveSelection";
|
this.mode = "moveSelection";
|
||||||
this.onSelectionDragStart_(col, row, color, frame, overlay);
|
this.onSelectionDragStart_(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.BaseSelect.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.moveToolAt = function(col, row, color, frame, overlay) {
|
||||||
if(this.mode == "select") {
|
if(this.mode == "select") {
|
||||||
|
|
||||||
this.onSelect_(col, row, color, frame, overlay);
|
this.onSelect_(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
else if(this.mode == "moveSelection") {
|
else if(this.mode == "moveSelection") {
|
||||||
|
|
||||||
this.onSelectionDrag_(col, row, color, frame, overlay);
|
this.onSelectionDrag_(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.BaseSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) {
|
||||||
if(this.mode == "select") {
|
if(this.mode == "select") {
|
||||||
|
|
||||||
this.onSelectEnd_(col, row, color, frame, overlay);
|
this.onSelectEnd_(col, row, color, frame, overlay);
|
||||||
} else if(this.mode == "moveSelection") {
|
} else if(this.mode == "moveSelection") {
|
||||||
|
|
||||||
this.onSelectionDragEnd_(col, row, color, frame, overlay);
|
this.onSelectionDragEnd_(col, row, color, frame, overlay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we mouseover the selection draw inside the overlay frame, show the 'move' cursor
|
* If we mouseover the selection draw inside the overlay frame, show the 'move' cursor
|
||||||
* instead of the 'select' one. It indicates that we can move the selection by dragndroping it.
|
* instead of the 'select' one. It indicates that we can move the selection by dragndroping it.
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.BaseSelect.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay) {
|
||||||
|
|
||||||
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
||||||
// We're hovering the selection, show the move tool:
|
// We're hovering the selection, show the move tool:
|
||||||
this.BodyRoot.addClass(this.toolId);
|
this.BodyRoot.addClass(this.toolId);
|
||||||
this.BodyRoot.removeClass(this.secondaryToolId);
|
this.BodyRoot.removeClass(this.secondaryToolId);
|
||||||
} else {
|
} else {
|
||||||
// We're not hovering the selection, show create selection tool:
|
// We're not hovering the selection, show create selection tool:
|
||||||
this.BodyRoot.addClass(this.secondaryToolId);
|
this.BodyRoot.addClass(this.secondaryToolId);
|
||||||
this.BodyRoot.removeClass(this.toolId);
|
this.BodyRoot.removeClass(this.toolId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the overlay frame filled with semi-transparent pixels that represent the selection.
|
* Move the overlay frame filled with semi-transparent pixels that represent the selection.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.BaseSelect.prototype.shiftOverlayFrame_ = function (colDiff, rowDiff, overlayFrame, reference) {
|
ns.BaseSelect.prototype.shiftOverlayFrame_ = function (colDiff, rowDiff, overlayFrame, reference) {
|
||||||
var color;
|
var color;
|
||||||
for (var col = 0 ; col < overlayFrame.getWidth() ; col++) {
|
for (var col = 0 ; col < overlayFrame.getWidth() ; col++) {
|
||||||
for (var row = 0 ; row < overlayFrame.getHeight() ; row++) {
|
for (var row = 0 ; row < overlayFrame.getHeight() ; row++) {
|
||||||
if (reference.containsPixel(col - colDiff, row - rowDiff)) {
|
if (reference.containsPixel(col - colDiff, row - rowDiff)) {
|
||||||
color = reference.getPixel(col - colDiff, row - rowDiff);
|
color = reference.getPixel(col - colDiff, row - rowDiff);
|
||||||
} else {
|
} else {
|
||||||
color = Constants.TRANSPARENT_COLOR;
|
color = Constants.TRANSPARENT_COLOR;
|
||||||
}
|
}
|
||||||
overlayFrame.setPixel(col, row, color);
|
overlayFrame.setPixel(col, row, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// The list of callbacks to implement by specialized tools to implement the selection creation behavior.
|
// The list of callbacks to implement by specialized tools to implement the selection creation behavior.
|
||||||
/** @protected */
|
/** @protected */
|
||||||
ns.BaseSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {};
|
ns.BaseSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {};
|
||||||
/** @protected */
|
/** @protected */
|
||||||
ns.BaseSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) {};
|
ns.BaseSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) {};
|
||||||
/** @protected */
|
/** @protected */
|
||||||
ns.BaseSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) {};
|
ns.BaseSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) {};
|
||||||
|
|
||||||
|
|
||||||
// The list of callbacks that define the drag'n drop behavior of the selection.
|
// The list of callbacks that define the drag'n drop behavior of the selection.
|
||||||
/** @private */
|
/** @private */
|
||||||
ns.BaseSelect.prototype.onSelectionDragStart_ = function (col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.onSelectionDragStart_ = function (col, row, color, frame, overlay) {
|
||||||
// Since we will move the overlayFrame in which the current selection is rendered,
|
// Since we will move the overlayFrame in which the current selection is rendered,
|
||||||
// we clone it to have a reference for the later shifting process.
|
// we clone it to have a reference for the later shifting process.
|
||||||
this.overlayFrameReference = overlay.clone();
|
this.overlayFrameReference = overlay.clone();
|
||||||
};
|
};
|
||||||
/** @private */
|
/** @private */
|
||||||
ns.BaseSelect.prototype.onSelectionDrag_ = function (col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.onSelectionDrag_ = function (col, row, color, frame, overlay) {
|
||||||
var deltaCol = col - this.lastCol;
|
var deltaCol = col - this.lastCol;
|
||||||
var deltaRow = row - this.lastRow;
|
var deltaRow = row - this.lastRow;
|
||||||
|
|
||||||
var colDiff = col - this.startCol, rowDiff = row - this.startRow;
|
var colDiff = col - this.startCol, rowDiff = row - this.startRow;
|
||||||
|
|
||||||
// Shifting selection on overlay frame:
|
// Shifting selection on overlay frame:
|
||||||
this.shiftOverlayFrame_(colDiff, rowDiff, overlay, this.overlayFrameReference);
|
this.shiftOverlayFrame_(colDiff, rowDiff, overlay, this.overlayFrameReference);
|
||||||
|
|
||||||
// Update selection model:
|
// Update selection model:
|
||||||
$.publish(Events.SELECTION_MOVE_REQUEST, [deltaCol, deltaRow]);
|
$.publish(Events.SELECTION_MOVE_REQUEST, [deltaCol, deltaRow]);
|
||||||
|
|
||||||
this.lastCol = col;
|
this.lastCol = col;
|
||||||
this.lastRow = row;
|
this.lastRow = row;
|
||||||
};
|
};
|
||||||
/** @private */
|
/** @private */
|
||||||
ns.BaseSelect.prototype.onSelectionDragEnd_ = function (col, row, color, frame, overlay) {
|
ns.BaseSelect.prototype.onSelectionDragEnd_ = function (col, row, color, frame, overlay) {
|
||||||
this.onSelectionDrag_(col, row, color, frame, overlay);
|
this.onSelectionDrag_(col, row, color, frame, overlay);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -4,48 +4,48 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.RectangleSelect = function() {
|
ns.RectangleSelect = function() {
|
||||||
this.toolId = "tool-rectangle-select";
|
this.toolId = "tool-rectangle-select";
|
||||||
this.helpText = "Rectangle selection tool";
|
this.helpText = "Rectangle selection tool";
|
||||||
|
|
||||||
ns.BaseSelect.call(this);
|
ns.BaseSelect.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.RectangleSelect, ns.BaseSelect);
|
pskl.utils.inherit(ns.RectangleSelect, ns.BaseSelect);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.RectangleSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {
|
ns.RectangleSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {
|
||||||
// Drawing the first point of the rectangle in the fake overlay canvas:
|
// Drawing the first point of the rectangle in the fake overlay canvas:
|
||||||
overlay.setPixel(col, row, color);
|
overlay.setPixel(col, row, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When creating the rectangle selection, we clear the current overlayFrame and
|
* When creating the rectangle selection, we clear the current overlayFrame and
|
||||||
* redraw the current rectangle based on the orgin coordinate and
|
* redraw the current rectangle based on the orgin coordinate and
|
||||||
* the current mouse coordiinate in sprite.
|
* the current mouse coordiinate in sprite.
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.RectangleSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) {
|
ns.RectangleSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) {
|
||||||
overlay.clear();
|
overlay.clear();
|
||||||
if(this.startCol == col &&this.startRow == row) {
|
if(this.startCol == col &&this.startRow == row) {
|
||||||
$.publish(Events.SELECTION_DISMISSED);
|
$.publish(Events.SELECTION_DISMISSED);
|
||||||
} else {
|
} else {
|
||||||
var selection = new pskl.selection.RectangularSelection(
|
var selection = new pskl.selection.RectangularSelection(
|
||||||
this.startCol, this.startRow, col, row);
|
this.startCol, this.startRow, col, row);
|
||||||
$.publish(Events.SELECTION_CREATED, [selection]);
|
$.publish(Events.SELECTION_CREATED, [selection]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.RectangleSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) {
|
ns.RectangleSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) {
|
||||||
this.onSelect_(col, row, color, frame, overlay);
|
this.onSelect_(col, row, color, frame, overlay);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -4,31 +4,31 @@
|
|||||||
* @require pskl.utils
|
* @require pskl.utils
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
var ns = $.namespace("pskl.drawingtools");
|
var ns = $.namespace("pskl.drawingtools");
|
||||||
|
|
||||||
ns.ShapeSelect = function() {
|
ns.ShapeSelect = function() {
|
||||||
this.toolId = "tool-shape-select";
|
this.toolId = "tool-shape-select";
|
||||||
this.helpText = "Shape selection tool";
|
this.helpText = "Shape selection tool";
|
||||||
|
|
||||||
ns.BaseSelect.call(this);
|
ns.BaseSelect.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.ShapeSelect, ns.BaseSelect);
|
pskl.utils.inherit(ns.ShapeSelect, ns.BaseSelect);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the shape select tool, you just need to click one time to create a selection.
|
* 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_)
|
* So we jsut need to implement onSelectStart_ (no need for onSelect_ & onSelectEnd_)
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
ns.ShapeSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {
|
ns.ShapeSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {
|
||||||
// Clean previous selection:
|
// Clean previous selection:
|
||||||
$.publish(Events.SELECTION_DISMISSED);
|
$.publish(Events.SELECTION_DISMISSED);
|
||||||
|
|
||||||
// From the pixel cliked, get shape using an algorithm similar to the paintbucket one:
|
// From the pixel cliked, get shape using an algorithm similar to the paintbucket one:
|
||||||
var pixels = pskl.PixelUtils.getSimilarConnectedPixelsFromFrame(frame, col, row);
|
var pixels = pskl.PixelUtils.getSimilarConnectedPixelsFromFrame(frame, col, row);
|
||||||
var selection = new pskl.selection.ShapeSelection(pixels);
|
var selection = new pskl.selection.ShapeSelection(pixels);
|
||||||
$.publish(Events.SELECTION_CREATED, [selection]);
|
$.publish(Events.SELECTION_CREATED, [selection]);
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1,118 +1,118 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.model");
|
var ns = $.namespace("pskl.model");
|
||||||
|
|
||||||
ns.Frame = function (pixels) {
|
ns.Frame = function (pixels) {
|
||||||
this.pixels = pixels;
|
this.pixels = pixels;
|
||||||
this.previousStates = [this.getPixels()];
|
this.previousStates = [this.getPixels()];
|
||||||
this.stateIndex = 0;
|
this.stateIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.createEmpty = function (width, height) {
|
ns.Frame.createEmpty = function (width, height) {
|
||||||
var pixels = ns.Frame.createEmptyPixelGrid_(width, height);
|
var pixels = ns.Frame.createEmptyPixelGrid_(width, height);
|
||||||
return new ns.Frame(pixels);
|
return new ns.Frame(pixels);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.createEmptyPixelGrid_ = function (width, height) {
|
ns.Frame.createEmptyPixelGrid_ = function (width, height) {
|
||||||
var pixels = []; //new Array(width);
|
var pixels = []; //new Array(width);
|
||||||
for (var columnIndex=0; columnIndex < width; columnIndex++) {
|
for (var columnIndex=0; columnIndex < width; columnIndex++) {
|
||||||
var columnArray = [];
|
var columnArray = [];
|
||||||
for(var heightIndex = 0; heightIndex < height; heightIndex++) {
|
for(var heightIndex = 0; heightIndex < height; heightIndex++) {
|
||||||
columnArray.push(Constants.TRANSPARENT_COLOR);
|
columnArray.push(Constants.TRANSPARENT_COLOR);
|
||||||
}
|
}
|
||||||
pixels[columnIndex] = columnArray;
|
pixels[columnIndex] = columnArray;
|
||||||
}
|
}
|
||||||
return pixels;
|
return pixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.createEmptyFromFrame = function (frame) {
|
ns.Frame.createEmptyFromFrame = function (frame) {
|
||||||
return ns.Frame.createEmpty(frame.getWidth(), frame.getHeight());
|
return ns.Frame.createEmpty(frame.getWidth(), frame.getHeight());
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.clone = function () {
|
ns.Frame.prototype.clone = function () {
|
||||||
return new ns.Frame(this.getPixels());
|
return new ns.Frame(this.getPixels());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of the pixels used by the frame
|
* Returns a copy of the pixels used by the frame
|
||||||
*/
|
*/
|
||||||
ns.Frame.prototype.getPixels = function () {
|
ns.Frame.prototype.getPixels = function () {
|
||||||
return this.clonePixels_(this.pixels);
|
return this.clonePixels_(this.pixels);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the passed pixels into the frame.
|
* Copies the passed pixels into the frame.
|
||||||
*/
|
*/
|
||||||
ns.Frame.prototype.setPixels = function (pixels) {
|
ns.Frame.prototype.setPixels = function (pixels) {
|
||||||
this.pixels = this.clonePixels_(pixels);
|
this.pixels = this.clonePixels_(pixels);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ns.Frame.prototype.clear = function () {
|
ns.Frame.prototype.clear = function () {
|
||||||
var pixels = ns.Frame.createEmptyPixelGrid_(this.getWidth(), this.getHeight());
|
var pixels = ns.Frame.createEmptyPixelGrid_(this.getWidth(), this.getHeight());
|
||||||
this.setPixels(pixels);
|
this.setPixels(pixels);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone a set of pixels. Should be static utility method
|
* Clone a set of pixels. Should be static utility method
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.Frame.prototype.clonePixels_ = function (pixels) {
|
ns.Frame.prototype.clonePixels_ = function (pixels) {
|
||||||
var clonedPixels = [];
|
var clonedPixels = [];
|
||||||
for (var col = 0 ; col < pixels.length ; col++) {
|
for (var col = 0 ; col < pixels.length ; col++) {
|
||||||
clonedPixels[col] = pixels[col].slice(0 , pixels[col].length);
|
clonedPixels[col] = pixels[col].slice(0 , pixels[col].length);
|
||||||
}
|
}
|
||||||
return clonedPixels;
|
return clonedPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.serialize = function () {
|
ns.Frame.prototype.serialize = function () {
|
||||||
return JSON.stringify(this.pixels);
|
return JSON.stringify(this.pixels);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.setPixel = function (col, row, color) {
|
ns.Frame.prototype.setPixel = function (col, row, color) {
|
||||||
this.pixels[col][row] = color;
|
this.pixels[col][row] = color;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.getPixel = function (col, row) {
|
ns.Frame.prototype.getPixel = function (col, row) {
|
||||||
return this.pixels[col][row];
|
return this.pixels[col][row];
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.getWidth = function () {
|
ns.Frame.prototype.getWidth = function () {
|
||||||
return this.pixels.length;
|
return this.pixels.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.getHeight = function () {
|
ns.Frame.prototype.getHeight = function () {
|
||||||
return this.pixels[0].length;
|
return this.pixels[0].length;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.containsPixel = function (col, row) {
|
ns.Frame.prototype.containsPixel = function (col, row) {
|
||||||
return col >= 0 && row >= 0 && col < this.pixels.length && row < this.pixels[0].length;
|
return col >= 0 && row >= 0 && col < this.pixels.length && row < this.pixels[0].length;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.saveState = function () {
|
ns.Frame.prototype.saveState = function () {
|
||||||
// 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.getPixels());
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.loadPreviousState = function () {
|
ns.Frame.prototype.loadPreviousState = function () {
|
||||||
if (this.stateIndex > 0) {
|
if (this.stateIndex > 0) {
|
||||||
this.stateIndex--;
|
this.stateIndex--;
|
||||||
this.setPixels(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.setPixels(this.previousStates[this.stateIndex]);
|
this.setPixels(this.previousStates[this.stateIndex]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Frame.prototype.isSameSize = function (otherFrame) {
|
ns.Frame.prototype.isSameSize = function (otherFrame) {
|
||||||
return this.getHeight() == otherFrame.getHeight() && this.getWidth() == otherFrame.getWidth();
|
return this.getHeight() == otherFrame.getHeight() && this.getWidth() == otherFrame.getWidth();
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,157 +1,157 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.model");
|
var ns = $.namespace("pskl.model");
|
||||||
ns.FrameSheet = function (height, width) {
|
ns.FrameSheet = function (height, width) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.frames = [];
|
this.frames = [];
|
||||||
this.currentFrameIndex = 0;
|
this.currentFrameIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getHeight = function () {
|
ns.FrameSheet.prototype.getHeight = function () {
|
||||||
return this.height;
|
return this.height;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getWidth = function () {
|
ns.FrameSheet.prototype.getWidth = function () {
|
||||||
return this.width;
|
return this.width;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.addEmptyFrame = function () {
|
ns.FrameSheet.prototype.addEmptyFrame = function () {
|
||||||
this.addFrame(ns.Frame.createEmpty(this.width, this.height));
|
this.addFrame(ns.Frame.createEmpty(this.width, this.height));
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.addFrame = function (frame) {
|
ns.FrameSheet.prototype.addFrame = function (frame) {
|
||||||
this.frames.push(frame);
|
this.frames.push(frame);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getFrameCount = function () {
|
ns.FrameSheet.prototype.getFrameCount = function () {
|
||||||
return this.frames.length;
|
return this.frames.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getCurrentFrame = function () {
|
ns.FrameSheet.prototype.getCurrentFrame = function () {
|
||||||
return this.frames[this.currentFrameIndex];
|
return this.frames[this.currentFrameIndex];
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.setCurrentFrameIndex = function (index) {
|
ns.FrameSheet.prototype.setCurrentFrameIndex = function (index) {
|
||||||
this.currentFrameIndex = index;
|
this.currentFrameIndex = index;
|
||||||
$.publish(Events.CURRENT_FRAME_SET, [this.getCurrentFrame()]);
|
$.publish(Events.CURRENT_FRAME_SET, [this.getCurrentFrame()]);
|
||||||
$.publish(Events.FRAMESHEET_RESET); // Is it no to overkill to have this here ?
|
$.publish(Events.FRAMESHEET_RESET); // Is it no to overkill to have this here ?
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getUsedColors = function() {
|
ns.FrameSheet.prototype.getUsedColors = function() {
|
||||||
var colors = {};
|
var colors = {};
|
||||||
for (var frameIndex=0; frameIndex < this.frames.length; frameIndex++) {
|
for (var frameIndex=0; frameIndex < this.frames.length; frameIndex++) {
|
||||||
var frame = this.frames[frameIndex];
|
var frame = this.frames[frameIndex];
|
||||||
for (var i = 0, width = frame.getWidth(); i < width ; i++) {
|
for (var i = 0, width = frame.getWidth(); i < width ; i++) {
|
||||||
var line = frame[i];
|
var line = frame[i];
|
||||||
for (var j = 0, height = frame.getHeight() ; j < height ; j++) {
|
for (var j = 0, height = frame.getHeight() ; j < height ; j++) {
|
||||||
var pixel = frame.getPixel(i, j);
|
var pixel = frame.getPixel(i, j);
|
||||||
colors[pixel] = pixel;
|
colors[pixel] = pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return colors;
|
return colors;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Could be used to pass around model using long GET param (good enough for simple models) and
|
// Could be used to pass around model using long GET param (good enough for simple models) and
|
||||||
// do some temporary locastorage
|
// do some temporary locastorage
|
||||||
ns.FrameSheet.prototype.serialize = function() {
|
ns.FrameSheet.prototype.serialize = function() {
|
||||||
var serializedFrames = [];
|
var serializedFrames = [];
|
||||||
for (var i = 0 ; i < this.frames.length ; i++) {
|
for (var i = 0 ; i < this.frames.length ; i++) {
|
||||||
serializedFrames.push(this.frames[i].serialize());
|
serializedFrames.push(this.frames[i].serialize());
|
||||||
}
|
}
|
||||||
return '[' + serializedFrames.join(",") + ']';
|
return '[' + serializedFrames.join(",") + ']';
|
||||||
//return JSON.stringify(frames);
|
//return JSON.stringify(frames);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a framesheet from a model that might have been persisted in db / localstorage
|
* Load a framesheet from a model that might have been persisted in db / localstorage
|
||||||
* Overrides existing frames.
|
* Overrides existing frames.
|
||||||
* @param {String} serialized
|
* @param {String} serialized
|
||||||
*/
|
*/
|
||||||
ns.FrameSheet.prototype.deserialize = function (serialized) {
|
ns.FrameSheet.prototype.deserialize = function (serialized) {
|
||||||
try {
|
try {
|
||||||
this.load(JSON.parse(serialized));
|
this.load(JSON.parse(serialized));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw "Could not load serialized framesheet : " + e.message;
|
throw "Could not load serialized framesheet : " + e.message;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a framesheet from a model that might have been persisted in db / localstorage
|
* Load a framesheet from a model that might have been persisted in db / localstorage
|
||||||
* Overrides existing frames.
|
* Overrides existing frames.
|
||||||
* @param {String} serialized
|
* @param {String} serialized
|
||||||
*/
|
*/
|
||||||
ns.FrameSheet.prototype.load = function (framesheet) {
|
ns.FrameSheet.prototype.load = function (framesheet) {
|
||||||
this.frames = [];
|
this.frames = [];
|
||||||
for (var i = 0 ; i < framesheet.length ; i++) {
|
for (var i = 0 ; i < framesheet.length ; i++) {
|
||||||
var frameCfg = framesheet[i];
|
var frameCfg = framesheet[i];
|
||||||
this.addFrame(new ns.Frame(frameCfg));
|
this.addFrame(new ns.Frame(frameCfg));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasFrameAtIndex(0)) {
|
if (this.hasFrameAtIndex(0)) {
|
||||||
this.height = this.getFrameByIndex(0).getHeight();
|
this.height = this.getFrameByIndex(0).getHeight();
|
||||||
this.width = this.getFrameByIndex(0).getWidth();
|
this.width = this.getFrameByIndex(0).getWidth();
|
||||||
this.setCurrentFrameIndex(0);
|
this.setCurrentFrameIndex(0);
|
||||||
$.publish(Events.FRAME_SIZE_CHANGED);
|
$.publish(Events.FRAME_SIZE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.publish(Events.FRAMESHEET_RESET);
|
$.publish(Events.FRAMESHEET_RESET);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ns.FrameSheet.prototype.hasFrameAtIndex = function(index) {
|
ns.FrameSheet.prototype.hasFrameAtIndex = function(index) {
|
||||||
return (index >= 0 && index < this.getFrameCount());
|
return (index >= 0 && index < this.getFrameCount());
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.getFrameByIndex = function(index) {
|
ns.FrameSheet.prototype.getFrameByIndex = function(index) {
|
||||||
if (isNaN(index)) {
|
if (isNaN(index)) {
|
||||||
throw "Bad argument value for getFrameByIndex method: <" + index + ">";
|
throw "Bad argument value for getFrameByIndex method: <" + index + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.hasFrameAtIndex(index)) {
|
if (!this.hasFrameAtIndex(index)) {
|
||||||
throw "Out of bound index for frameSheet object.";
|
throw "Out of bound index for frameSheet object.";
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.frames[index];
|
return this.frames[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.removeFrameByIndex = function(index) {
|
ns.FrameSheet.prototype.removeFrameByIndex = function(index) {
|
||||||
if(!this.hasFrameAtIndex(index)) {
|
if(!this.hasFrameAtIndex(index)) {
|
||||||
throw "Out of bound index for frameSheet object.";
|
throw "Out of bound index for frameSheet object.";
|
||||||
}
|
}
|
||||||
this.frames.splice(index, 1);
|
this.frames.splice(index, 1);
|
||||||
|
|
||||||
// Current frame index might not be valid anymore
|
// Current frame index might not be valid anymore
|
||||||
if (!this.hasFrameAtIndex(this.currentFrameIndex)) {
|
if (!this.hasFrameAtIndex(this.currentFrameIndex)) {
|
||||||
// if not select last frame available
|
// if not select last frame available
|
||||||
this.setCurrentFrameIndex(this.getFrameCount() - 1);
|
this.setCurrentFrameIndex(this.getFrameCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.publish(Events.FRAMESHEET_RESET);
|
$.publish(Events.FRAMESHEET_RESET);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.duplicateFrameByIndex = function(index) {
|
ns.FrameSheet.prototype.duplicateFrameByIndex = function(index) {
|
||||||
var frame = this.getFrameByIndex(index);
|
var frame = this.getFrameByIndex(index);
|
||||||
this.frames.splice(index + 1, 0, frame.clone());
|
this.frames.splice(index + 1, 0, frame.clone());
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.moveFrame = function(originIndex, destinationIndex) {
|
ns.FrameSheet.prototype.moveFrame = function(originIndex, destinationIndex) {
|
||||||
this.frames.splice(destinationIndex, 0, this.frames.splice(originIndex, 1)[0]);
|
this.frames.splice(destinationIndex, 0, this.frames.splice(originIndex, 1)[0]);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameSheet.prototype.swapFrames = function(indexFrame1, indexFrame2) {
|
ns.FrameSheet.prototype.swapFrames = function(indexFrame1, indexFrame2) {
|
||||||
if(isNaN(indexFrame1) || isNaN(indexFrame1) ||
|
if(isNaN(indexFrame1) || isNaN(indexFrame1) ||
|
||||||
(!this.hasFrameAtIndex(indexFrame1) && !this.hasFrameAtIndex(indexFrame2))) {
|
(!this.hasFrameAtIndex(indexFrame1) && !this.hasFrameAtIndex(indexFrame2))) {
|
||||||
throw "Bad indexes for swapFrames Framesheet function.";
|
throw "Bad indexes for swapFrames Framesheet function.";
|
||||||
}
|
}
|
||||||
if(indexFrame1 == indexFrame2) {
|
if(indexFrame1 == indexFrame2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var swapFrame = this.frames[indexFrame1];
|
var swapFrame = this.frames[indexFrame1];
|
||||||
this.frames[indexFrame1] = this.frames[indexFrame2];
|
this.frames[indexFrame1] = this.frames[indexFrame2];
|
||||||
this.frames[indexFrame2] = swapFrame;
|
this.frames[indexFrame2] = swapFrame;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -184,7 +184,7 @@
|
|||||||
if (this.status == 200) {
|
if (this.status == 200) {
|
||||||
if (pskl.app.isStaticVersion) {
|
if (pskl.app.isStaticVersion) {
|
||||||
var baseUrl = window.location.href.replace(window.location.search, "");
|
var baseUrl = window.location.href.replace(window.location.search, "");
|
||||||
window.location.href = baseUrl + "?frameId=" + this.responseText;
|
window.location.href = baseUrl + "?frameId=" + this.responseText;
|
||||||
} else {
|
} else {
|
||||||
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]);
|
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]);
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
var ns = $.namespace("pskl.rendering");
|
var ns = $.namespace("pskl.rendering");
|
||||||
ns.CanvasRenderer = function (frame, dpi) {
|
ns.CanvasRenderer = function (frame, dpi) {
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.dpi = dpi;
|
this.dpi = dpi;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.CanvasRenderer.prototype.render = function (frame, dpi) {
|
ns.CanvasRenderer.prototype.render = function (frame, dpi) {
|
||||||
var canvas = this.createCanvas_();
|
var canvas = this.createCanvas_();
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
for(var col = 0, width = this.frame.getWidth(); col < width; col++) {
|
for(var col = 0, width = this.frame.getWidth(); col < width; col++) {
|
||||||
for(var row = 0, height = this.frame.getHeight(); row < height; row++) {
|
for(var row = 0, height = this.frame.getHeight(); row < height; row++) {
|
||||||
var color = this.frame.getPixel(col, row);
|
var color = this.frame.getPixel(col, row);
|
||||||
this.renderPixel_(color, col, row, context);
|
this.renderPixel_(color, col, row, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.CanvasRenderer.prototype.renderPixel_ = function (color, col, row, context) {
|
ns.CanvasRenderer.prototype.renderPixel_ = function (color, col, row, context) {
|
||||||
if(color == Constants.TRANSPARENT_COLOR) {
|
if(color == Constants.TRANSPARENT_COLOR) {
|
||||||
color = "#FFF";
|
color = "#FFF";
|
||||||
}
|
}
|
||||||
|
|
||||||
context.fillStyle = color;
|
context.fillStyle = color;
|
||||||
context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi);
|
context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.CanvasRenderer.prototype.createCanvas_ = function () {
|
ns.CanvasRenderer.prototype.createCanvas_ = function () {
|
||||||
var width = this.frame.getWidth() * this.dpi;
|
var width = this.frame.getWidth() * this.dpi;
|
||||||
var height = this.frame.getHeight() * this.dpi;
|
var height = this.frame.getHeight() * this.dpi;
|
||||||
return pskl.CanvasUtils.createCanvas(width, height);
|
return pskl.CanvasUtils.createCanvas(width, height);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,61 +1,61 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.rendering");
|
var ns = $.namespace("pskl.rendering");
|
||||||
|
|
||||||
ns.DrawingLoop = function () {
|
ns.DrawingLoop = function () {
|
||||||
this.requestAnimationFrame = this.getRequestAnimationFrameShim_();
|
this.requestAnimationFrame = this.getRequestAnimationFrameShim_();
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
this.previousTime = 0;
|
this.previousTime = 0;
|
||||||
this.callbacks = [];
|
this.callbacks = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.addCallback = function (callback, scope, args) {
|
ns.DrawingLoop.prototype.addCallback = function (callback, scope, args) {
|
||||||
var callbackObj = {
|
var callbackObj = {
|
||||||
fn : callback,
|
fn : callback,
|
||||||
scope : scope,
|
scope : scope,
|
||||||
args : args
|
args : args
|
||||||
};
|
};
|
||||||
this.callbacks.push(callbackObj);
|
this.callbacks.push(callbackObj);
|
||||||
return callbackObj;
|
return callbackObj;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.removeCallback = function (callbackObj) {
|
ns.DrawingLoop.prototype.removeCallback = function (callbackObj) {
|
||||||
var index = this.callbacks.indexOf(callbackObj);
|
var index = this.callbacks.indexOf(callbackObj);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.callbacks.splice(index, 1);
|
this.callbacks.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.start = function () {
|
ns.DrawingLoop.prototype.start = function () {
|
||||||
this.isRunning = true;
|
this.isRunning = true;
|
||||||
this.loop_();
|
this.loop_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.loop_ = function () {
|
ns.DrawingLoop.prototype.loop_ = function () {
|
||||||
var currentTime = Date.now();
|
var currentTime = Date.now();
|
||||||
var delta = currentTime - this.previousTime;
|
var delta = currentTime - this.previousTime;
|
||||||
this.executeCallbacks_(delta);
|
this.executeCallbacks_(delta);
|
||||||
this.previousTime = currentTime;
|
this.previousTime = currentTime;
|
||||||
this.requestAnimationFrame.call(window, this.loop_.bind(this));
|
this.requestAnimationFrame.call(window, this.loop_.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.executeCallbacks_ = function (deltaTime) {
|
ns.DrawingLoop.prototype.executeCallbacks_ = function (deltaTime) {
|
||||||
for (var i = 0 ; i < this.callbacks.length ; i++) {
|
for (var i = 0 ; i < this.callbacks.length ; i++) {
|
||||||
var cb = this.callbacks[i];
|
var cb = this.callbacks[i];
|
||||||
cb.fn.call(cb.scope, deltaTime, cb.args);
|
cb.fn.call(cb.scope, deltaTime, cb.args);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.stop = function () {
|
ns.DrawingLoop.prototype.stop = function () {
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingLoop.prototype.getRequestAnimationFrameShim_ = function () {
|
ns.DrawingLoop.prototype.getRequestAnimationFrameShim_ = function () {
|
||||||
var requestAnimationFrame = window.requestAnimationFrame ||
|
var requestAnimationFrame = window.requestAnimationFrame ||
|
||||||
window.mozRequestAnimationFrame ||
|
window.mozRequestAnimationFrame ||
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
window.msRequestAnimationFrame ||
|
window.msRequestAnimationFrame ||
|
||||||
function (callback) { window.setTimeout(callback, 1000/60); };
|
function (callback) { window.setTimeout(callback, 1000/60); };
|
||||||
|
|
||||||
return requestAnimationFrame;
|
return requestAnimationFrame;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,165 +1,165 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.rendering");
|
var ns = $.namespace("pskl.rendering");
|
||||||
|
|
||||||
ns.FrameRenderer = function (container, renderingOptions, className) {
|
ns.FrameRenderer = function (container, renderingOptions, className) {
|
||||||
this.defaultRenderingOptions = {
|
this.defaultRenderingOptions = {
|
||||||
'supportGridRendering' : false
|
'supportGridRendering' : false
|
||||||
};
|
};
|
||||||
renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions);
|
renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions);
|
||||||
|
|
||||||
if(container === undefined) {
|
if(container === undefined) {
|
||||||
throw 'Bad FrameRenderer initialization. <container> undefined.';
|
throw 'Bad FrameRenderer initialization. <container> undefined.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isNaN(renderingOptions.dpi)) {
|
||||||
|
throw 'Bad FrameRenderer initialization. <dpi> not well defined.';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.container = container;
|
||||||
|
this.dpi = renderingOptions.dpi;
|
||||||
|
this.className = className;
|
||||||
|
this.canvas = null;
|
||||||
|
this.supportGridRendering = renderingOptions.supportGridRendering;
|
||||||
|
|
||||||
|
this.enableGrid(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID));
|
||||||
|
|
||||||
|
// Flag to know if the config was altered
|
||||||
|
this.canvasConfigDirty = true;
|
||||||
|
this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND));
|
||||||
|
$.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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) {
|
||||||
|
|
||||||
|
if(settingName == pskl.UserSettings.SHOW_GRID) {
|
||||||
|
this.enableGrid(settingValue);
|
||||||
|
}
|
||||||
|
else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) {
|
||||||
|
this.updateBackgroundClass_(settingValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) {
|
||||||
|
var currentClass = this.container.data('current-background-class');
|
||||||
|
if (currentClass) {
|
||||||
|
this.container.removeClass(currentClass);
|
||||||
|
}
|
||||||
|
this.container.addClass(newClass);
|
||||||
|
this.container.data('current-background-class', newClass);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.FrameRenderer.prototype.enableGrid = function (flag) {
|
||||||
|
this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0;
|
||||||
|
this.canvasConfigDirty = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
var color = frame.getPixel(col, row);
|
||||||
|
this.renderPixel_(color, col, row, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.lastRenderedFrame = frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.FrameRenderer.prototype.clear = function (frame) {
|
||||||
|
var canvas = this.getCanvas_(frame);
|
||||||
|
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.getFramePos_ = function(index) {
|
||||||
|
return index * this.dpi + ((index - 1) * this.gridStrokeWidth);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.FrameRenderer.prototype.drawGrid_ = function(canvas, width, height, col, row) {
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.lineWidth = Constants.GRID_STROKE_WIDTH;
|
||||||
|
ctx.strokeStyle = Constants.GRID_STROKE_COLOR;
|
||||||
|
for(var c=1; c < col; c++) {
|
||||||
|
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.getFramePos_(r));
|
||||||
|
ctx.lineTo(width, this.getFramePos_(r));
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.FrameRenderer.prototype.getCanvas_ = function (frame) {
|
||||||
|
if(this.canvasConfigDirty) {
|
||||||
|
$(this.canvas).remove();
|
||||||
|
|
||||||
|
var col = frame.getWidth(),
|
||||||
|
row = frame.getHeight();
|
||||||
|
|
||||||
|
var pixelWidth = col * this.dpi + this.gridStrokeWidth * (col - 1);
|
||||||
|
var pixelHeight = row * this.dpi + this.gridStrokeWidth * (row - 1);
|
||||||
|
var classes = ['canvas'];
|
||||||
|
if (this.className) {
|
||||||
|
classes.push(this.className);
|
||||||
|
}
|
||||||
|
var canvas = pskl.CanvasUtils.createCanvas(pixelWidth, pixelHeight, classes);
|
||||||
|
|
||||||
|
this.container.append(canvas);
|
||||||
|
|
||||||
|
if(this.gridStrokeWidth > 0) {
|
||||||
|
this.drawGrid_(canvas, pixelWidth, pixelHeight, col, row);
|
||||||
|
}
|
||||||
|
|
||||||
if(isNaN(renderingOptions.dpi)) {
|
this.canvas = canvas;
|
||||||
throw 'Bad FrameRenderer initialization. <dpi> not well defined.';
|
this.canvasConfigDirty = false;
|
||||||
}
|
}
|
||||||
|
return this.canvas;
|
||||||
this.container = container;
|
};
|
||||||
this.dpi = renderingOptions.dpi;
|
|
||||||
this.className = className;
|
|
||||||
this.canvas = null;
|
|
||||||
this.supportGridRendering = renderingOptions.supportGridRendering;
|
|
||||||
|
|
||||||
this.enableGrid(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID));
|
|
||||||
|
|
||||||
// Flag to know if the config was altered
|
|
||||||
this.canvasConfigDirty = true;
|
|
||||||
this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND));
|
|
||||||
$.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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) {
|
|
||||||
|
|
||||||
if(settingName == pskl.UserSettings.SHOW_GRID) {
|
|
||||||
this.enableGrid(settingValue);
|
|
||||||
}
|
|
||||||
else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) {
|
|
||||||
this.updateBackgroundClass_(settingValue);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) {
|
|
||||||
var currentClass = this.container.data('current-background-class');
|
|
||||||
if (currentClass) {
|
|
||||||
this.container.removeClass(currentClass);
|
|
||||||
}
|
|
||||||
this.container.addClass(newClass);
|
|
||||||
this.container.data('current-background-class', newClass);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.enableGrid = function (flag) {
|
|
||||||
this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0;
|
|
||||||
this.canvasConfigDirty = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
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++) {
|
|
||||||
var color = frame.getPixel(col, row);
|
|
||||||
this.renderPixel_(color, col, row, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.lastRenderedFrame = frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.clear = function (frame) {
|
|
||||||
var canvas = this.getCanvas_(frame);
|
|
||||||
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.getFramePos_ = function(index) {
|
|
||||||
return index * this.dpi + ((index - 1) * this.gridStrokeWidth);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.FrameRenderer.prototype.drawGrid_ = function(canvas, width, height, col, row) {
|
|
||||||
var ctx = canvas.getContext("2d");
|
|
||||||
ctx.lineWidth = Constants.GRID_STROKE_WIDTH;
|
|
||||||
ctx.strokeStyle = Constants.GRID_STROKE_COLOR;
|
|
||||||
for(var c=1; c < col; c++) {
|
|
||||||
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.getFramePos_(r));
|
|
||||||
ctx.lineTo(width, this.getFramePos_(r));
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.FrameRenderer.prototype.getCanvas_ = function (frame) {
|
|
||||||
if(this.canvasConfigDirty) {
|
|
||||||
$(this.canvas).remove();
|
|
||||||
|
|
||||||
var col = frame.getWidth(),
|
|
||||||
row = frame.getHeight();
|
|
||||||
|
|
||||||
var pixelWidth = col * this.dpi + this.gridStrokeWidth * (col - 1);
|
|
||||||
var pixelHeight = row * this.dpi + this.gridStrokeWidth * (row - 1);
|
|
||||||
var classes = ['canvas'];
|
|
||||||
if (this.className) {
|
|
||||||
classes.push(this.className);
|
|
||||||
}
|
|
||||||
var canvas = pskl.CanvasUtils.createCanvas(pixelWidth, pixelHeight, classes);
|
|
||||||
|
|
||||||
this.container.append(canvas);
|
|
||||||
|
|
||||||
if(this.gridStrokeWidth > 0) {
|
|
||||||
this.drawGrid_(canvas, pixelWidth, pixelHeight, col, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.canvas = canvas;
|
|
||||||
this.canvasConfigDirty = false;
|
|
||||||
}
|
|
||||||
return this.canvas;
|
|
||||||
};
|
|
||||||
})();
|
})();
|
@ -1,63 +1,63 @@
|
|||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
var ns = $.namespace("pskl.rendering");
|
var ns = $.namespace("pskl.rendering");
|
||||||
|
|
||||||
ns.SpritesheetRenderer = function (framesheet) {
|
ns.SpritesheetRenderer = function (framesheet) {
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SpritesheetRenderer.prototype.renderAsImageDataSpritesheetPNG = function () {
|
ns.SpritesheetRenderer.prototype.renderAsImageDataSpritesheetPNG = function () {
|
||||||
var canvas = this.createCanvas_();
|
var canvas = this.createCanvas_();
|
||||||
for (var i = 0 ; i < this.framesheet.getFrameCount() ; i++) {
|
for (var i = 0 ; i < this.framesheet.getFrameCount() ; i++) {
|
||||||
var frame = this.framesheet.getFrameByIndex(i);
|
var frame = this.framesheet.getFrameByIndex(i);
|
||||||
this.drawFrameInCanvas_(frame, canvas, i * this.framesheet.getWidth(), 0);
|
this.drawFrameInCanvas_(frame, canvas, i * this.framesheet.getWidth(), 0);
|
||||||
}
|
}
|
||||||
return canvas.toDataURL("image/png");
|
return canvas.toDataURL("image/png");
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SpritesheetRenderer.prototype.renderAsImageDataAnimatedGIF = function (fps) {
|
ns.SpritesheetRenderer.prototype.renderAsImageDataAnimatedGIF = function (fps) {
|
||||||
var encoder = new GIFEncoder(), dpi = 10;
|
var encoder = new GIFEncoder(), dpi = 10;
|
||||||
encoder.setRepeat(0);
|
encoder.setRepeat(0);
|
||||||
encoder.setDelay(1000/fps);
|
encoder.setDelay(1000/fps);
|
||||||
|
|
||||||
encoder.start();
|
encoder.start();
|
||||||
encoder.setSize(this.framesheet.getWidth() * dpi, this.framesheet.getHeight() * dpi);
|
encoder.setSize(this.framesheet.getWidth() * dpi, this.framesheet.getHeight() * dpi);
|
||||||
for (var i = 0 ; i < this.framesheet.frames.length ; i++) {
|
for (var i = 0 ; i < this.framesheet.frames.length ; i++) {
|
||||||
var frame = this.framesheet.frames[i];
|
var frame = this.framesheet.frames[i];
|
||||||
var renderer = new pskl.rendering.CanvasRenderer(frame, dpi);
|
var renderer = new pskl.rendering.CanvasRenderer(frame, dpi);
|
||||||
encoder.addFrame(renderer.render());
|
encoder.addFrame(renderer.render());
|
||||||
|
}
|
||||||
|
encoder.finish();
|
||||||
|
|
||||||
|
var imageData = 'data:image/gif;base64,' + encode64(encoder.stream().getData());
|
||||||
|
return imageData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO(juliandescottes): Mutualize with code already present in FrameRenderer
|
||||||
|
*/
|
||||||
|
ns.SpritesheetRenderer.prototype.drawFrameInCanvas_ = function (frame, canvas, offsetWidth, offsetHeight) {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
for(var col = 0, width = frame.getWidth(); col < width; col++) {
|
||||||
|
for(var row = 0, height = frame.getHeight(); row < height; row++) {
|
||||||
|
var color = frame.getPixel(col, row);
|
||||||
|
if(color != Constants.TRANSPARENT_COLOR) {
|
||||||
|
context.fillStyle = color;
|
||||||
|
context.fillRect(col + offsetWidth, row + offsetHeight, 1, 1);
|
||||||
}
|
}
|
||||||
encoder.finish();
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var imageData = 'data:image/gif;base64,' + encode64(encoder.stream().getData());
|
ns.SpritesheetRenderer.prototype.createCanvas_ = function () {
|
||||||
return imageData;
|
var frameCount = this.framesheet.getFrameCount();
|
||||||
};
|
if (frameCount > 0){
|
||||||
|
var width = frameCount * this.framesheet.getWidth();
|
||||||
|
var height = this.framesheet.getHeight();
|
||||||
/**
|
return pskl.CanvasUtils.createCanvas(width, height);
|
||||||
* TODO(juliandescottes): Mutualize with code already present in FrameRenderer
|
} else {
|
||||||
*/
|
throw "Cannot render empty Spritesheet";
|
||||||
ns.SpritesheetRenderer.prototype.drawFrameInCanvas_ = function (frame, canvas, offsetWidth, offsetHeight) {
|
}
|
||||||
var context = canvas.getContext('2d');
|
};
|
||||||
for(var col = 0, width = frame.getWidth(); col < width; col++) {
|
|
||||||
for(var row = 0, height = frame.getHeight(); row < height; row++) {
|
|
||||||
var color = frame.getPixel(col, row);
|
|
||||||
if(color != Constants.TRANSPARENT_COLOR) {
|
|
||||||
context.fillStyle = color;
|
|
||||||
context.fillRect(col + offsetWidth, row + offsetHeight, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SpritesheetRenderer.prototype.createCanvas_ = function () {
|
|
||||||
var frameCount = this.framesheet.getFrameCount();
|
|
||||||
if (frameCount > 0){
|
|
||||||
var width = frameCount * this.framesheet.getWidth();
|
|
||||||
var height = this.framesheet.getHeight();
|
|
||||||
return pskl.CanvasUtils.createCanvas(width, height);
|
|
||||||
} else {
|
|
||||||
throw "Cannot render empty Spritesheet";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
})();
|
@ -1,34 +1,34 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.selection");
|
var ns = $.namespace("pskl.selection");
|
||||||
|
|
||||||
ns.BaseSelection = function () {
|
ns.BaseSelection = function () {
|
||||||
this.reset();
|
this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseSelection.prototype.reset = function () {
|
ns.BaseSelection.prototype.reset = function () {
|
||||||
this.pixels = [];
|
this.pixels = [];
|
||||||
this.hasPastedContent = false;
|
this.hasPastedContent = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseSelection.prototype.move = function (colDiff, rowDiff) {
|
ns.BaseSelection.prototype.move = function (colDiff, rowDiff) {
|
||||||
var movedPixel, movedPixels = [];
|
var movedPixel, movedPixels = [];
|
||||||
|
|
||||||
for(var i=0, l=this.pixels.length; i<l; i++) {
|
for(var i=0, l=this.pixels.length; i<l; i++) {
|
||||||
movedPixel = this.pixels[i];
|
movedPixel = this.pixels[i];
|
||||||
movedPixel.col += colDiff;
|
movedPixel.col += colDiff;
|
||||||
movedPixel.row += rowDiff;
|
movedPixel.row += rowDiff;
|
||||||
movedPixels.push(movedPixel);
|
movedPixels.push(movedPixel);
|
||||||
}
|
}
|
||||||
this.pixels = movedPixels;
|
this.pixels = movedPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseSelection.prototype.fillSelectionFromFrame = function (targetFrame) {
|
ns.BaseSelection.prototype.fillSelectionFromFrame = function (targetFrame) {
|
||||||
var pixelWithCopiedColor;
|
var pixelWithCopiedColor;
|
||||||
for(var i=0, l=this.pixels.length; i<l; i++) {
|
for(var i=0, l=this.pixels.length; i<l; i++) {
|
||||||
pixelWithCopiedColor = this.pixels[i];
|
pixelWithCopiedColor = this.pixels[i];
|
||||||
pixelWithCopiedColor.copiedColor =
|
pixelWithCopiedColor.copiedColor =
|
||||||
targetFrame.getPixel(pixelWithCopiedColor.col, pixelWithCopiedColor.row);
|
targetFrame.getPixel(pixelWithCopiedColor.col, pixelWithCopiedColor.row);
|
||||||
}
|
}
|
||||||
this.hasPastedContent = true;
|
this.hasPastedContent = true;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,9 +1,9 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.selection");
|
var ns = $.namespace("pskl.selection");
|
||||||
|
|
||||||
ns.RectangularSelection = function (x0, y0, x1, y1) {
|
ns.RectangularSelection = function (x0, y0, x1, y1) {
|
||||||
this.pixels = pskl.PixelUtils.getRectanglePixels(x0, y0, x1, y1);
|
this.pixels = pskl.PixelUtils.getRectanglePixels(x0, y0, x1, y1);
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.RectangularSelection, ns.BaseSelection);
|
pskl.utils.inherit(ns.RectangularSelection, ns.BaseSelection);
|
||||||
})();
|
})();
|
@ -1,130 +1,130 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.selection");
|
var ns = $.namespace("pskl.selection");
|
||||||
|
|
||||||
|
|
||||||
ns.SelectionManager = function (framesheet, overlayFrame) {
|
ns.SelectionManager = function (framesheet, overlayFrame) {
|
||||||
|
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
this.overlayFrame = overlayFrame;
|
this.overlayFrame = overlayFrame;
|
||||||
|
|
||||||
this.currentSelection = null;
|
this.currentSelection = null;
|
||||||
|
|
||||||
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
|
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
|
||||||
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
|
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
|
||||||
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
|
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
|
||||||
|
|
||||||
$.subscribe(Events.PASTE, $.proxy(this.onPaste_, this));
|
$.subscribe(Events.PASTE, $.proxy(this.onPaste_, this));
|
||||||
$.subscribe(Events.COPY, $.proxy(this.onCopy_, this));
|
$.subscribe(Events.COPY, $.proxy(this.onCopy_, this));
|
||||||
$.subscribe(Events.CUT, $.proxy(this.onCut_, this));
|
$.subscribe(Events.CUT, $.proxy(this.onCut_, this));
|
||||||
|
|
||||||
$.subscribe(Events.TOOL_SELECTED, $.proxy(this.onToolSelected_, this));
|
$.subscribe(Events.TOOL_SELECTED, $.proxy(this.onToolSelected_, this));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.cleanSelection_ = function(selection) {
|
ns.SelectionManager.prototype.cleanSelection_ = function(selection) {
|
||||||
if(this.currentSelection) {
|
if(this.currentSelection) {
|
||||||
this.currentSelection.reset();
|
this.currentSelection.reset();
|
||||||
}
|
}
|
||||||
this.overlayFrame.clear();
|
this.overlayFrame.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onToolSelected_ = function(evt, tool) {
|
ns.SelectionManager.prototype.onToolSelected_ = function(evt, tool) {
|
||||||
var isSelectionTool = tool instanceof pskl.drawingtools.BaseSelect;
|
var isSelectionTool = tool instanceof pskl.drawingtools.BaseSelect;
|
||||||
if(!isSelectionTool) {
|
if(!isSelectionTool) {
|
||||||
this.cleanSelection_();
|
this.cleanSelection_();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onSelectionDismissed_ = function(evt) {
|
ns.SelectionManager.prototype.onSelectionDismissed_ = function(evt) {
|
||||||
this.cleanSelection_();
|
this.cleanSelection_();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onCut_ = function(evt) {
|
ns.SelectionManager.prototype.onCut_ = function(evt) {
|
||||||
if(this.currentSelection) {
|
if(this.currentSelection) {
|
||||||
// Put cut target into the selection:
|
// Put cut target into the selection:
|
||||||
this.currentSelection.fillSelectionFromFrame(this.framesheet.getCurrentFrame());
|
this.currentSelection.fillSelectionFromFrame(this.framesheet.getCurrentFrame());
|
||||||
|
|
||||||
var pixels = this.currentSelection.pixels;
|
var pixels = this.currentSelection.pixels;
|
||||||
var currentFrame = this.framesheet.getCurrentFrame();
|
var currentFrame = this.framesheet.getCurrentFrame();
|
||||||
for(var i=0, l=pixels.length; i<l; i++) {
|
for(var i=0, l=pixels.length; i<l; i++) {
|
||||||
try {
|
try {
|
||||||
currentFrame.setPixel(pixels[i].col, pixels[i].row, Constants.TRANSPARENT_COLOR);
|
currentFrame.setPixel(pixels[i].col, pixels[i].row, Constants.TRANSPARENT_COLOR);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
// Catchng out of frame's bound pixels without testing
|
// Catchng out of frame's bound pixels without testing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "Bad state for CUT callback in SelectionManager";
|
throw "Bad state for CUT callback in SelectionManager";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SelectionManager.prototype.onPaste_ = function(evt) {
|
ns.SelectionManager.prototype.onPaste_ = function(evt) {
|
||||||
if(this.currentSelection && this.currentSelection.hasPastedContent) {
|
if(this.currentSelection && this.currentSelection.hasPastedContent) {
|
||||||
var pixels = this.currentSelection.pixels;
|
var pixels = this.currentSelection.pixels;
|
||||||
var currentFrame = this.framesheet.getCurrentFrame();
|
var currentFrame = this.framesheet.getCurrentFrame();
|
||||||
for(var i=0, l=pixels.length; i<l; i++) {
|
for(var i=0, l=pixels.length; i<l; i++) {
|
||||||
try {
|
try {
|
||||||
currentFrame.setPixel(
|
currentFrame.setPixel(
|
||||||
pixels[i].col, pixels[i].row,
|
pixels[i].col, pixels[i].row,
|
||||||
pixels[i].copiedColor);
|
pixels[i].copiedColor);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
// Catchng out of frame's bound pixels without testing
|
// Catchng out of frame's bound pixels without testing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onCopy_ = function(evt) {
|
ns.SelectionManager.prototype.onCopy_ = function(evt) {
|
||||||
if(this.currentSelection && this.framesheet.getCurrentFrame()) {
|
if(this.currentSelection && this.framesheet.getCurrentFrame()) {
|
||||||
this.currentSelection.fillSelectionFromFrame(this.framesheet.getCurrentFrame());
|
this.currentSelection.fillSelectionFromFrame(this.framesheet.getCurrentFrame());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "Bad state for CUT callback in SelectionManager";
|
throw "Bad state for CUT callback in SelectionManager";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onSelectionCreated_ = function(evt, selection) {
|
ns.SelectionManager.prototype.onSelectionCreated_ = function(evt, selection) {
|
||||||
if(selection) {
|
if(selection) {
|
||||||
this.currentSelection = selection;
|
this.currentSelection = selection;
|
||||||
var pixels = selection.pixels;
|
var pixels = selection.pixels;
|
||||||
for(var i=0, l=pixels.length; i<l; i++) {
|
for(var i=0, l=pixels.length; i<l; i++) {
|
||||||
this.overlayFrame.setPixel(pixels[i].col, pixels[i].row, Constants.SELECTION_TRANSPARENT_COLOR);
|
this.overlayFrame.setPixel(pixels[i].col, pixels[i].row, Constants.SELECTION_TRANSPARENT_COLOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "No selection set in SelectionManager";
|
throw "No selection set in SelectionManager";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.SelectionManager.prototype.onSelectionMoved_ = function(evt, colDiff, rowDiff) {
|
ns.SelectionManager.prototype.onSelectionMoved_ = function(evt, colDiff, rowDiff) {
|
||||||
if(this.currentSelection) {
|
if(this.currentSelection) {
|
||||||
this.currentSelection.move(colDiff, rowDiff);
|
this.currentSelection.move(colDiff, rowDiff);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "Bad state: No currentSelection set when trying to move it in SelectionManager";
|
throw "Bad state: No currentSelection set when trying to move it in SelectionManager";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.selection");
|
var ns = $.namespace("pskl.selection");
|
||||||
|
|
||||||
ns.ShapeSelection = function (pixels) {
|
ns.ShapeSelection = function (pixels) {
|
||||||
this.pixels = pixels;
|
this.pixels = pixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.ShapeSelection, ns.BaseSelection);
|
pskl.utils.inherit(ns.ShapeSelection, ns.BaseSelection);
|
||||||
})();
|
})();
|
@ -1,15 +1,15 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.service");
|
var ns = $.namespace("pskl.service");
|
||||||
ns.HistoryService = function (framesheet) {
|
ns.HistoryService = function (framesheet) {
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.init = function () {
|
ns.HistoryService.prototype.init = function () {
|
||||||
|
|
||||||
$.subscribe(Events.TOOL_RELEASED, this.saveState.bind(this));
|
$.subscribe(Events.TOOL_RELEASED, this.saveState.bind(this));
|
||||||
$.subscribe(Events.UNDO, this.undo.bind(this));
|
$.subscribe(Events.UNDO, this.undo.bind(this));
|
||||||
$.subscribe(Events.REDO, this.redo.bind(this));
|
$.subscribe(Events.REDO, this.redo.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryService.prototype.saveState = function () {
|
ns.HistoryService.prototype.saveState = function () {
|
||||||
this.framesheet.getCurrentFrame().saveState();
|
this.framesheet.getCurrentFrame().saveState();
|
||||||
|
@ -1,64 +1,64 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.service");
|
var ns = $.namespace("pskl.service");
|
||||||
|
|
||||||
ns.KeyboardEventService = function () {};
|
ns.KeyboardEventService = function () {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.KeyboardEventService.prototype.KeyboardActions_ = {
|
ns.KeyboardEventService.prototype.KeyboardActions_ = {
|
||||||
|
|
||||||
"ctrl" : {
|
"ctrl" : {
|
||||||
"z" : Events.UNDO,
|
"z" : Events.UNDO,
|
||||||
"y" : Events.REDO,
|
"y" : Events.REDO,
|
||||||
"x" : Events.CUT,
|
"x" : Events.CUT,
|
||||||
"c" : Events.COPY,
|
"c" : Events.COPY,
|
||||||
"v" : Events.PASTE
|
"v" : Events.PASTE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.KeyboardEventService.prototype.CharCodeToKeyCodeMap_ = {
|
ns.KeyboardEventService.prototype.CharCodeToKeyCodeMap_ = {
|
||||||
|
|
||||||
90 : "z",
|
90 : "z",
|
||||||
89 : "y",
|
89 : "y",
|
||||||
88 : "x",
|
88 : "x",
|
||||||
67 : "c",
|
67 : "c",
|
||||||
86 : "v"
|
86 : "v"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.KeyboardEventService.prototype.onKeyUp_ = function(evt) {
|
ns.KeyboardEventService.prototype.onKeyUp_ = function(evt) {
|
||||||
var isMac = false;
|
var isMac = false;
|
||||||
if (navigator.appVersion.indexOf("Mac")!=-1) {
|
if (navigator.appVersion.indexOf("Mac")!=-1) {
|
||||||
// Welcome in mac world where vowels are consons and meta used instead of ctrl:
|
// Welcome in mac world where vowels are consons and meta used instead of ctrl:
|
||||||
isMac = true;
|
isMac = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMac ? evt.metaKey : evt.ctrlKey) {
|
if (isMac ? evt.metaKey : evt.ctrlKey) {
|
||||||
// Get key pressed:
|
// Get key pressed:
|
||||||
var letter = this.CharCodeToKeyCodeMap_[evt.which];
|
var letter = this.CharCodeToKeyCodeMap_[evt.which];
|
||||||
if(letter) {
|
if(letter) {
|
||||||
var eventToTrigger = this.KeyboardActions_.ctrl[letter];
|
var eventToTrigger = this.KeyboardActions_.ctrl[letter];
|
||||||
if(eventToTrigger) {
|
if(eventToTrigger) {
|
||||||
$.publish(eventToTrigger);
|
$.publish(eventToTrigger);
|
||||||
|
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
ns.KeyboardEventService.prototype.init = function() {
|
ns.KeyboardEventService.prototype.init = function() {
|
||||||
$(document.body).keydown($.proxy(this.onKeyUp_, this));
|
$(document.body).keydown($.proxy(this.onKeyUp_, this));
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
@ -4,7 +4,7 @@
|
|||||||
ns.LocalStorageService = function (framesheet_) {
|
ns.LocalStorageService = function (framesheet_) {
|
||||||
|
|
||||||
if(framesheet_ === undefined) {
|
if(framesheet_ === undefined) {
|
||||||
throw "Bad LocalStorageService initialization: <undefined frameSheet>";
|
throw "Bad LocalStorageService initialization: <undefined frameSheet>";
|
||||||
}
|
}
|
||||||
this.framesheet = framesheet_;
|
this.framesheet = framesheet_;
|
||||||
this.localStorageThrottler_ = null;
|
this.localStorageThrottler_ = null;
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl");
|
var ns = $.namespace("pskl");
|
||||||
|
|
||||||
ns.CanvasUtils = {
|
ns.CanvasUtils = {
|
||||||
createCanvas : function (width, height, classList) {
|
createCanvas : function (width, height, classList) {
|
||||||
var canvas = document.createElement("canvas");
|
var canvas = document.createElement("canvas");
|
||||||
canvas.setAttribute("width", width);
|
canvas.setAttribute("width", width);
|
||||||
canvas.setAttribute("height", height);
|
canvas.setAttribute("height", height);
|
||||||
|
|
||||||
if (typeof classList == "string") {
|
if (typeof classList == "string") {
|
||||||
classList = [classList];
|
classList = [classList];
|
||||||
}
|
}
|
||||||
if (Array.isArray(classList)) {
|
if (Array.isArray(classList)) {
|
||||||
for (var i = 0 ; i < classList.length ; i++) {
|
for (var i = 0 ; i < classList.length ; i++) {
|
||||||
canvas.classList.add(classList[i]);
|
canvas.classList.add(classList[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,175 +1,177 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl");
|
var ns = $.namespace("pskl");
|
||||||
|
|
||||||
ns.PixelUtils = {
|
ns.PixelUtils = {
|
||||||
|
|
||||||
getRectanglePixels : function (x0, y0, x1, y1) {
|
getRectanglePixels : function (x0, y0, x1, y1) {
|
||||||
var rectangle = this.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
var rectangle = this.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
||||||
var pixels = [];
|
var pixels = [];
|
||||||
|
|
||||||
for(var x = rectangle.x0; x <= rectangle.x1; x++) {
|
for(var x = rectangle.x0; x <= rectangle.x1; x++) {
|
||||||
for(var y = rectangle.y0; y <= rectangle.y1; y++) {
|
for(var y = rectangle.y0; y <= rectangle.y1; y++) {
|
||||||
pixels.push({"col": x, "row": y});
|
pixels.push({"col": x, "row": y});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixels;
|
||||||
|
},
|
||||||
|
|
||||||
|
getBoundRectanglePixels : function (x0, y0, x1, y1) {
|
||||||
|
var rectangle = this.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
||||||
|
var pixels = [];
|
||||||
|
// Creating horizontal sides of the rectangle:
|
||||||
|
for(var x = rectangle.x0; x <= rectangle.x1; x++) {
|
||||||
|
pixels.push({"col": x, "row": rectangle.y0});
|
||||||
|
pixels.push({"col": x, "row": rectangle.y1});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating vertical sides of the rectangle:
|
||||||
|
for(var y = rectangle.y0; y <= rectangle.y1; y++) {
|
||||||
|
pixels.push({"col": rectangle.x0, "row": y});
|
||||||
|
pixels.push({"col": rectangle.x1, "row": y});
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixels;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an object of ordered rectangle coordinate.
|
||||||
|
* In returned object {x0, y0} => top left corner - {x1, y1} => bottom right corner
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
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),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of pixels that would have been filled by a paintbucket tool applied
|
||||||
|
* on pixel at coordinate (x,y).
|
||||||
|
* This function is not altering the Frame object argument.
|
||||||
|
*
|
||||||
|
* @param frame pskl.model.Frame The frame target in which we want to paintbucket
|
||||||
|
* @param col number Column coordinate in the frame
|
||||||
|
* @param row number Row coordinate in the frame
|
||||||
|
*
|
||||||
|
* @return an array of the pixel coordinates paint with the replacement color
|
||||||
|
*/
|
||||||
|
getSimilarConnectedPixelsFromFrame: function(frame, col, row) {
|
||||||
|
// To get the list of connected (eg the same color) pixels, we will use the paintbucket algorithm
|
||||||
|
// in a fake cloned frame. The returned pixels by the paintbucket algo are the painted pixels
|
||||||
|
// and are as well connected.
|
||||||
|
var fakeFrame = frame.clone(); // We just want to
|
||||||
|
var fakeFillColor = "sdfsdfsdf"; // A fake color that will never match a real color.
|
||||||
|
var paintedPixels = this.paintSimilarConnectedPixelsFromFrame(fakeFrame, col, row, fakeFillColor);
|
||||||
|
|
||||||
|
return paintedPixels;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the paintbucket tool in a frame at the (col, row) initial position
|
||||||
|
* with the replacement color.
|
||||||
|
*
|
||||||
|
* @param frame pskl.model.Frame The frame target in which we want to paintbucket
|
||||||
|
* @param col number Column coordinate in the frame
|
||||||
|
* @param row number Row coordinate in the frame
|
||||||
|
* @param replacementColor string Hexadecimal color used to fill the area
|
||||||
|
*
|
||||||
|
* @return an array of the pixel coordinates paint with the replacement color
|
||||||
|
*/
|
||||||
|
paintSimilarConnectedPixelsFromFrame: function(frame, col, row, replacementColor) {
|
||||||
|
/**
|
||||||
|
* Queue linear Flood-fill (node, target-color, replacement-color):
|
||||||
|
* 1. Set Q to the empty queue.
|
||||||
|
* 2. If the color of node is not equal to target-color, return.
|
||||||
|
* 3. Add node to Q.
|
||||||
|
* 4. For each element n of Q:
|
||||||
|
* 5. If the color of n is equal to target-color:
|
||||||
|
* 6. Set w and e equal to n.
|
||||||
|
* 7. Move w to the west until the color of the node to the west of w no longer matches target-color.
|
||||||
|
* 8. Move e to the east until the color of the node to the east of e no longer matches target-color.
|
||||||
|
* 9. Set the color of nodes between w and e to replacement-color.
|
||||||
|
* 10. For each node n between w and e:
|
||||||
|
* 11. If the color of the node to the north of n is target-color, add that node to Q.
|
||||||
|
* 12. If the color of the node to the south of n is target-color, add that node to Q.
|
||||||
|
* 13. Continue looping until Q is exhausted.
|
||||||
|
* 14. Return.
|
||||||
|
*/
|
||||||
|
var paintedPixels = [];
|
||||||
|
var queue = [];
|
||||||
|
var dy = [-1, 0, 1, 0];
|
||||||
|
var dx = [0, 1, 0, -1];
|
||||||
|
var targetColor;
|
||||||
|
try {
|
||||||
|
targetColor = frame.getPixel(col, row);
|
||||||
|
} catch(e) {
|
||||||
|
// Frame out of bound exception.
|
||||||
|
}
|
||||||
|
|
||||||
|
if(targetColor == replacementColor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
queue.push({"col": col, "row": row});
|
||||||
|
var loopCount = 0;
|
||||||
|
var cellCount = frame.getWidth() * frame.getHeight();
|
||||||
|
while(queue.length > 0) {
|
||||||
|
loopCount ++;
|
||||||
|
|
||||||
|
var currentItem = queue.pop();
|
||||||
|
frame.setPixel(currentItem.col, currentItem.row, replacementColor);
|
||||||
|
paintedPixels.push({"col": currentItem.col, "row": currentItem.row });
|
||||||
|
|
||||||
|
for (var i = 0; i < 4; i++) {
|
||||||
|
var nextCol = currentItem.col + dx[i];
|
||||||
|
var nextRow = currentItem.row + dy[i];
|
||||||
|
try {
|
||||||
|
if (frame.containsPixel(nextCol, nextRow) && frame.getPixel(nextCol, nextRow) == targetColor) {
|
||||||
|
queue.push({"col": nextCol, "row": nextRow });
|
||||||
}
|
}
|
||||||
|
} catch(e) {
|
||||||
return pixels;
|
// Frame out of bound exception.
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getBoundRectanglePixels : function (x0, y0, x1, y1) {
|
// Security loop breaker:
|
||||||
var rectangle = this.getOrderedRectangleCoordinates(x0, y0, x1, y1);
|
if(loopCount > 10 * cellCount) {
|
||||||
var pixels = [];
|
console.log("loop breaker called");
|
||||||
// Creating horizontal sides of the rectangle:
|
break;
|
||||||
for(var x = rectangle.x0; x <= rectangle.x1; x++) {
|
}
|
||||||
pixels.push({"col": x, "row": rectangle.y0});
|
}
|
||||||
pixels.push({"col": x, "row": rectangle.y1});
|
return paintedPixels;
|
||||||
}
|
},
|
||||||
|
|
||||||
// Creating vertical sides of the rectangle:
|
/**
|
||||||
for(var y = rectangle.y0; y <= rectangle.y1; y++) {
|
* Calculate and return the maximal DPI to display a picture in a given container.
|
||||||
pixels.push({"col": rectangle.x0, "row": y});
|
*
|
||||||
pixels.push({"col": rectangle.x1, "row": y});
|
* @param container jQueryObject Container where the picture should be displayed
|
||||||
}
|
* @param number pictureHeight height in pixels of the picture to display
|
||||||
|
* @param number pictureWidth width in pixels of the picture to display
|
||||||
return pixels;
|
* @return number maximal dpi
|
||||||
},
|
*/
|
||||||
|
calculateDPIForContainer : function (container, pictureHeight, pictureWidth) {
|
||||||
|
return this.calculateDPI(container.height(), container.width(), pictureHeight, pictureWidth);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an object of ordered rectangle coordinate.
|
* Calculate and return the maximal DPI to display a picture for a given height and width.
|
||||||
* In returned object {x0, y0} => top left corner - {x1, y1} => bottom right corner
|
*
|
||||||
* @private
|
* @param height number Height available to display the picture
|
||||||
*/
|
* @param width number Width available to display the picture
|
||||||
getOrderedRectangleCoordinates : function (x0, y0, x1, y1) {
|
* @param number pictureHeight height in pixels of the picture to display
|
||||||
return {
|
* @param number pictureWidth width in pixels of the picture to display
|
||||||
x0 : Math.min(x0, x1), y0 : Math.min(y0, y1),
|
* @return number maximal dpi
|
||||||
x1 : Math.max(x0, x1), y1 : Math.max(y0, y1),
|
*/
|
||||||
};
|
calculateDPI : function (height, width, pictureHeight, pictureWidth) {
|
||||||
},
|
var heightBoundDpi = Math.floor(height / pictureHeight),
|
||||||
|
widthBoundDpi = Math.floor(width / pictureWidth);
|
||||||
|
|
||||||
/**
|
return Math.min(heightBoundDpi, widthBoundDpi);
|
||||||
* Return the list of pixels that would have been filled by a paintbucket tool applied
|
},
|
||||||
* on pixel at coordinate (x,y).
|
};
|
||||||
* This function is not altering the Frame object argument.
|
|
||||||
*
|
|
||||||
* @param frame pskl.model.Frame The frame target in which we want to paintbucket
|
|
||||||
* @param col number Column coordinate in the frame
|
|
||||||
* @param row number Row coordinate in the frame
|
|
||||||
*
|
|
||||||
* @return an array of the pixel coordinates paint with the replacement color
|
|
||||||
*/
|
|
||||||
getSimilarConnectedPixelsFromFrame: function(frame, col, row) {
|
|
||||||
// To get the list of connected (eg the same color) pixels, we will use the paintbucket algorithm
|
|
||||||
// in a fake cloned frame. The returned pixels by the paintbucket algo are the painted pixels
|
|
||||||
// and are as well connected.
|
|
||||||
var fakeFrame = frame.clone(); // We just want to
|
|
||||||
var fakeFillColor = "sdfsdfsdf"; // A fake color that will never match a real color.
|
|
||||||
var paintedPixels = this.paintSimilarConnectedPixelsFromFrame(fakeFrame, col, row, fakeFillColor);
|
|
||||||
|
|
||||||
return paintedPixels;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the paintbucket tool in a frame at the (col, row) initial position
|
|
||||||
* with the replacement color.
|
|
||||||
*
|
|
||||||
* @param frame pskl.model.Frame The frame target in which we want to paintbucket
|
|
||||||
* @param col number Column coordinate in the frame
|
|
||||||
* @param row number Row coordinate in the frame
|
|
||||||
* @param replacementColor string Hexadecimal color used to fill the area
|
|
||||||
*
|
|
||||||
* @return an array of the pixel coordinates paint with the replacement color
|
|
||||||
*/
|
|
||||||
paintSimilarConnectedPixelsFromFrame: function(frame, col, row, replacementColor) {
|
|
||||||
/**
|
|
||||||
* Queue linear Flood-fill (node, target-color, replacement-color):
|
|
||||||
* 1. Set Q to the empty queue.
|
|
||||||
* 2. If the color of node is not equal to target-color, return.
|
|
||||||
* 3. Add node to Q.
|
|
||||||
* 4. For each element n of Q:
|
|
||||||
* 5. If the color of n is equal to target-color:
|
|
||||||
* 6. Set w and e equal to n.
|
|
||||||
* 7. Move w to the west until the color of the node to the west of w no longer matches target-color.
|
|
||||||
* 8. Move e to the east until the color of the node to the east of e no longer matches target-color.
|
|
||||||
* 9. Set the color of nodes between w and e to replacement-color.
|
|
||||||
* 10. For each node n between w and e:
|
|
||||||
* 11. If the color of the node to the north of n is target-color, add that node to Q.
|
|
||||||
* 12. If the color of the node to the south of n is target-color, add that node to Q.
|
|
||||||
* 13. Continue looping until Q is exhausted.
|
|
||||||
* 14. Return.
|
|
||||||
*/
|
|
||||||
var paintedPixels = [];
|
|
||||||
var queue = [];
|
|
||||||
var dy = [-1, 0, 1, 0];
|
|
||||||
var dx = [0, 1, 0, -1];
|
|
||||||
var targetColor;
|
|
||||||
try {
|
|
||||||
targetColor = frame.getPixel(col, row);
|
|
||||||
} catch(e) {
|
|
||||||
// Frame out of bound exception.
|
|
||||||
}
|
|
||||||
|
|
||||||
if(targetColor == replacementColor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
queue.push({"col": col, "row": row});
|
|
||||||
var loopCount = 0;
|
|
||||||
var cellCount = frame.getWidth() * frame.getHeight();
|
|
||||||
while(queue.length > 0) {
|
|
||||||
loopCount ++;
|
|
||||||
|
|
||||||
var currentItem = queue.pop();
|
|
||||||
frame.setPixel(currentItem.col, currentItem.row, replacementColor);
|
|
||||||
paintedPixels.push({"col": currentItem.col, "row": currentItem.row });
|
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++) {
|
|
||||||
var nextCol = currentItem.col + dx[i];
|
|
||||||
var nextRow = currentItem.row + dy[i];
|
|
||||||
try {
|
|
||||||
if (frame.containsPixel(nextCol, nextRow) && frame.getPixel(nextCol, nextRow) == targetColor) {
|
|
||||||
queue.push({"col": nextCol, "row": nextRow });
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
// Frame out of bound exception.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security loop breaker:
|
|
||||||
if(loopCount > 10 * cellCount) {
|
|
||||||
console.log("loop breaker called");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return paintedPixels;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate and return the maximal DPI to display a picture in a given container.
|
|
||||||
*
|
|
||||||
* @param container jQueryObject Container where the picture should be displayed
|
|
||||||
* @param number pictureHeight height in pixels of the picture to display
|
|
||||||
* @param number pictureWidth width in pixels of the picture to display
|
|
||||||
* @return number maximal dpi
|
|
||||||
*/
|
|
||||||
calculateDPIForContainer : function (container, pictureHeight, pictureWidth) {
|
|
||||||
return this.calculateDPI(container.height(), container.width(), pictureHeight, pictureWidth);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate and return the maximal DPI to display a picture for a given height and width.
|
|
||||||
*
|
|
||||||
* @param height number Height available to display the picture
|
|
||||||
* @param width number Width available to display the picture
|
|
||||||
* @param number pictureHeight height in pixels of the picture to display
|
|
||||||
* @param number pictureWidth width in pixels of the picture to display
|
|
||||||
* @return number maximal dpi
|
|
||||||
*/
|
|
||||||
calculateDPI : function (height, width, pictureHeight, pictureWidth) {
|
|
||||||
var heightBoundDpi = Math.floor(height / pictureHeight),
|
|
||||||
widthBoundDpi = Math.floor(width / pictureWidth);
|
|
||||||
|
|
||||||
return Math.min(heightBoundDpi, widthBoundDpi);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
})();
|
})();
|
@ -1,76 +1,76 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl");
|
var ns = $.namespace("pskl");
|
||||||
|
|
||||||
ns.UserSettings = {
|
ns.UserSettings = {
|
||||||
|
|
||||||
SHOW_GRID : 'SHOW_GRID',
|
SHOW_GRID : 'SHOW_GRID',
|
||||||
CANVAS_BACKGROUND : 'CANVAS_BACKGROUND',
|
CANVAS_BACKGROUND : 'CANVAS_BACKGROUND',
|
||||||
|
|
||||||
KEY_TO_DEFAULT_VALUE_MAP_ : {
|
KEY_TO_DEFAULT_VALUE_MAP_ : {
|
||||||
'SHOW_GRID' : false,
|
'SHOW_GRID' : false,
|
||||||
'CANVAS_BACKGROUND' : 'medium-canvas-background'
|
'CANVAS_BACKGROUND' : 'medium-canvas-background'
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
cache_ : {},
|
cache_ : {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method to access a user defined settings value ot its default
|
* Static method to access a user defined settings value ot its default
|
||||||
* value if not defined yet.
|
* value if not defined yet.
|
||||||
*/
|
*/
|
||||||
get : function (key) {
|
get : function (key) {
|
||||||
this.checkKeyValidity_(key);
|
this.checkKeyValidity_(key);
|
||||||
if (!(key in this.cache_)) {
|
if (!(key in this.cache_)) {
|
||||||
this.cache_[key] =
|
this.cache_[key] =
|
||||||
this.readFromLocalStorage_(key) || this.readFromDefaults_(key);
|
this.readFromLocalStorage_(key) || this.readFromDefaults_(key);
|
||||||
}
|
}
|
||||||
return this.cache_[key];
|
return this.cache_[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
set : function (key, value) {
|
set : function (key, value) {
|
||||||
this.checkKeyValidity_(key);
|
this.checkKeyValidity_(key);
|
||||||
this.cache_[key] = value;
|
this.cache_[key] = value;
|
||||||
this.writeToLocalStorage_(key, value);
|
this.writeToLocalStorage_(key, value);
|
||||||
|
|
||||||
$.publish(Events.USER_SETTINGS_CHANGED, [key, value]);
|
$.publish(Events.USER_SETTINGS_CHANGED, [key, value]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
readFromLocalStorage_ : function(key) {
|
readFromLocalStorage_ : function(key) {
|
||||||
var value = window.localStorage[key];
|
var value = window.localStorage[key];
|
||||||
if (typeof value != "undefined") {
|
if (typeof value != "undefined") {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
writeToLocalStorage_ : function(key, value) {
|
writeToLocalStorage_ : function(key, value) {
|
||||||
// TODO(grosbouddha): Catch storage exception here.
|
// TODO(grosbouddha): Catch storage exception here.
|
||||||
window.localStorage[key] = JSON.stringify(value);
|
window.localStorage[key] = JSON.stringify(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
readFromDefaults_ : function (key) {
|
readFromDefaults_ : function (key) {
|
||||||
return this.KEY_TO_DEFAULT_VALUE_MAP_[key];
|
return this.KEY_TO_DEFAULT_VALUE_MAP_[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
checkKeyValidity_ : function(key) {
|
checkKeyValidity_ : function(key) {
|
||||||
if(!(key in this.KEY_TO_DEFAULT_VALUE_MAP_)) {
|
if(!(key in this.KEY_TO_DEFAULT_VALUE_MAP_)) {
|
||||||
// TODO(grosbouddha): Define error catching strategy and throw exception from here.
|
// TODO(grosbouddha): Define error catching strategy and throw exception from here.
|
||||||
console.log("UserSettings key <"+ key +"> not find in supported keys.");
|
console.log("UserSettings key <"+ key +"> not find in supported keys.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
@ -1,14 +1,14 @@
|
|||||||
jQuery.namespace = function() {
|
jQuery.namespace = function() {
|
||||||
var a=arguments, o=null, i, j, d;
|
var a=arguments, o=null, i, j, d;
|
||||||
for (i=0; i<a.length; i=i+1) {
|
for (i=0; i<a.length; i=i+1) {
|
||||||
d=a[i].split(".");
|
d=a[i].split(".");
|
||||||
o=window;
|
o=window;
|
||||||
for (j=0; j<d.length; j=j+1) {
|
for (j=0; j<d.length; j=j+1) {
|
||||||
o[d[j]]=o[d[j]] || {};
|
o[d[j]]=o[d[j]] || {};
|
||||||
o=o[d[j]];
|
o=o[d[j]];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return o;
|
}
|
||||||
|
return o;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -18,19 +18,19 @@ jQuery.namespace = function() {
|
|||||||
*/
|
*/
|
||||||
(function() { // namespace: pskl.utils
|
(function() { // namespace: pskl.utils
|
||||||
|
|
||||||
var ns = $.namespace("pskl.utils");
|
var ns = $.namespace("pskl.utils");
|
||||||
|
|
||||||
ns.rgbToHex = function(r, g, b) {
|
ns.rgbToHex = function(r, g, b) {
|
||||||
if (r > 255 || g > 255 || b > 255)
|
if (r > 255 || g > 255 || b > 255)
|
||||||
throw "Invalid color component";
|
throw "Invalid color component";
|
||||||
return ((r << 16) | (g << 8) | b).toString(16);
|
return ((r << 16) | (g << 8) | b).toString(16);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.inherit = function(extendedObject, inheritFrom) {
|
ns.inherit = function(extendedObject, inheritFrom) {
|
||||||
extendedObject.prototype = Object.create(inheritFrom.prototype);
|
extendedObject.prototype = Object.create(inheritFrom.prototype);
|
||||||
extendedObject.prototype.constructor = extendedObject;
|
extendedObject.prototype.constructor = extendedObject;
|
||||||
extendedObject.prototype.superclass = inheritFrom.prototype;
|
extendedObject.prototype.superclass = inheritFrom.prototype;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"grunt": "~0.4.1",
|
"grunt": "~0.4.1",
|
||||||
"grunt-contrib-connect": "0.3.0",
|
"grunt-contrib-connect": "0.3.0",
|
||||||
"grunt-contrib-jshint": "0.5.4",
|
"grunt-contrib-jshint": "0.5.4",
|
||||||
"grunt-ghost": "1.0.12"
|
"grunt-ghost": "1.0.12",
|
||||||
|
"grunt-leading-indent" : "0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user