mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Merge pull request #88 from grosbouddha/clean-localstorage-service
Clean code
This commit is contained in:
25
index.html
25
index.html
@ -89,23 +89,26 @@
|
|||||||
|
|
||||||
<!-- Application libraries-->
|
<!-- Application libraries-->
|
||||||
<script src="js/rendering/DrawingLoop.js"></script>
|
<script src="js/rendering/DrawingLoop.js"></script>
|
||||||
|
<!-- Models -->
|
||||||
<script src="js/model/Frame.js"></script>
|
<script src="js/model/Frame.js"></script>
|
||||||
<script src="js/model/FrameSheet.js"></script>
|
<script src="js/model/FrameSheet.js"></script>
|
||||||
<script src="js/rendering/FrameRenderer.js"></script>
|
|
||||||
<script src="js/controller/DrawingController.js"></script>
|
|
||||||
<script src="js/controller/PreviewFilmController.js"></script>
|
|
||||||
<script src="js/controller/AnimatedPreviewController.js"></script>
|
|
||||||
<script src="js/controller/ToolController.js"></script>
|
|
||||||
<script src="js/LocalStorageService.js"></script>
|
|
||||||
<script src="js/HistoryManager.js"></script>
|
|
||||||
<script src="js/KeyManager.js"></script>
|
|
||||||
<script src="js/selection/SelectionManager.js"></script>
|
<script src="js/selection/SelectionManager.js"></script>
|
||||||
<script src="js/selection/BaseSelection.js"></script>
|
<script src="js/selection/BaseSelection.js"></script>
|
||||||
<script src="js/selection/RectangularSelection.js"></script>
|
<script src="js/selection/RectangularSelection.js"></script>
|
||||||
<script src="js/selection/ShapeSelection.js"></script>
|
<script src="js/selection/ShapeSelection.js"></script>
|
||||||
<script src="js/Palette.js"></script>
|
<!-- Rendering -->
|
||||||
<script src="js/Notification.js"></script>
|
<script src="js/rendering/FrameRenderer.js"></script>
|
||||||
|
<script src="js/controller/DrawingController.js"></script>
|
||||||
|
<!-- Controllers -->
|
||||||
|
<script src="js/controller/PreviewFilmController.js"></script>
|
||||||
|
<script src="js/controller/AnimatedPreviewController.js"></script>
|
||||||
|
<script src="js/controller/ToolController.js"></script>
|
||||||
|
<script src="js/controller/PaletteController.js"></script>
|
||||||
|
<script src="js/controller/NotificationController.js"></script>
|
||||||
|
<!-- Services -->
|
||||||
|
<script src="js/service/LocalStorageService.js"></script>
|
||||||
|
<script src="js/service/HistoryService.js"></script>
|
||||||
|
<script src="js/service/KeyboardEventService.js"></script>
|
||||||
<!-- Tools-->
|
<!-- Tools-->
|
||||||
<script src="js/drawingtools/BaseTool.js"></script>
|
<script src="js/drawingtools/BaseTool.js"></script>
|
||||||
<script src="js/drawingtools/SimplePen.js"></script>
|
<script src="js/drawingtools/SimplePen.js"></script>
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* @provide pskl.LocalStrageService
|
|
||||||
*
|
|
||||||
* @require Constants
|
|
||||||
* @require Events
|
|
||||||
*/
|
|
||||||
$.namespace("pskl");
|
|
||||||
|
|
||||||
pskl.LocalStorageService = (function() {
|
|
||||||
|
|
||||||
var frameSheet_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var localStorageThrottler_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var persistToLocalStorageRequest_ = function() {
|
|
||||||
// Persist to localStorage when drawing. We throttle localStorage accesses
|
|
||||||
// for high frequency drawing (eg mousemove).
|
|
||||||
if(localStorageThrottler_ !== null) {
|
|
||||||
window.clearTimeout(localStorageThrottler_);
|
|
||||||
}
|
|
||||||
localStorageThrottler_ = window.setTimeout(function() {
|
|
||||||
persistToLocalStorage_();
|
|
||||||
localStorageThrottler_ = null;
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var persistToLocalStorage_ = function() {
|
|
||||||
console.log('[LocalStorage service]: Snapshot stored');
|
|
||||||
window.localStorage.snapShot = frameSheet_.serialize();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* TODO(vince): Move that away from LocalStorageService
|
|
||||||
*/
|
|
||||||
var restoreFromLocalStorage_ = function() {
|
|
||||||
|
|
||||||
frameSheet_.deserialize(window.localStorage.snapShot);
|
|
||||||
frameSheet_.setCurrentFrameIndex(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var cleanLocalStorage_ = function() {
|
|
||||||
console.log('[LocalStorage service]: Snapshot removed');
|
|
||||||
delete window.localStorage.snapShot;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function(frameSheet) {
|
|
||||||
|
|
||||||
if(frameSheet === undefined) {
|
|
||||||
throw "Bad LocalStorageService initialization: <undefined frameSheet>";
|
|
||||||
}
|
|
||||||
frameSheet_ = frameSheet;
|
|
||||||
|
|
||||||
$.subscribe(Events.LOCALSTORAGE_REQUEST, persistToLocalStorageRequest_);
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO(vincz): Find a good place to put this UI rendering, a service should not render UI.
|
|
||||||
displayRestoreNotification: function() {
|
|
||||||
if(window.localStorage && window.localStorage.snapShot) {
|
|
||||||
var reloadLink = "<a href='#' class='localstorage-restore onclick='piskel.restoreFromLocalStorage()'>reload</a>";
|
|
||||||
var discardLink = "<a href='#' class='localstorage-discard' onclick='piskel.cleanLocalStorage()'>discard</a>";
|
|
||||||
var content = "Non saved version found. " + reloadLink + " or " + discardLink;
|
|
||||||
|
|
||||||
$.publish(Events.SHOW_NOTIFICATION, [{
|
|
||||||
"content": content,
|
|
||||||
"behavior": function(rootNode) {
|
|
||||||
rootNode = $(rootNode);
|
|
||||||
rootNode.click(function(evt) {
|
|
||||||
var target = $(evt.target);
|
|
||||||
if(target.hasClass("localstorage-restore")) {
|
|
||||||
restoreFromLocalStorage_();
|
|
||||||
}
|
|
||||||
else if (target.hasClass("localstorage-discard")) {
|
|
||||||
cleanLocalStorage_();
|
|
||||||
}
|
|
||||||
$.publish(Events.HIDE_NOTIFICATION);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* @provide pskl.NotificationService
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$.namespace("pskl");
|
|
||||||
|
|
||||||
pskl.NotificationService = (function() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var displayMessage_ = function (evt, messageInfo) {
|
|
||||||
var message = document.createElement('div');
|
|
||||||
message.id = "user-message";
|
|
||||||
message.className = "user-message";
|
|
||||||
message.innerHTML = messageInfo.content;
|
|
||||||
message.innerHTML = message.innerHTML + "<div title='Close message' class='close'>x</div>";
|
|
||||||
document.body.appendChild(message);
|
|
||||||
$(message).find(".close").click(removeMessage_);
|
|
||||||
if(messageInfo.behavior) messageInfo.behavior(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var removeMessage_ = function (evt) {
|
|
||||||
var message = $("#user-message");
|
|
||||||
if (message.length) {
|
|
||||||
message.remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function() {
|
|
||||||
$.subscribe(Events.SHOW_NOTIFICATION, displayMessage_);
|
|
||||||
$.subscribe(Events.HIDE_NOTIFICATION, removeMessage_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
116
js/Palette.js
116
js/Palette.js
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* @provide pskl.Palette
|
|
||||||
*
|
|
||||||
* @require Constants
|
|
||||||
* @require Events
|
|
||||||
*/
|
|
||||||
$.namespace("pskl");
|
|
||||||
|
|
||||||
pskl.Palette = (function() {
|
|
||||||
|
|
||||||
var paletteRoot,
|
|
||||||
paletteColors = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var onPickerChange_ = function(evt, isPrimary) {
|
|
||||||
var inputPicker = $(evt.target);
|
|
||||||
$.publish(Events.COLOR_SELECTED, [inputPicker.val(), evt.data.isPrimary]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var createPalette_ = function (colors) {
|
|
||||||
// Always adding transparent color
|
|
||||||
paletteRoot.html('<span class="palette-color transparent-color" data-color="TRANSPARENT" rel="tooltip" data-placement="bottom" title="Transparent"></span>');
|
|
||||||
for(var color in colors) {
|
|
||||||
if(color != Constants.TRANSPARENT_COLOR) {
|
|
||||||
addColorToPalette_(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var addColorToPalette_ = function (color) {
|
|
||||||
if (paletteColors.indexOf(color) == -1 && color != Constants.TRANSPARENT_COLOR) {
|
|
||||||
var colorEl = document.createElement("li");
|
|
||||||
colorEl.className = "palette-color";
|
|
||||||
colorEl.setAttribute("rel", "tooltip");
|
|
||||||
colorEl.setAttribute("data-placement", "bottom");
|
|
||||||
colorEl.setAttribute("data-color", color);
|
|
||||||
colorEl.setAttribute("title", color);
|
|
||||||
colorEl.style.background = color;
|
|
||||||
paletteRoot[0].appendChild(colorEl);
|
|
||||||
paletteColors.push(color);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var onPaletteColorClick_ = function (event) {
|
|
||||||
var selectedColor = $(event.target).data("color");
|
|
||||||
if (event.which == 1) { // left button
|
|
||||||
updateColorPicker(selectedColor, $('#color-picker'));
|
|
||||||
$.publish(Events.COLOR_SELECTED, [selectedColor, true]);
|
|
||||||
} else if (event.which == 3) { // right button
|
|
||||||
updateColorPicker(selectedColor, $('#secondary-color-picker'));
|
|
||||||
$.publish(Events.COLOR_SELECTED, [selectedColor, false]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var updateColorPicker = function (color, colorPicker) {
|
|
||||||
if (color == Constants.TRANSPARENT_COLOR) {
|
|
||||||
// We can set the current palette color to transparent.
|
|
||||||
// You can then combine this transparent color with an advanced
|
|
||||||
// tool for customized deletions.
|
|
||||||
// Eg: bucket + transparent: Delete a colored area
|
|
||||||
// Stroke + transparent: hollow out the equivalent of a stroke
|
|
||||||
|
|
||||||
// The colorpicker can't be set to a transparent state.
|
|
||||||
// We set its background to white and insert the
|
|
||||||
// string "TRANSPARENT" to mimic this state:
|
|
||||||
colorPicker[0].color.fromString("#fff");
|
|
||||||
colorPicker.val(Constants.TRANSPARENT_COLOR);
|
|
||||||
} else {
|
|
||||||
colorPicker[0].color.fromString(color);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function(framesheet) {
|
|
||||||
|
|
||||||
paletteRoot = $("#palette");
|
|
||||||
|
|
||||||
// Initialize palette:
|
|
||||||
createPalette_(framesheet.getUsedColors());
|
|
||||||
|
|
||||||
$.subscribe(Events.FRAMESHEET_RESET, function(evt) {
|
|
||||||
createPalette_(framesheet.getUsedColors());
|
|
||||||
});
|
|
||||||
|
|
||||||
paletteRoot.mouseup(onPaletteColorClick_);
|
|
||||||
$.subscribe(Events.COLOR_SELECTED, function(evt, color) {
|
|
||||||
addColorToPalette_(color);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize colorpicker:
|
|
||||||
var colorPicker = $('#color-picker');
|
|
||||||
colorPicker.val(Constants.DEFAULT_PEN_COLOR);
|
|
||||||
colorPicker.change({isPrimary : true}, onPickerChange_);
|
|
||||||
|
|
||||||
|
|
||||||
var secondaryColorPicker = $('#secondary-color-picker');
|
|
||||||
secondaryColorPicker.val(Constants.TRANSPARENT_COLOR);
|
|
||||||
secondaryColorPicker.change({isPrimary : false}, onPickerChange_);
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
39
js/controller/NotificationController.js
Normal file
39
js/controller/NotificationController.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace("pskl.controller");
|
||||||
|
|
||||||
|
ns.NotificationController = function () {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.NotificationController.prototype.displayMessage_ = function (evt, messageInfo) {
|
||||||
|
var message = document.createElement('div');
|
||||||
|
message.id = "user-message";
|
||||||
|
message.className = "user-message";
|
||||||
|
message.innerHTML = messageInfo.content;
|
||||||
|
message.innerHTML = message.innerHTML + "<div title='Close message' class='close'>x</div>";
|
||||||
|
document.body.appendChild(message);
|
||||||
|
$(message).find(".close").click($.proxy(this.removeMessage_, this));
|
||||||
|
if(messageInfo.behavior) {
|
||||||
|
messageInfo.behavior(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.NotificationController.prototype.removeMessage_ = function (evt) {
|
||||||
|
var message = $("#user-message");
|
||||||
|
if (message.length) {
|
||||||
|
message.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
ns.NotificationController.prototype.init = function() {
|
||||||
|
$.subscribe(Events.SHOW_NOTIFICATION, $.proxy(this.displayMessage_, this));
|
||||||
|
$.subscribe(Events.HIDE_NOTIFICATION, $.proxy(this.removeMessage_, this));
|
||||||
|
};
|
||||||
|
})();
|
115
js/controller/PaletteController.js
Normal file
115
js/controller/PaletteController.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace("pskl.controller");
|
||||||
|
|
||||||
|
ns.PaletteController = function () {
|
||||||
|
this.paletteRoot = null;
|
||||||
|
this.paletteColors = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.onPickerChange_ = function(evt, isPrimary) {
|
||||||
|
var inputPicker = $(evt.target);
|
||||||
|
$.publish(Events.COLOR_SELECTED, [inputPicker.val(), evt.data.isPrimary]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.createPalette_ = function (colors) {
|
||||||
|
// Always adding transparent color
|
||||||
|
this.paletteRoot.html('<span class="palette-color transparent-color" data-color="TRANSPARENT" title="Transparent"></span>');
|
||||||
|
for(var color in colors) {
|
||||||
|
if(color != Constants.TRANSPARENT_COLOR) {
|
||||||
|
this.addColorToPalette_(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.addColorToPalette_ = function (color) {
|
||||||
|
if (this.paletteColors.indexOf(color) == -1 && color != Constants.TRANSPARENT_COLOR) {
|
||||||
|
var colorEl = document.createElement("li");
|
||||||
|
colorEl.className = "palette-color";
|
||||||
|
colorEl.setAttribute("data-color", color);
|
||||||
|
colorEl.setAttribute("title", color);
|
||||||
|
colorEl.style.background = color;
|
||||||
|
this.paletteRoot.append(colorEl);
|
||||||
|
this.paletteColors.push(color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.onPaletteColorClick_ = function (event) {
|
||||||
|
var selectedColor = $(event.target).data("color");
|
||||||
|
if (event.which == 1) { // left button
|
||||||
|
this.updateColorPicker_(selectedColor, $('#color-picker'));
|
||||||
|
$.publish(Events.COLOR_SELECTED, [selectedColor, true]);
|
||||||
|
} else if (event.which == 3) { // right button
|
||||||
|
this.updateColorPicker_(selectedColor, $('#secondary-color-picker'));
|
||||||
|
$.publish(Events.COLOR_SELECTED, [selectedColor, false]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.updateColorPicker_ = function (color, colorPicker) {
|
||||||
|
if (color == Constants.TRANSPARENT_COLOR) {
|
||||||
|
// We can set the current palette color to transparent.
|
||||||
|
// You can then combine this transparent color with an advanced
|
||||||
|
// tool for customized deletions.
|
||||||
|
// Eg: bucket + transparent: Delete a colored area
|
||||||
|
// Stroke + transparent: hollow out the equivalent of a stroke
|
||||||
|
|
||||||
|
// The colorpicker can't be set to a transparent state.
|
||||||
|
// We set its background to white and insert the
|
||||||
|
// string "TRANSPARENT" to mimic this state:
|
||||||
|
colorPicker[0].color.fromString("#fff");
|
||||||
|
colorPicker.val(Constants.TRANSPARENT_COLOR);
|
||||||
|
} else {
|
||||||
|
colorPicker[0].color.fromString(color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
ns.PaletteController.prototype.init = function(framesheet) {
|
||||||
|
|
||||||
|
this.paletteRoot = $("#palette");
|
||||||
|
this.framesheet = framesheet;
|
||||||
|
|
||||||
|
// Initialize palette:
|
||||||
|
this.createPalette_(this.framesheet.getUsedColors());
|
||||||
|
|
||||||
|
$.subscribe(Events.FRAMESHEET_RESET, $.proxy(function(evt) {
|
||||||
|
this.createPalette_(this.framesheet.getUsedColors());
|
||||||
|
}, this));
|
||||||
|
|
||||||
|
this.paletteRoot.mouseup($.proxy(this.onPaletteColorClick_, this));
|
||||||
|
|
||||||
|
$.subscribe(Events.COLOR_SELECTED, $.proxy(function(evt, color) {
|
||||||
|
this.addColorToPalette_(color);
|
||||||
|
}, this));
|
||||||
|
|
||||||
|
// Initialize colorpickers:
|
||||||
|
var colorPicker = $('#color-picker');
|
||||||
|
colorPicker.val(Constants.DEFAULT_PEN_COLOR);
|
||||||
|
colorPicker.change({isPrimary : true}, $.proxy(this.onPickerChange_, this));
|
||||||
|
|
||||||
|
|
||||||
|
var secondaryColorPicker = $('#secondary-color-picker');
|
||||||
|
secondaryColorPicker.val(Constants.TRANSPARENT_COLOR);
|
||||||
|
secondaryColorPicker.change({isPrimary : false}, $.proxy(this.onPickerChange_, this));
|
||||||
|
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
19
js/piskel.js
19
js/piskel.js
@ -66,13 +66,17 @@ $.namespace("pskl");
|
|||||||
this.animationController.init();
|
this.animationController.init();
|
||||||
this.previewsController.init();
|
this.previewsController.init();
|
||||||
|
|
||||||
this.historyManager = new pskl.HistoryManager(frameSheet);
|
this.historyService = new pskl.service.HistoryService(frameSheet);
|
||||||
this.historyManager.init();
|
this.historyService.init();
|
||||||
|
|
||||||
this.keyManager = new pskl.KeyManager();
|
this.keyboardEventService = new pskl.service.KeyboardEventService();
|
||||||
|
this.keyboardEventService.init();
|
||||||
|
|
||||||
pskl.NotificationService.init();
|
this.notificationController = new pskl.controller.NotificationController();
|
||||||
pskl.LocalStorageService.init(frameSheet);
|
this.notificationController.init();
|
||||||
|
|
||||||
|
this.localStorageService = new pskl.service.LocalStorageService(frameSheet);
|
||||||
|
this.localStorageService.init();
|
||||||
|
|
||||||
// TODO: Add comments
|
// TODO: Add comments
|
||||||
var framesheetId = this.getFramesheetIdFromUrl();
|
var framesheetId = this.getFramesheetIdFromUrl();
|
||||||
@ -81,7 +85,7 @@ $.namespace("pskl");
|
|||||||
this.loadFramesheetFromService(framesheetId);
|
this.loadFramesheetFromService(framesheetId);
|
||||||
} else {
|
} else {
|
||||||
this.finishInit();
|
this.finishInit();
|
||||||
pskl.LocalStorageService.displayRestoreNotification();
|
this.localStorageService.displayRestoreNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
var drawingLoop = new pskl.rendering.DrawingLoop();
|
var drawingLoop = new pskl.rendering.DrawingLoop();
|
||||||
@ -155,7 +159,8 @@ $.namespace("pskl");
|
|||||||
var toolController = new pskl.controller.ToolController();
|
var toolController = new pskl.controller.ToolController();
|
||||||
toolController.init();
|
toolController.init();
|
||||||
|
|
||||||
pskl.Palette.init(frameSheet);
|
var paletteController = new pskl.controller.PaletteController();
|
||||||
|
paletteController.init(frameSheet);
|
||||||
},
|
},
|
||||||
|
|
||||||
getFramesheetIdFromUrl : function() {
|
getFramesheetIdFromUrl : function() {
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl");
|
var ns = $.namespace("pskl.service");
|
||||||
ns.HistoryManager = function (framesheet) {
|
ns.HistoryService = function (framesheet) {
|
||||||
this.framesheet = framesheet;
|
this.framesheet = framesheet;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryManager.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.HistoryManager.prototype.saveState = function () {
|
ns.HistoryService.prototype.saveState = function () {
|
||||||
this.framesheet.getCurrentFrame().saveState();
|
this.framesheet.getCurrentFrame().saveState();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryManager.prototype.undo = function () {
|
ns.HistoryService.prototype.undo = function () {
|
||||||
this.framesheet.getCurrentFrame().loadPreviousState();
|
this.framesheet.getCurrentFrame().loadPreviousState();
|
||||||
$.publish(Events.FRAMESHEET_RESET);
|
$.publish(Events.FRAMESHEET_RESET);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HistoryManager.prototype.redo = function () {
|
ns.HistoryService.prototype.redo = function () {
|
||||||
this.framesheet.getCurrentFrame().loadNextState();
|
this.framesheet.getCurrentFrame().loadNextState();
|
||||||
$.publish(Events.FRAMESHEET_RESET);
|
$.publish(Events.FRAMESHEET_RESET);
|
||||||
};
|
};
|
@ -1,21 +1,12 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace("pskl");
|
var ns = $.namespace("pskl.service");
|
||||||
|
|
||||||
ns.KeyManager = function () {
|
ns.KeyboardEventService = function () {};
|
||||||
$(document.body).keydown($.proxy(this.onKeyUp_, this));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Kind of object that make you want to stop front-end _engineering_:
|
/**
|
||||||
ns.KeyManager.prototype.CharCodeToKeyCodeMap = {
|
* @private
|
||||||
|
*/
|
||||||
90 : "z",
|
ns.KeyboardEventService.prototype.KeyboardActions_ = {
|
||||||
89 : "y",
|
|
||||||
88 : "x",
|
|
||||||
67 : "c",
|
|
||||||
86 : "v"
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.KeyManager.prototype.KeyboardActions = {
|
|
||||||
|
|
||||||
"ctrl" : {
|
"ctrl" : {
|
||||||
"z" : Events.UNDO,
|
"z" : Events.UNDO,
|
||||||
@ -26,9 +17,22 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.KeyboardEventService.prototype.CharCodeToKeyCodeMap_ = {
|
||||||
|
|
||||||
ns.KeyManager.prototype.onKeyUp_ = function(evt) {
|
90 : "z",
|
||||||
|
89 : "y",
|
||||||
|
88 : "x",
|
||||||
|
67 : "c",
|
||||||
|
86 : "v"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
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:
|
||||||
@ -37,14 +41,24 @@
|
|||||||
|
|
||||||
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();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
ns.KeyboardEventService.prototype.init = function() {
|
||||||
|
$(document.body).keydown($.proxy(this.onKeyUp_, this));
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
})();
|
89
js/service/LocalStorageService.js
Normal file
89
js/service/LocalStorageService.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace("pskl.service");
|
||||||
|
|
||||||
|
ns.LocalStorageService = function (framesheet_) {
|
||||||
|
|
||||||
|
if(framesheet_ === undefined) {
|
||||||
|
throw "Bad LocalStorageService initialization: <undefined frameSheet>";
|
||||||
|
}
|
||||||
|
this.framesheet = framesheet_;
|
||||||
|
this.localStorageThrottler_ = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.persistToLocalStorageRequest_ = function () {
|
||||||
|
// Persist to localStorage when drawing. We throttle localStorage accesses
|
||||||
|
// for high frequency drawing (eg mousemove).
|
||||||
|
if(this.localStorageThrottler_ !== null) {
|
||||||
|
window.clearTimeout(this.localStorageThrottler_);
|
||||||
|
}
|
||||||
|
this.localStorageThrottler_ = window.setTimeout($.proxy(function() {
|
||||||
|
this.persistToLocalStorage_();
|
||||||
|
this.localStorageThrottler_ = null;
|
||||||
|
}, this), 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.persistToLocalStorage_ = function() {
|
||||||
|
|
||||||
|
console.log('[LocalStorage service]: Snapshot stored');
|
||||||
|
window.localStorage.snapShot = this.framesheet.serialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.restoreFromLocalStorage_ = function() {
|
||||||
|
|
||||||
|
this.framesheet.deserialize(window.localStorage.snapShot);
|
||||||
|
this.framesheet.setCurrentFrameIndex(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.cleanLocalStorage_ = function() {
|
||||||
|
console.log('[LocalStorage service]: Snapshot removed');
|
||||||
|
delete window.localStorage.snapShot;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.init = function(framesheet_) {
|
||||||
|
|
||||||
|
$.subscribe(Events.LOCALSTORAGE_REQUEST, $.proxy(this.persistToLocalStorageRequest_, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
ns.LocalStorageService.prototype.displayRestoreNotification = function() {
|
||||||
|
if(window.localStorage && window.localStorage.snapShot) {
|
||||||
|
var reloadLink = "<a href='#' class='localstorage-restore onclick='piskel.restoreFromLocalStorage()'>reload</a>";
|
||||||
|
var discardLink = "<a href='#' class='localstorage-discard' onclick='piskel.cleanLocalStorage()'>discard</a>";
|
||||||
|
var content = "Non saved version found. " + reloadLink + " or " + discardLink;
|
||||||
|
|
||||||
|
$.publish(Events.SHOW_NOTIFICATION, [{
|
||||||
|
"content": content,
|
||||||
|
"behavior": $.proxy(function(rootNode) {
|
||||||
|
rootNode = $(rootNode);
|
||||||
|
rootNode.click($.proxy(function(evt) {
|
||||||
|
var target = $(evt.target);
|
||||||
|
if(target.hasClass("localstorage-restore")) {
|
||||||
|
this.restoreFromLocalStorage_();
|
||||||
|
}
|
||||||
|
else if (target.hasClass("localstorage-discard")) {
|
||||||
|
this.cleanLocalStorage_();
|
||||||
|
}
|
||||||
|
$.publish(Events.HIDE_NOTIFICATION);
|
||||||
|
}, this));
|
||||||
|
}, this)
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
Reference in New Issue
Block a user