Merge branch 'master' into gh-pages

This commit is contained in:
jdescottes 2013-06-19 07:39:08 +02:00
commit 69a2a76192
14 changed files with 461 additions and 197 deletions

View File

@ -16,9 +16,9 @@ body {
text-align: center;
font-size: 0;
position: absolute;
left: 104px;
left: 100px; /* Reserve room for tools on the left edge of the screen. */
top: 10px;
right: 0;
right: 50px; /* Reserve room for actions on the right edge of the screen. */
bottom: 10px;
}
@ -51,15 +51,120 @@ body {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 140px;
z-index: 1000;
}
.sticky-section .wrap {
.sticky-section .wrap,
.sticky-section .drawer {
display: table-cell;
vertical-align: middle;
}
.left-sticky-section.sticky-section {
left: 0;
max-width: 100px;
}
.left-sticky-section .tool-icon {
float: left;
}
.right-sticky-section.sticky-section {
right: 0;
width: 50px;
-webkit-transition: all 200ms ease-out;
-moz-transition: all 200ms ease-out;
-ms-transition: all 200ms ease-out;
transition: all 200ms ease-out;
}
.right-sticky-section .tool-icon {
float: right;
margin-right: 0;
}
.drawer {
}
.drawer-content {
overflow: hidden;
background-color: #444;
height: 550px;
max-height: 100%;
width: 280px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
/** Righty sticky drawer expanded state. */
.right-sticky-section.expanded {
right: 280px;
}
.right-sticky-section.expanded .tool-icon {
margin-right: 1px;
}
.right-sticky-section .tool-icon.has-expanded-drawer {
position: relative;
background-color: #444;
margin-right: 0;
padding-right: 1px;
}
.settings-section {
margin: 10px 20px;
font-size: 12px;
font-weight: bold;
color: #ccc;
text-shadow: 1px 1px #000;
}
.settings-title {
margin-top: 20px;
margin-bottom: 10px;
text-transform: uppercase;
border-bottom: 1px #aaa solid;
padding-bottom: 5px;
}
.settings-item {}
.background-picker-wrapper {
overflow: hidden;
padding: 10px 5px 20px 5px;
}
.background-picker {
cursor: pointer;
float: left;
height: 35px;
width: 35px;
background-color: transparent;
margin-right: 15px;
padding: 1px;
position: relative;
}
.background-picker:after {
content: " ";
position: absolute;
top: -2px;
right: -2px;
bottom: -2px;
left: -2px;
}
.background-picker:hover:after {
border: #eee 1px solid;
}
.background-picker.selected:after {
border: gold 1px solid;
}
/**
* Canvases layout
@ -76,7 +181,6 @@ body {
}
.canvas-container .canvas-background {
background: url(../img/canvas_background/medium_canvas_background.png) repeat;
position: absolute;
top: 0;
right: 0;
@ -84,18 +188,22 @@ body {
left: 0;
}
.light-picker-background,
.light-canvas-background .canvas-background {
background: url(../img/canvas_background/light_canvas_background.png) repeat;
}
.medium-picker-background,
.medium-canvas-background .canvas-background {
background: url(../img/canvas_background/medium_canvas_background.png) repeat;
}
.lowcont-medium-picker-background,
.lowcont-medium-canvas-background .canvas-background {
background: url(../img/canvas_background/lowcont_medium_canvas_background.png) repeat;
}
.lowcont-dark-picker-background,
.lowcont-dark-canvas-background .canvas-background {
background: url(../img/canvas_background/lowcont_dark_canvas_background.png) repeat;
}
@ -137,10 +245,6 @@ body {
overflow: hidden;
}
.application-actions {
margin-top: 35px;
}
/**
* User messages
*/

View File

@ -6,12 +6,11 @@
}
.tool-icon {
float: left;
cursor : pointer;
width: 46px;
height: 46px;
margin: 1px;
background-color: rgba(200,200,200, .1);
background-color: #3a3a3a;
background-repeat: no-repeat;
background-position: 12px 12px;
background-size: 24px 24px;
@ -198,6 +197,12 @@
background-size: 36px 36px;
}
.tool-icon.gear-icon {
background-image: url(../img/gear.png);
background-position: 6px 7px;
background-size: 32px 32px;
}
.tool-icon.upload-cloud-icon {
background-image: url(../img/cloud_export.png);
background-position: 4px 0px;
@ -213,5 +218,6 @@
font-size: 11px;
text-transform: uppercase;
color: #fff;
text-align: center;
}

BIN
img/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

View File

@ -16,8 +16,7 @@
<link rel="stylesheet" type="text/css" href="css/preview-film-section.css">
</head>
<body>
<div id="menubar" class="sticky-section">
<div class="sticky-section left-sticky-section" id="tool-section">
<div class="wrap">
<ul id="tools-container" class="tools-wrapper"></ul>
<div class="palette-wrapper">
@ -31,21 +30,48 @@
</div>
</div>
</div>
<!-- TODO: remove grid -->
<div style="display:none;" class="options-wrapper">
<div class="tool-grid">
<input id="show-grid" type="checkbox"/>
<label for="show-grid">Show grid</label>
</div>
</div>
</div>
<div id="application-action-section" class="sticky-section right-sticky-section">
<div class="wrap">
<div id="settings" class="tool-icon gear-icon" title="Preferences" rel="tooltip" data-placement="left"></div>
<a class="tool-icon gallery-icon" title="Visit gallery" href="http://juliandescottes.github.io/piskel-website/" rel="tooltip" data-placement="left" target="_blank"></a>
<div class="tool-icon save-icon" title="Save to gallery" onclick="piskel.storeSheet()" rel="tooltip" data-placement="left" ></div>
<div class="tool-icon upload-cloud-icon" title="Upload as an animated GIF" onclick="piskel.uploadAsAnimatedGIF()" rel="tooltip" data-placement="left">
<span class="label">GIF</span>
</div>
<div style="float: left; margin-top: 20px; color: #fff;">
Canvas background:
<select id="canvas-picker" style="width:100px;">
<option value="light-canvas-background">Light</option>
<option value="lowcont-medium-canvas-background">Medium - low contrast</option>
<option value="medium-canvas-background" selected="selected">Medium - high contrast</option>
<option value="lowcont-dark-canvas-background">Dark - low constrast</option>
</select>
<div class="tool-icon upload-cloud-icon" title="Upload as a spritesheet PNG" onclick="piskel.uploadAsSpritesheetPNG()" rel="tooltip" data-placement="left">
<span class="label">PNG</span>
</div>
</div>
<div class="drawer">
<div class="drawer-content">
<div class="settings-section">
<div class="settings-title">
Canvas settings:
</div>
<div class="settings-item">
<label>Background:</label>
<div id="background-picker-wrapper" class="background-picker-wrapper">
<div class="background-picker light-picker-background" data-background-class="light-canvas-background"
rel="tooltip" data-placement="bottom" title="light / high contrast">
</div>
<div class="background-picker medium-picker-background" data-background-class="medium-canvas-background"
rel="tooltip" data-placement="bottom" title="medium / high contrast">
</div>
<div class="background-picker lowcont-medium-picker-background" data-background-class="lowcont-medium-canvas-background"
rel="tooltip" data-placement="bottom" title="medium / low contrast">
</div>
<div class="background-picker lowcont-dark-picker-background" data-background-class="lowcont-dark-canvas-background"
rel="tooltip" data-placement="bottom" title="dark / low contrast">
</div>
</div>
</div>
<div class="settings-item">
<label for="show-grid">Show grid:</label> <input id="show-grid" type="checkbox"/>
</div>
</div>
</div>
</div>
</div>
@ -81,16 +107,6 @@
<input id="preview-fps" class="range-fps" type="range" min="1" max="24" value="12"/>
</div>
</div>
<div class="application-actions">
<a class="tool-icon gallery-icon" title="Visit gallery" href="http://juliandescottes.github.io/piskel-website/" rel="tooltip" data-placement="bottom" target="_blank"></a>
<div class="tool-icon save-icon" title="Save to gallery" onclick="piskel.storeSheet()" rel="tooltip" data-placement="bottom" ></div>
<div class="tool-icon upload-cloud-icon" title="Upload as an animated GIF" onclick="piskel.uploadAsAnimatedGIF()" rel="tooltip" data-placement="bottom" >
<span class="label">GIF</span>
</div>
<div class="tool-icon upload-cloud-icon" title="Upload as a spritesheet PNG" onclick="piskel.uploadAsSpritesheetPNG()" rel="tooltip" data-placement="bottom" >
<span class="label">PNG</span>
</div>
</div>
</div>
</div>
@ -114,6 +130,7 @@
<script src="js/utils/core.js"></script>
<script src="js/utils/PixelUtils.js"></script>
<script src="js/utils/CanvasUtils.js"></script>
<script src="js/utils/UserSettings.js"></script>
<script src="js/lib/jsColor_1_4_0/jscolor.js"></script>
<!-- Application libraries-->
@ -136,6 +153,7 @@
<script src="js/controller/ToolController.js"></script>
<script src="js/controller/PaletteController.js"></script>
<script src="js/controller/NotificationController.js"></script>
<script src="js/controller/SettingsController.js"></script>
<!-- Services -->
<script src="js/service/LocalStorageService.js"></script>
<script src="js/service/HistoryService.js"></script>

View File

@ -1,3 +1,4 @@
// TODO(grosbouddha): put under pskl namespace.
var Constants = {
DEFAULT_SIZE : {
height : 32,

View File

@ -1,3 +1,4 @@
// TODO(grosbouddha): put under pskl namespace.
Events = {
TOOL_SELECTED : "TOOL_SELECTED",
@ -30,7 +31,13 @@ Events = {
*/
REDRAW_PREVIEWFILM: "REDRAW_PREVIEWFILM",
GRID_DISPLAY_STATE_CHANGED: "GRID_DISPLAY_STATE_CHANGED",
/**
* Fired each time a user setting change.
* The payload will be:
* 1st argument: Name of the settings
* 2nd argument: New value
*/
USER_SETTINGS_CHANGED: "USER_SETTINGS_CHANGED",
/**
* The framesheet was reseted and is now probably drastically different.

View File

@ -19,7 +19,7 @@
// TODO(vincz): Store user prefs in a localstorage string ?
var renderingOptions = {
"dpi": this.calculateDPI_(),
"hasGrid" : true
"supportGridRendering" : true
};
this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, "drawing-canvas");
@ -61,7 +61,7 @@
$(window).resize($.proxy(this.startDPIUpdateTimer_, this));
$.subscribe(Events.FRAME_SIZE_CHANGED, $.proxy(this.updateDPI_, this));
$.subscribe(Events.GRID_DISPLAY_STATE_CHANGED, $.proxy(this.forceRendering_, this));
$.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this));
};
ns.DrawingController.prototype.initMouseBehavior = function() {
@ -83,6 +83,15 @@
this.dpiUpdateTimer = window.setTimeout($.proxy(this.updateDPI_, this), 200);
},
/**
* @private
*/
ns.DrawingController.prototype.onUserSettingsChange_ = function (evt, settingsName, settingsValue) {
if(settingsName == pskl.UserSettings.SHOW_GRID) {
this.forceRendering_();
}
},
/**
* @private
*/

View File

@ -56,10 +56,10 @@
if (scrollBottom > treshold) {
overflowBottom = true;
}
var wrapper = $('#preview-list-wrapper');
wrapper.toggleClass('top-overflow-visible', overflowTop);
wrapper.toggleClass('bottom-overflow-visible', overflowBottom);
}
var wrapper = $('#preview-list-wrapper');
wrapper.toggleClass('top-overflow-visible', overflowTop);
wrapper.toggleClass('bottom-overflow-visible', overflowBottom);
};
ns.PreviewFilmController.prototype.createPreviews_ = function () {

View File

@ -0,0 +1,45 @@
(function () {
var ns = $.namespace("pskl.controller");
ns.SettingsController = function () {};
/**
* @public
*/
ns.SettingsController.prototype.init = function() {
// Highlight selected background picker:
var backgroundClass = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);
$('#background-picker-wrapper')
.find('.background-picker[data-background-class=' + backgroundClass + ']')
.addClass('selected');
// Initial state for grid display:
var show_grid = pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID);
$('#show-grid').prop('checked', show_grid);
// Expand drawer when clicking 'Settings' tab.
$('#settings').click(function(evt) {
$('.right-sticky-section').toggleClass('expanded');
$('#settings').toggleClass('has-expanded-drawer');
});
// Handle grid display changes:
$('#show-grid').change($.proxy(function(evt) {
var checked = $('#show-grid').prop('checked');
pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked);
}, this));
// Handle canvas background changes:
$('#background-picker-wrapper').click(function(evt) {
var target = $(evt.target).closest('.background-picker');
if (target.length) {
var backgroundClass = target.data('background-class');
pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass);
$('.background-picker').removeClass('selected');
target.addClass('selected');
}
});
};
})();

