mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Merge branch 'master' into gh-pages
This commit is contained in:
commit
69a2a76192
124
css/style.css
124
css/style.css
@ -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
|
||||
*/
|
||||
|
@ -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
BIN
img/gear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 789 B |
70
index.html
70
index.html
@ -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>
|
||||
|
@ -1,3 +1,4 @@
|
||||
// TODO(grosbouddha): put under pskl namespace.
|
||||
var Constants = {
|
||||
DEFAULT_SIZE : {
|
||||
height : 32,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 () {
|
||||
|
45
js/controller/SettingsController.js
Normal file
45
js/controller/SettingsController.js
Normal 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');
|
||||
}
|
||||
});
|
||||
};
|
||||
})();
|
@ -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));
|
||||
};
|
||||
})();
|
12
js/piskel.js
12
js/piskel.js
@ -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();
|
||||
|
||||
|
@ -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
76
js/utils/UserSettings.js
Normal 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
BIN
resources/icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
Loading…
Reference in New Issue
Block a user