View File

@ -58,7 +58,7 @@
this.selectTool_(this.toolInstances[tool]);
// Show tool as selected:
$('#menubar .tool-icon.selected').removeClass('selected');
$('#tool-section .tool-icon.selected').removeClass('selected');
clickedTool.addClass('selected');
}
}
@ -83,17 +83,6 @@
$('#tools-container').html(toolMarkup);
};
/**
* Get state for the checkbox that control the display of the grid
* on the drawing canvas.
* @private
*/
ns.ToolController.prototype.isShowGridChecked_ = function() {
var showGridCheckbox = $('#show-grid');
var isChecked = showGridCheckbox.is(':checked');
return isChecked;
};
/**
* @public
*/
@ -105,13 +94,6 @@
// Set SimplePen as default selected tool:
this.selectTool_(this.toolInstances.simplePen);
// Activate listener on tool panel:
$("#menubar").click($.proxy(this.onToolIconClicked_, this));
// Show/hide the grid on drawing canvas:
$.publish(Events.GRID_DISPLAY_STATE_CHANGED, [this.isShowGridChecked_()]);
$('#show-grid').change($.proxy(function(evt) {
var checked = this.isShowGridChecked_();
$.publish(Events.GRID_DISPLAY_STATE_CHANGED, [checked]);
}, this));
$("#tool-section").click($.proxy(this.onToolIconClicked_, this));
};
})();

View File

@ -24,6 +24,7 @@ $.namespace("pskl");
this.drawingController = new pskl.controller.DrawingController(frameSheet, $('#drawing-canvas-container'));
this.animationController = new pskl.controller.AnimatedPreviewController(frameSheet, $('#preview-canvas-container'));
this.previewsController = new pskl.controller.PreviewFilmController(frameSheet, $('#preview-list'));
this.settingsController = new pskl.controller.SettingsController();
// To catch the current active frame, the selection manager have to be initialized before
// the 'frameSheet.setCurrentFrameIndex(0);' line below.
@ -39,6 +40,7 @@ $.namespace("pskl");
this.animationController.init();
this.previewsController.init();
this.settingsController.init();
this.historyService = new pskl.service.HistoryService(frameSheet);
this.historyService.init();
@ -70,13 +72,6 @@ $.namespace("pskl");
$('body').tooltip({
selector: '[rel=tooltip]'
});
$('#canvas-picker').change(function(evt) {
$('#canvas-picker option:selected').each(function() {
console.log($(this).val());
$('html')[0].className = $(this).val();
});
});
},
render : function (delta) {
@ -130,7 +125,6 @@ $.namespace("pskl");
loadFramesheetFromService : function (frameId) {
var xhr = new XMLHttpRequest();
// TODO: Change frameId to framesheetId on the backend
xhr.open('GET', Constants.PISKEL_SERVICE_URL + '/get?l=' + frameId, true);
xhr.responseType = 'text';
@ -152,7 +146,6 @@ $.namespace("pskl");
// TODO(julz): Create package ?
storeSheet : function (event) {
// TODO Refactor using jquery ?
var xhr = new XMLHttpRequest();
var formData = new FormData();
formData.append('framesheet_content', frameSheet.serialize());
@ -213,6 +206,7 @@ $.namespace("pskl");
}
};
// TODO(grosbouddha): Remove this window.piskel global (eventually pskl.piskel or pskl.app instead)
window.piskel = piskel;
piskel.init();

View File

@ -1,143 +1,165 @@
(function () {
var ns = $.namespace("pskl.rendering");
var ns = $.namespace("pskl.rendering");
ns.FrameRenderer = function (container, renderingOptions, className) {
this.defaultRenderingOptions = {
"hasGrid" : false
};
renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions);
ns.FrameRenderer = function (container, renderingOptions, className) {
this.defaultRenderingOptions = {
'supportGridRendering' : false
};
renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions);
if(container === undefined) {
throw "Bad FrameRenderer initialization. <container> undefined.";
}
if(isNaN(renderingOptions.dpi)) {
throw "Bad FrameRenderer initialization. <dpi> not well defined.";
}
if(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.hasGrid = renderingOptions.hasGrid;
this.gridStrokeWidth = 0;
this.container = container;
this.dpi = renderingOptions.dpi;
this.className = className;
this.canvas = null;
this.supportGridRendering = renderingOptions.supportGridRendering;
// Flag to know if the config was altered
this.canvasConfigDirty = true;
this.enableGrid(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID));
if(this.hasGrid) {
$.subscribe(Events.GRID_DISPLAY_STATE_CHANGED, $.proxy(this.showGrid, this));
}
};
// 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.init = function (frame) {
this.render(frame);
this.lastRenderedFrame = frame;
};
ns.FrameRenderer.prototype.updateDPI = function (newDPI) {
this.dpi = newDPI;
this.canvasConfigDirty = true;
};
ns.FrameRenderer.prototype.updateDPI = function (newDPI) {
this.dpi = newDPI;
this.canvasConfigDirty = true;
};
ns.FrameRenderer.prototype.showGrid = function (evt, show) {
this.gridStrokeWidth = 0;
if(show) {
this.gridStrokeWidth = Constants.GRID_STROKE_WIDTH;
}
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);
}
};
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;
};
/**
* @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.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.enableGrid = function (flag) {
this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0;
this.canvasConfigDirty = true;
};
ns.FrameRenderer.prototype.clear = function (frame) {
var canvas = this.getCanvas_(frame);
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
};
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;
};
/**
* 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
};
};
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);
}
};
/**
* @private
*/
ns.FrameRenderer.prototype.getFramePos_ = function(index) {
return index * this.dpi + ((index - 1) * this.gridStrokeWidth);
};
ns.FrameRenderer.prototype.clear = function (frame) {
var canvas = this.getCanvas_(frame);
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
};
/**
* @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();
}
};
/**
* 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.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 canvas = pskl.CanvasUtils.createCanvas(pixelWidth, pixelHeight, ["canvas", this.className]);
/**
* @private
*/
ns.FrameRenderer.prototype.getFramePos_ = function(index) {
return index * this.dpi + ((index - 1) * this.gridStrokeWidth);
};
this.container.append(canvas);
/**
* @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();
}
};
if(this.gridStrokeWidth > 0) {
this.drawGrid_(canvas, pixelWidth, pixelHeight, col, row);
}
this.canvas = canvas;
this.canvasConfigDirty = false;
}
return this.canvas;
};
/**
* @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;
};
})();

76
js/utils/UserSettings.js Normal file
View File

@ -0,0 +1,76 @@
(function () {
var ns = $.namespace("pskl");
ns.UserSettings = {
SHOW_GRID : 'SHOW_GRID',
CANVAS_BACKGROUND : 'CANVAS_BACKGROUND',
KEY_TO_DEFAULT_VALUE_MAP_ : {
'SHOW_GRID' : false,
'CANVAS_BACKGROUND' : 'medium-canvas-background'
},
/**
* @private
*/
cache_ : {},
/**
* Static method to access a user defined settings value ot its default
* value if not defined yet.
*/
get : function (key) {
this.checkKeyValidity_(key);
if (!(key in this.cache_)) {
this.cache_[key] =
this.readFromLocalStorage_(key) || this.readFromDefaults_(key);
}
return this.cache_[key];
},
set : function (key, value) {
this.checkKeyValidity_(key);
this.cache_[key] = value;
this.writeToLocalStorage_(key, value);
$.publish(Events.USER_SETTINGS_CHANGED, [key, value]);
},
/**
* @private
*/
readFromLocalStorage_ : function(key) {
var value = window.localStorage[key];
if (typeof value != "undefined") {
value = JSON.parse(value);
}
return value;
},
/**
* @private
*/
writeToLocalStorage_ : function(key, value) {
// TODO(grosbouddha): Catch storage exception here.
window.localStorage[key] = JSON.stringify(value);
},
/**
* @private
*/
readFromDefaults_ : function (key) {
return this.KEY_TO_DEFAULT_VALUE_MAP_[key];
},
/**
* @private
*/
checkKeyValidity_ : function(key) {
if(!(key in this.KEY_TO_DEFAULT_VALUE_MAP_)) {
// TODO(grosbouddha): Define error catching strategy and throw exception from here.
console.log("UserSettings key <"+ key +"> not find in supported keys.");
}
}
};
})();

BIN
resources/icons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB