diff --git a/misc/icons/SVG/flip.svg b/misc/icons/SVG/flip.svg new file mode 100644 index 00000000..429112be --- /dev/null +++ b/misc/icons/SVG/flip.svg @@ -0,0 +1,88 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/misc/icons/noun-project/sheep/icon_8389.png b/misc/icons/noun-project/sheep/icon_8389.png new file mode 100644 index 00000000..2e3dbf76 Binary files /dev/null and b/misc/icons/noun-project/sheep/icon_8389.png differ diff --git a/misc/icons/noun-project/sheep/icon_8389.svg b/misc/icons/noun-project/sheep/icon_8389.svg new file mode 100644 index 00000000..673f4f70 --- /dev/null +++ b/misc/icons/noun-project/sheep/icon_8389.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/misc/icons/noun-project/sheep/license.txt b/misc/icons/noun-project/sheep/license.txt new file mode 100644 index 00000000..31ca6c35 --- /dev/null +++ b/misc/icons/noun-project/sheep/license.txt @@ -0,0 +1,8 @@ +Thank you for using The Noun Project. This icon is licensed under Creative +Commons Attribution and must be attributed as: + + Sheep by Unrecognized MJ from The Noun Project + +If you have a Premium Account or have purchased a license for this icon, you +don't need to worry about attribution! We will share the profits from your +purchase with this icon's designer. diff --git a/misc/icons/noun-project/undo-kyle_levi_fox/icon_10033.svg b/misc/icons/noun-project/undo-kyle_levi_fox/icon_10033.svg new file mode 100644 index 00000000..a65a77e1 --- /dev/null +++ b/misc/icons/noun-project/undo-kyle_levi_fox/icon_10033.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/misc/icons/noun-project/undo-kyle_levi_fox/license.txt b/misc/icons/noun-project/undo-kyle_levi_fox/license.txt new file mode 100644 index 00000000..90fdf374 --- /dev/null +++ b/misc/icons/noun-project/undo-kyle_levi_fox/license.txt @@ -0,0 +1,8 @@ +Thank you for using The Noun Project. This icon is licensed under Creative +Commons Attribution and must be attributed as: + + Undo by Kyle Levi Fox from The Noun Project + +If you have a Premium Account or have purchased a license for this icon, you +don't need to worry about attribution! We will share the profits from your +purchase with this icon's designer. diff --git a/src/css/layout.css b/src/css/layout.css new file mode 100644 index 00000000..37645a45 --- /dev/null +++ b/src/css/layout.css @@ -0,0 +1,154 @@ +/** + * Application layout + */ + +.main-wrapper { + position: absolute; + top: 5px; + right: 0; + bottom: 5px; + left: 0; +} + +.column-wrapper { + text-align: center; + font-size: 0; + position: absolute; + left: 100px; /* Reserve room for tools on the left edge of the screen. */ + top: 0; + right: 50px; /* Reserve room for actions on the right edge of the screen. */ + bottom: 0; +} + +.column { + display: inline-block; +} + +.left-column { + vertical-align: top; + height: 100%; + margin-right: 7px; +} + +.main-column { + height: 100%; + position: relative; +} + +.right-column { + vertical-align: top; + margin-left: 10px; + height: 100%; + position: relative; +} + +.drawing-canvas-container { + font-size: 0; +} + +.sticky-section { + position: fixed; + top: 0; + bottom: 0; + z-index: 1000; +} + +.sticky-section .sticky-section-wrap { + display: table; + height: 100%; +} + +.sticky-section .vertical-centerer { + display: table-cell; + vertical-align: middle; +} + +.left-sticky-section.sticky-section { + left: 0; + max-width: 100px; +} + +.left-sticky-section .tool-icon { + float: left; +} + +.cursor-coordinates { + color:#888; + font-size:12px; + font-weight:bold; + font-family:Courier; +} + +/** + * Canvases layout + */ + +.canvas { + position: relative; + z-index: 1; +} + +.canvas-container { + position: relative; + display: block; +} + +.canvas-container .canvas-background { + position: absolute; + top: 0; + right: 0; + bottom: 0; + 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; +} + +.layers-canvas, +.canvas.onion-skin-canvas { + opacity: 0.2; +} + +.canvas.canvas-overlay, +.canvas.layers-canvas, +.canvas.onion-skin-canvas { + position: absolute; + top: 0; + left: 0; +} + +.tools-wrapper, +.options-wrapper, +.palette-wrapper { + float : left; +} + +/** + * Z-indexes should match the drawing area canvas superposition order : + * - 1 : draw layers below current layer + * - 2 : draw current layer + * - 3 : draw layers above current layer + * - 4 : draw the tools overlay + */ +.canvas.layers-below-canvas {z-index: 7;} +.canvas.drawing-canvas {z-index: 8;} +.canvas.canvas-overlay {z-index: 9;} +.canvas.onion-skin-canvas {z-index: 10;} +.canvas.layers-above-canvas {z-index: 11;} \ No newline at end of file diff --git a/src/css/style.css b/src/css/style.css index deaa44a7..d1aa309d 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -20,148 +20,10 @@ body { user-select: initial; } -/** - * Application layout - */ - -.main-wrapper { - position: absolute; - top: 5px; - right: 0; - bottom: 5px; - left: 0; +.no-overflow { + overflow : hidden; } -.column-wrapper { - text-align: center; - font-size: 0; - position: absolute; - left: 100px; /* Reserve room for tools on the left edge of the screen. */ - top: 0; - right: 50px; /* Reserve room for actions on the right edge of the screen. */ - bottom: 0; -} - -.column { - display: inline-block; -} - -.left-column { - vertical-align: top; - height: 100%; - margin-right: 7px; -} - -.main-column { - height: 100%; - position: relative; -} - -.right-column { - vertical-align: top; - margin-left: 10px; - height: 100%; - position: relative; -} - -.drawing-canvas-container { - font-size: 0; -} - -.sticky-section { - position: fixed; - top: 0; - bottom: 0; - z-index: 1000; -} - -.sticky-section .sticky-section-wrap { - display: table; - height: 100%; -} - -.sticky-section .vertical-centerer { - display: table-cell; - vertical-align: middle; -} - -.left-sticky-section.sticky-section { - left: 0; - max-width: 100px; -} - -.left-sticky-section .tool-icon { - float: left; -} - -/** - * Canvases layout - */ - -.canvas { - position: relative; - z-index: 1; -} - -.canvas-container { - position: relative; - display: block; -} - -.canvas-container .canvas-background { - position: absolute; - top: 0; - right: 0; - bottom: 0; - 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; -} - -.layers-canvas, -.canvas.onion-skin-canvas { - opacity: 0.2; -} - -.canvas.canvas-overlay, -.canvas.layers-canvas, -.canvas.onion-skin-canvas { - position: absolute; - top: 0; - left: 0; -} - -/** - * Z-indexes should match the drawing area canvas superposition order : - * - 1 : draw layers below current layer - * - 2 : draw current layer - * - 3 : draw layers above current layer - * - 4 : draw the tools overlay - */ -.canvas.layers-below-canvas {z-index: 7;} -.canvas.drawing-canvas {z-index: 8;} -.canvas.canvas-overlay {z-index: 9;} -.canvas.onion-skin-canvas {z-index: 10;} -.canvas.layers-above-canvas {z-index: 11;} - .image-link { color : gold; } @@ -188,10 +50,3 @@ body { .pull-left { left:0; } - -.cursor-coordinates { - color:#888; - font-size:12px; - font-weight:bold; - font-family:Courier; -} \ No newline at end of file diff --git a/src/css/tools.css b/src/css/tools.css index c27716a5..89a2e907 100644 --- a/src/css/tools.css +++ b/src/css/tools.css @@ -1,10 +1,3 @@ - -.tools-wrapper, -.options-wrapper, -.palette-wrapper { - float: left; -} - .tool-icon { position : relative; cursor : pointer; @@ -88,8 +81,8 @@ .tool-icon.tool-lighten { background-image: url(../img/tools/lighten.png); - background-size: 30px 30px; background-position: 8px 8px; + background-size: 30px 30px; } .tool-icon.tool-colorpicker { @@ -103,6 +96,24 @@ background-size: 36px 36px; } +.tool-icon.tool-flip { + background-image: url(../img/tools/flip.png); + background-position: 7px 11px; + background-size: 32px; +} + +.tool-icon.tool-rotate { + background-image: url(../img/tools/rotate.png); + background-position: 10px 9px; + background-size: 26px; +} + +.tool-icon.tool-clone { + background-image: url(../img/tools/clone.png); + background-position: 9px 15px; + background-size: 30px; +} + /* * Tool cursors: */ diff --git a/src/css/transformations.css b/src/css/transformations.css new file mode 100644 index 00000000..13c7c8da --- /dev/null +++ b/src/css/transformations.css @@ -0,0 +1,3 @@ +.transformations-container .tool-icon { + float:left; +} \ No newline at end of file diff --git a/src/img/tools/clone.png b/src/img/tools/clone.png new file mode 100644 index 00000000..ca02ff71 Binary files /dev/null and b/src/img/tools/clone.png differ diff --git a/src/img/tools/flip.png b/src/img/tools/flip.png new file mode 100644 index 00000000..c2fbc8c8 Binary files /dev/null and b/src/img/tools/flip.png differ diff --git a/src/img/tools/rotate.png b/src/img/tools/rotate.png new file mode 100644 index 00000000..cea4c5cb Binary files /dev/null and b/src/img/tools/rotate.png differ diff --git a/src/index.html b/src/index.html index 99b1e0e7..03672105 100644 --- a/src/index.html +++ b/src/index.html @@ -44,6 +44,7 @@
+
diff --git a/src/js/app.js b/src/js/app.js index fe8eb764..8d626e02 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -87,6 +87,9 @@ this.notificationController = new pskl.controller.NotificationController(); this.notificationController.init(); + this.transformationsController = new pskl.controller.TransformationsController(); + this.transformationsController.init(); + this.progressBarController = new pskl.controller.ProgressBarController(); this.progressBarController.init(); diff --git a/src/js/controller/ToolController.js b/src/js/controller/ToolController.js index 270718c8..d21e4c10 100644 --- a/src/js/controller/ToolController.js +++ b/src/js/controller/ToolController.js @@ -7,23 +7,22 @@ }; this.tools = [ - toDescriptor('simplePen', 'P', new pskl.drawingtools.SimplePen()), - toDescriptor('verticalMirrorPen', 'V', new pskl.drawingtools.VerticalMirrorPen()), - toDescriptor('paintBucket', 'B', new pskl.drawingtools.PaintBucket()), - toDescriptor('colorSwap', 'A', new pskl.drawingtools.ColorSwap()), - toDescriptor('eraser', 'E', new pskl.drawingtools.Eraser()), - toDescriptor('stroke', 'L', new pskl.drawingtools.Stroke()), - toDescriptor('rectangle', 'R', new pskl.drawingtools.Rectangle()), - toDescriptor('circle', 'C', new pskl.drawingtools.Circle()), - toDescriptor('move', 'M', new pskl.drawingtools.Move()), - toDescriptor('rectangleSelect', 'S', new pskl.drawingtools.RectangleSelect()), - toDescriptor('shapeSelect', 'Z', new pskl.drawingtools.ShapeSelect()), - toDescriptor('lighten', 'U', new pskl.drawingtools.Lighten()), - toDescriptor('colorPicker', 'O', new pskl.drawingtools.ColorPicker()) + toDescriptor('simplePen', 'P', new pskl.tools.drawing.SimplePen()), + toDescriptor('verticalMirrorPen', 'V', new pskl.tools.drawing.VerticalMirrorPen()), + toDescriptor('paintBucket', 'B', new pskl.tools.drawing.PaintBucket()), + toDescriptor('colorSwap', 'A', new pskl.tools.drawing.ColorSwap()), + toDescriptor('eraser', 'E', new pskl.tools.drawing.Eraser()), + toDescriptor('stroke', 'L', new pskl.tools.drawing.Stroke()), + toDescriptor('rectangle', 'R', new pskl.tools.drawing.Rectangle()), + toDescriptor('circle', 'C', new pskl.tools.drawing.Circle()), + toDescriptor('move', 'M', new pskl.tools.drawing.Move()), + toDescriptor('rectangleSelect', 'S', new pskl.tools.drawing.RectangleSelect()), + toDescriptor('shapeSelect', 'Z', new pskl.tools.drawing.ShapeSelect()), + toDescriptor('lighten', 'U', new pskl.tools.drawing.Lighten()), + toDescriptor('colorPicker', 'O', new pskl.tools.drawing.ColorPicker()) ]; - this.currentSelectedTool = this.tools[0]; - this.previousSelectedTool = this.tools[0]; + this.toolIconRenderer = new pskl.tools.IconMarkupRenderer(); }; /** @@ -50,7 +49,7 @@ var previousSelectedToolClass = stage.data("selected-tool-class"); if(previousSelectedToolClass) { stage.removeClass(previousSelectedToolClass); - stage.removeClass(pskl.drawingtools.Move.TOOL_ID); + stage.removeClass(pskl.tools.drawing.Move.TOOL_ID); } stage.addClass(tool.instance.toolId); stage.data("selected-tool-class", tool.instance.toolId); @@ -105,43 +104,21 @@ }; ns.ToolController.prototype.getToolById_ = function (toolId) { - for(var i = 0 ; i < this.tools.length ; i++) { - var tool = this.tools[i]; - if (tool.instance.toolId == toolId) { - return tool; - } - } - return null; + return pskl.utils.Array.find(this.tools, function (tool) { + return tool.instance.toolId == toolId; + }); }; /** * @private */ ns.ToolController.prototype.createToolsDom_ = function() { - var toolMarkup = ''; + var html = ''; for(var i = 0 ; i < this.tools.length ; i++) { - toolMarkup += this.getToolMarkup_(this.tools[i]); + var tool = this.tools[i]; + html += this.toolIconRenderer.render(tool.instance, tool.shortcut); } - $('#tools-container').html(toolMarkup); - }; - - /** - * @private - */ - ns.ToolController.prototype.getToolMarkup_ = function(tool) { - var toolId = tool.instance.toolId; - - var classList = ['tool-icon', toolId]; - if (this.currentSelectedTool == tool) { - classList.push('selected'); - } - - var tpl = pskl.utils.Template.get('drawing-tool-item-template'); - return pskl.utils.Template.replace(tpl, { - cssclass : classList.join(' '), - toolid : toolId, - title : tool.instance.getTooltipText(tool.shortcut) - }); + $('#tools-container').html(html); }; ns.ToolController.prototype.addKeyboardShortcuts_ = function () { diff --git a/src/js/controller/TransformationsController.js b/src/js/controller/TransformationsController.js new file mode 100644 index 00000000..d1e3a71d --- /dev/null +++ b/src/js/controller/TransformationsController.js @@ -0,0 +1,42 @@ +(function () { + var ns = $.namespace('pskl.controller'); + + ns.TransformationsController = function () { + + var toDescriptor = function (id, shortcut, instance) { + return {id:id, shortcut:shortcut, instance:instance}; + }; + + this.tools = [ + toDescriptor('flip', '', new pskl.tools.transform.Flip()), + toDescriptor('rotate', '', new pskl.tools.transform.Rotate()), + toDescriptor('clone', '', new pskl.tools.transform.Clone()) + ]; + + this.toolIconRenderer = new pskl.tools.IconMarkupRenderer(); + }; + + ns.TransformationsController.prototype.init = function () { + var container = document.querySelector('.transformations-container'); + this.toolsContainer = container.querySelector('.tools-wrapper'); + container.addEventListener('click', this.onTransformationClick.bind(this)); + this.createToolsDom_(); + }; + + + ns.TransformationsController.prototype.onTransformationClick = function (evt) { + var toolId = evt.target.dataset.toolId; + this.tools.forEach(function (tool) { + if (tool.instance.toolId === toolId) { + tool.instance.apply(evt); + } + }.bind(this)); + }; + + ns.TransformationsController.prototype.createToolsDom_ = function() { + var html = this.tools.reduce(function (p, tool) { + return p + this.toolIconRenderer.render(tool.instance, tool.shortcut, 'left'); + }.bind(this), ''); + this.toolsContainer.innerHTML = html; + }; +})(); \ No newline at end of file diff --git a/src/js/controller/dialogs/CreatePaletteController.js b/src/js/controller/dialogs/CreatePaletteController.js index fa777fcc..ba729897 100644 --- a/src/js/controller/dialogs/CreatePaletteController.js +++ b/src/js/controller/dialogs/CreatePaletteController.js @@ -27,7 +27,7 @@ importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this)); var colorsListContainer = document.querySelector('.colors-container'); - this.colorsListWidget = new pskl.controller.widgets.ColorsList(colorsListContainer); + this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer); var palette; var isCurrentColorsPalette = paletteId == Constants.CURRENT_COLORS_PALETTE_ID; diff --git a/src/js/selection/SelectionManager.js b/src/js/selection/SelectionManager.js index 2088b36a..e6a90214 100644 --- a/src/js/selection/SelectionManager.js +++ b/src/js/selection/SelectionManager.js @@ -41,7 +41,7 @@ * @private */ ns.SelectionManager.prototype.onToolSelected_ = function(evt, tool) { - var isSelectionTool = tool instanceof pskl.drawingtools.BaseSelect; + var isSelectionTool = tool instanceof pskl.tools.drawing.BaseSelect; if(!isSelectionTool) { this.cleanSelection_(); } diff --git a/src/js/tools/IconMarkupRenderer.js b/src/js/tools/IconMarkupRenderer.js new file mode 100644 index 00000000..e4979283 --- /dev/null +++ b/src/js/tools/IconMarkupRenderer.js @@ -0,0 +1,49 @@ +(function () { + var ns = $.namespace('pskl.tools'); + + ns.IconMarkupRenderer = function () {}; + + ns.IconMarkupRenderer.prototype.render = function (tool, shortcut, tooltipPosition) { + tooltipPosition = tooltipPosition || 'right'; + shortcut = shortcut ? '(' + shortcut + ')' : ''; + var tpl = pskl.utils.Template.get('drawingTool-item-template'); + return pskl.utils.Template.replace(tpl, { + cssclass : ['tool-icon', tool.toolId].join(' '), + toolid : tool.toolId, + title : this.getTooltipText(tool, shortcut), + tooltipposition : tooltipPosition + }); + }; + + ns.IconMarkupRenderer.prototype.getTooltipText = function(tool, shortcut) { + var descriptors = tool.tooltipDescriptors; + var tpl = pskl.utils.Template.get('drawingTool-tooltipContainer-template'); + return pskl.utils.Template.replace(tpl, { + helptext : tool.getHelpText(), + shortcut : shortcut, + descriptors : this.formatToolDescriptors_(descriptors) + }); + }; + + + ns.IconMarkupRenderer.prototype.formatToolDescriptors_ = function(descriptors) { + descriptors = descriptors || []; + return descriptors.reduce(function (p, descriptor) { + return p += this.formatToolDescriptor_(descriptor); + }.bind(this), ''); + }; + + ns.IconMarkupRenderer.prototype.formatToolDescriptor_ = function(descriptor) { + var tpl; + if (descriptor.key) { + tpl = pskl.utils.Template.get('drawingTool-tooltipDescriptor-template'); + descriptor.key = descriptor.key.toUpperCase(); + if (pskl.utils.UserAgent.isMac) { + descriptor.key = descriptor.key.replace('CTRL', 'CMD'); + } + } else { + tpl = pskl.utils.Template.get('drawingTool-simpleTooltipDescriptor-template'); + } + return pskl.utils.Template.replace(tpl, descriptor); + }; +})(); \ No newline at end of file diff --git a/src/js/tools/Tool.js b/src/js/tools/Tool.js new file mode 100644 index 00000000..a0a476fe --- /dev/null +++ b/src/js/tools/Tool.js @@ -0,0 +1,17 @@ +(function () { + var ns = $.namespace('pskl.tools'); + + ns.Tool = function () { + this.toolId = "tool"; + this.helpText = "Abstract tool"; + this.tooltipDescriptors = []; + }; + + ns.Tool.prototype.getHelpText = function() { + return this.helpText; + }; + + ns.Tool.prototype.getId = function() { + return this.toolId; + }; +})(); \ No newline at end of file diff --git a/src/js/drawingtools/BaseTool.js b/src/js/tools/drawing/BaseTool.js similarity index 68% rename from src/js/drawingtools/BaseTool.js rename to src/js/tools/drawing/BaseTool.js index 2a364c2f..ea6480bb 100644 --- a/src/js/drawingtools/BaseTool.js +++ b/src/js/tools/drawing/BaseTool.js @@ -1,15 +1,18 @@ /** - * @provide pskl.drawingtools.BaseTool + * @provide pskl.tools.drawing.BaseTool * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.BaseTool = function() { + pskl.tool.Tool.call(this); this.toolId = "tool-base"; }; + pskl.utils.inherit(ns.BaseTool, pskl.tools.Tool); + ns.BaseTool.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {}; ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {}; @@ -58,41 +61,6 @@ }); }; - ns.BaseTool.prototype.getHelpText = function() { - return this.shortHelpText || this.helpText; - }; - - ns.BaseTool.prototype.getTooltipText = function(shortcut) { - var tpl = pskl.utils.Template.get('drawing-tool-tooltip-container-template'); - - var descriptors = ""; - if (Array.isArray(this.tooltipDescriptors)) { - this.tooltipDescriptors.forEach(function (descriptor) { - descriptors += this.getTooltipDescription(descriptor); - }.bind(this)); - } - - return pskl.utils.Template.replace(tpl, { - helptext : this.getHelpText(), - shortcut : shortcut, - descriptors : descriptors - }); - }; - - ns.BaseTool.prototype.getTooltipDescription = function(descriptor) { - var tpl; - if (descriptor.key) { - tpl = pskl.utils.Template.get('drawing-tool-tooltip-descriptor-template'); - descriptor.key = descriptor.key.toUpperCase(); - if (pskl.utils.UserAgent.isMac) { - descriptor.key = descriptor.key.replace('CTRL', 'CMD'); - } - } else { - tpl = pskl.utils.Template.get('drawing-tool-tooltip-descriptor-simple-template'); - } - return pskl.utils.Template.replace(tpl, descriptor); - }; - ns.BaseTool.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {}; /** diff --git a/src/js/drawingtools/Circle.js b/src/js/tools/drawing/Circle.js similarity index 91% rename from src/js/drawingtools/Circle.js rename to src/js/tools/drawing/Circle.js index 3b2f7da2..53bcdb2d 100644 --- a/src/js/drawingtools/Circle.js +++ b/src/js/tools/drawing/Circle.js @@ -1,52 +1,52 @@ -/** - * @provide pskl.drawingtools.Circle - * - * @require pskl.utils - */ -(function() { - var ns = $.namespace("pskl.drawingtools"); - - ns.Circle = function() { - ns.ShapeTool.call(this); - - this.toolId = "tool-circle"; - - this.helpText = "Circle tool"; - }; - - pskl.utils.inherit(ns.Circle, ns.ShapeTool); - - ns.Circle.prototype.draw_ = function (col, row, color, targetFrame) { - var circlePoints = this.getCirclePixels_(this.startCol, this.startRow, col, row); - for(var i = 0; i< circlePoints.length; i++) { - // Change model: - targetFrame.setPixel(circlePoints[i].col, circlePoints[i].row, color); - } - }; - - ns.Circle.prototype.getCirclePixels_ = function (x0, y0, x1, y1) { - var coords = pskl.PixelUtils.getOrderedRectangleCoordinates(x0, y0, x1, y1); - var xC = (coords.x0 + coords.x1)/2; - var yC = (coords.y0 + coords.y1)/2; - - var rX = coords.x1 - xC; - var rY = coords.y1 - yC; - - var pixels = []; - var x, y, angle; - for (x = coords.x0 ; x < coords.x1 ; x++) { - angle = Math.acos((x - xC)/rX); - y = Math.round(rY * Math.sin(angle) + yC); - pixels.push({"col": x, "row": y}); - pixels.push({"col": 2*xC - x, "row": 2*yC - y}); - } - - for (y = coords.y0 ; y < coords.y1 ; y++) { - angle = Math.asin((y - yC)/rY); - x = Math.round(rX * Math.cos(angle) + xC); - pixels.push({"col": x, "row": y}); - pixels.push({"col": 2*xC - x, "row": 2*yC - y}); - } - return pixels; - }; -})(); +/** + * @provide pskl.tools.drawing.Circle + * + * @require pskl.utils + */ +(function() { + var ns = $.namespace("pskl.tools.drawing"); + + ns.Circle = function() { + ns.ShapeTool.call(this); + + this.toolId = "tool-circle"; + + this.helpText = "Circle tool"; + }; + + pskl.utils.inherit(ns.Circle, ns.ShapeTool); + + ns.Circle.prototype.draw_ = function (col, row, color, targetFrame) { + var circlePoints = this.getCirclePixels_(this.startCol, this.startRow, col, row); + for(var i = 0; i< circlePoints.length; i++) { + // Change model: + targetFrame.setPixel(circlePoints[i].col, circlePoints[i].row, color); + } + }; + + ns.Circle.prototype.getCirclePixels_ = function (x0, y0, x1, y1) { + var coords = pskl.PixelUtils.getOrderedRectangleCoordinates(x0, y0, x1, y1); + var xC = (coords.x0 + coords.x1)/2; + var yC = (coords.y0 + coords.y1)/2; + + var rX = coords.x1 - xC; + var rY = coords.y1 - yC; + + var pixels = []; + var x, y, angle; + for (x = coords.x0 ; x < coords.x1 ; x++) { + angle = Math.acos((x - xC)/rX); + y = Math.round(rY * Math.sin(angle) + yC); + pixels.push({"col": x, "row": y}); + pixels.push({"col": 2*xC - x, "row": 2*yC - y}); + } + + for (y = coords.y0 ; y < coords.y1 ; y++) { + angle = Math.asin((y - yC)/rY); + x = Math.round(rX * Math.cos(angle) + xC); + pixels.push({"col": x, "row": y}); + pixels.push({"col": 2*xC - x, "row": 2*yC - y}); + } + return pixels; + }; +})(); diff --git a/src/js/drawingtools/ColorPicker.js b/src/js/tools/drawing/ColorPicker.js similarity index 88% rename from src/js/drawingtools/ColorPicker.js rename to src/js/tools/drawing/ColorPicker.js index 5a0de4ee..b30a4d69 100644 --- a/src/js/drawingtools/ColorPicker.js +++ b/src/js/tools/drawing/ColorPicker.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.ColorPicker + * @provide pskl.tools.drawing.ColorPicker * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.ColorPicker = function() { this.toolId = "tool-colorpicker"; diff --git a/src/js/drawingtools/ColorSwap.js b/src/js/tools/drawing/ColorSwap.js similarity index 94% rename from src/js/drawingtools/ColorSwap.js rename to src/js/tools/drawing/ColorSwap.js index 47cc8e26..54de9813 100644 --- a/src/js/drawingtools/ColorSwap.js +++ b/src/js/tools/drawing/ColorSwap.js @@ -1,9 +1,9 @@ /** - * @provide pskl.drawingtools.ColorSwap + * @provide pskl.tools.drawing.ColorSwap * */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.ColorSwap = function() { this.toolId = "tool-colorswap"; diff --git a/src/js/drawingtools/Eraser.js b/src/js/tools/drawing/Eraser.js similarity index 89% rename from src/js/drawingtools/Eraser.js rename to src/js/tools/drawing/Eraser.js index 27243f7e..6a40b674 100644 --- a/src/js/drawingtools/Eraser.js +++ b/src/js/tools/drawing/Eraser.js @@ -1,11 +1,11 @@ /** - * @provide pskl.drawingtools.Eraser + * @provide pskl.tools.drawing.Eraser * * @require Constants * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.Eraser = function() { this.superclass.constructor.call(this); diff --git a/src/js/drawingtools/Lighten.js b/src/js/tools/drawing/Lighten.js similarity index 95% rename from src/js/drawingtools/Lighten.js rename to src/js/tools/drawing/Lighten.js index 4695169f..f6bba044 100644 --- a/src/js/drawingtools/Lighten.js +++ b/src/js/tools/drawing/Lighten.js @@ -1,11 +1,11 @@ /** - * @provide pskl.drawingtools.Eraser + * @provide pskl.tools.drawing.Eraser * * @require Constants * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); var DEFAULT_STEP = 3; ns.Lighten = function() { diff --git a/src/js/drawingtools/Move.js b/src/js/tools/drawing/Move.js similarity index 95% rename from src/js/drawingtools/Move.js rename to src/js/tools/drawing/Move.js index a40735fa..51479b54 100644 --- a/src/js/drawingtools/Move.js +++ b/src/js/tools/drawing/Move.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.Move + * @provide pskl.tools.drawing.Move * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.Move = function() { this.toolId = ns.Move.TOOL_ID; diff --git a/src/js/drawingtools/PaintBucket.js b/src/js/tools/drawing/PaintBucket.js similarity index 88% rename from src/js/drawingtools/PaintBucket.js rename to src/js/tools/drawing/PaintBucket.js index 357fb7cb..0e00663d 100644 --- a/src/js/drawingtools/PaintBucket.js +++ b/src/js/tools/drawing/PaintBucket.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.PaintBucket + * @provide pskl.tools.drawing.PaintBucket * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.PaintBucket = function() { this.toolId = "tool-paint-bucket"; diff --git a/src/js/drawingtools/Rectangle.js b/src/js/tools/drawing/Rectangle.js similarity index 81% rename from src/js/drawingtools/Rectangle.js rename to src/js/tools/drawing/Rectangle.js index 250da4b7..def6cace 100644 --- a/src/js/drawingtools/Rectangle.js +++ b/src/js/tools/drawing/Rectangle.js @@ -1,17 +1,17 @@ /** - * @provide pskl.drawingtools.Rectangle + * @provide pskl.tools.drawing.Rectangle * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.Rectangle = function() { ns.ShapeTool.call(this); this.toolId = "tool-rectangle"; - this.shortHelpText = "Rectangle tool"; + this.helpText = "Rectangle tool"; }; pskl.utils.inherit(ns.Rectangle, ns.ShapeTool); diff --git a/src/js/drawingtools/ShapeTool.js b/src/js/tools/drawing/ShapeTool.js similarity index 98% rename from src/js/drawingtools/ShapeTool.js rename to src/js/tools/drawing/ShapeTool.js index e0916171..771a70e6 100644 --- a/src/js/drawingtools/ShapeTool.js +++ b/src/js/tools/drawing/ShapeTool.js @@ -1,5 +1,5 @@ (function () { - var ns = $.namespace('pskl.drawingtools'); + var ns = $.namespace('pskl.tools.drawing'); /** * Abstract shape tool class, parent to all shape tools (rectangle, circle). * Shape tools should override only the draw_ method diff --git a/src/js/drawingtools/SimplePen.js b/src/js/tools/drawing/SimplePen.js similarity index 96% rename from src/js/drawingtools/SimplePen.js rename to src/js/tools/drawing/SimplePen.js index 993ca445..134ad231 100644 --- a/src/js/drawingtools/SimplePen.js +++ b/src/js/tools/drawing/SimplePen.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.SimplePen + * @provide pskl.tools.drawing.SimplePen * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.SimplePen = function() { this.toolId = "tool-pen"; diff --git a/src/js/drawingtools/Stroke.js b/src/js/tools/drawing/Stroke.js similarity index 97% rename from src/js/drawingtools/Stroke.js rename to src/js/tools/drawing/Stroke.js index 27c115ae..088a9aa5 100644 --- a/src/js/drawingtools/Stroke.js +++ b/src/js/tools/drawing/Stroke.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.Stroke + * @provide pskl.tools.drawing.Stroke * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.Stroke = function() { this.toolId = "tool-stroke"; diff --git a/src/js/drawingtools/VerticalMirrorPen.js b/src/js/tools/drawing/VerticalMirrorPen.js similarity index 97% rename from src/js/drawingtools/VerticalMirrorPen.js rename to src/js/tools/drawing/VerticalMirrorPen.js index e2d851a9..24d5a4a5 100644 --- a/src/js/drawingtools/VerticalMirrorPen.js +++ b/src/js/tools/drawing/VerticalMirrorPen.js @@ -1,5 +1,5 @@ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.VerticalMirrorPen = function() { this.superclass.constructor.call(this); diff --git a/src/js/drawingtools/selectiontools/BaseSelect.js b/src/js/tools/drawing/selection/BaseSelect.js similarity index 97% rename from src/js/drawingtools/selectiontools/BaseSelect.js rename to src/js/tools/drawing/selection/BaseSelect.js index ae33c364..2646ddf8 100644 --- a/src/js/drawingtools/selectiontools/BaseSelect.js +++ b/src/js/tools/drawing/selection/BaseSelect.js @@ -1,13 +1,13 @@ /** - * @provide pskl.drawingtools.BaseSelect + * @provide pskl.tools.drawing.BaseSelect * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.BaseSelect = function() { - this.secondaryToolId = pskl.drawingtools.Move.TOOL_ID; + this.secondaryToolId = pskl.tools.drawing.Move.TOOL_ID; this.BodyRoot = $('body'); // Select's first point coordinates (set in applyToolAt) diff --git a/src/js/drawingtools/selectiontools/RectangleSelect.js b/src/js/tools/drawing/selection/RectangleSelect.js similarity index 94% rename from src/js/drawingtools/selectiontools/RectangleSelect.js rename to src/js/tools/drawing/selection/RectangleSelect.js index 3abb4ba8..1f4843f6 100644 --- a/src/js/drawingtools/selectiontools/RectangleSelect.js +++ b/src/js/tools/drawing/selection/RectangleSelect.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.RectangleSelect + * @provide pskl.tools.drawing.RectangleSelect * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.RectangleSelect = function() { this.toolId = "tool-rectangle-select"; diff --git a/src/js/drawingtools/selectiontools/ShapeSelect.js b/src/js/tools/drawing/selection/ShapeSelect.js similarity index 91% rename from src/js/drawingtools/selectiontools/ShapeSelect.js rename to src/js/tools/drawing/selection/ShapeSelect.js index 4c829001..887d88ac 100644 --- a/src/js/drawingtools/selectiontools/ShapeSelect.js +++ b/src/js/tools/drawing/selection/ShapeSelect.js @@ -1,10 +1,10 @@ /** - * @provide pskl.drawingtools.ShapeSelect + * @provide pskl.tools.drawing.ShapeSelect * * @require pskl.utils */ (function() { - var ns = $.namespace("pskl.drawingtools"); + var ns = $.namespace("pskl.tools.drawing"); ns.ShapeSelect = function() { this.toolId = "tool-shape-select"; diff --git a/src/js/tools/transform/Clone.js b/src/js/tools/transform/Clone.js new file mode 100644 index 00000000..e648adb7 --- /dev/null +++ b/src/js/tools/transform/Clone.js @@ -0,0 +1,25 @@ +(function () { + var ns = $.namespace('pskl.tools.transform'); + + ns.Clone = function () { + this.toolId = "tool-clone"; + this.helpText = "Clone current layer to all frames"; + this.tooltipDescriptors = []; + }; + + pskl.utils.inherit(ns.Clone, ns.Transform); + + ns.Clone.prototype.apply = function (evt) { + var ref = pskl.app.piskelController.getCurrentFrame(); + var layer = pskl.app.piskelController.getCurrentLayer(); + layer.getFrames().forEach(function (frame) { + if (frame !== ref) { + frame.setPixels(ref.getPixels()); + } + }); + $.publish(Events.PISKEL_RESET); + $.publish(Events.PISKEL_SAVE_STATE, { + type : pskl.service.HistoryService.SNAPSHOT + }); + }; +})(); \ No newline at end of file diff --git a/src/js/tools/transform/Flip.js b/src/js/tools/transform/Flip.js new file mode 100644 index 00000000..95d2ec6c --- /dev/null +++ b/src/js/tools/transform/Flip.js @@ -0,0 +1,28 @@ +(function () { + var ns = $.namespace('pskl.tools.transform'); + + ns.Flip = function () { + this.toolId = "tool-flip"; + this.helpText = "Flip vertically"; + this.tooltipDescriptors = [ + {key : 'alt', description : 'Flip horizontally'}, + {key : 'ctrl', description : 'Apply to all layers'}, + {key : 'shift', description : 'Apply to all frames'} + ]; + }; + + pskl.utils.inherit(ns.Flip, ns.Transform); + + ns.Flip.prototype.applyToolOnFrame_ = function (frame, altKey) { + var axis; + + if (altKey) { + axis = pskl.utils.FrameTransform.HORIZONTAL; + } else { + axis = pskl.utils.FrameTransform.VERTICAL; + } + + pskl.utils.FrameTransform.flip(frame, axis); + }; + +})(); \ No newline at end of file diff --git a/src/js/tools/transform/Rotate.js b/src/js/tools/transform/Rotate.js new file mode 100644 index 00000000..082fdd27 --- /dev/null +++ b/src/js/tools/transform/Rotate.js @@ -0,0 +1,27 @@ +(function () { + var ns = $.namespace('pskl.tools.transform'); + + ns.Rotate = function () { + this.toolId = "tool-rotate"; + this.helpText = "Counter-clockwise rotation"; + this.tooltipDescriptors = [ + {key : 'alt', description : 'Clockwise rotation'}, + {key : 'ctrl', description : 'Apply to all layers'}, + {key : 'shift', description : 'Apply to all frames'}]; + }; + + pskl.utils.inherit(ns.Rotate, ns.Transform); + + ns.Rotate.prototype.applyToolOnFrame_ = function (frame, altKey) { + var direction; + + if (altKey) { + direction = pskl.utils.FrameTransform.CLOCKWISE; + } else { + direction = pskl.utils.FrameTransform.COUNTERCLOCKWISE; + } + + pskl.utils.FrameTransform.rotate(frame, direction); + }; + +})(); \ No newline at end of file diff --git a/src/js/tools/transform/Transform.js b/src/js/tools/transform/Transform.js new file mode 100644 index 00000000..7cd19f3d --- /dev/null +++ b/src/js/tools/transform/Transform.js @@ -0,0 +1,33 @@ +(function () { + var ns = $.namespace('pskl.tools.transform'); + + ns.Transform = function () { + this.toolId = "tool-transform"; + this.helpText = "Transform tool"; + this.tooltipDescriptors = []; + }; + + pskl.utils.inherit(ns.Transform, pskl.tools.Tool); + + ns.Transform.prototype.apply = function (evt) { + var allFrames = evt.shiftKey; + var allLayers = evt.ctrlKey; + this.applyTool_(evt.altKey, allFrames, allLayers); + }; + + ns.Transform.prototype.applyTool_ = function (altKey, allFrames, allLayers) { + var currentFrameIndex = pskl.app.piskelController.getCurrentFrameIndex(); + var layers = allLayers ? pskl.app.piskelController.getLayers(): [pskl.app.piskelController.getCurrentLayer()]; + layers.forEach(function (layer) { + var frames = allFrames ? layer.getFrames(): [layer.getFrameAt(currentFrameIndex)]; + frames.forEach(function (frame) { + this.applyToolOnFrame_(frame, altKey); + }.bind(this)); + }.bind(this)); + $.publish(Events.PISKEL_RESET); + $.publish(Events.PISKEL_SAVE_STATE, { + type : pskl.service.HistoryService.SNAPSHOT + }); + }; + +})(); \ No newline at end of file diff --git a/src/js/utils/Array.js b/src/js/utils/Array.js new file mode 100644 index 00000000..efe69c1b --- /dev/null +++ b/src/js/utils/Array.js @@ -0,0 +1,16 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + ns.Array = { + find : function (array, filterFn) { + var match = null; + array = Array.isArray(array) ? array : []; + var filtered = array.filter(filterFn); + if (filtered.length) { + match = filtered[0]; + } + return match; + } + }; + +})(); \ No newline at end of file diff --git a/src/js/utils/FrameTransform.js b/src/js/utils/FrameTransform.js new file mode 100644 index 00000000..864cb7ed --- /dev/null +++ b/src/js/utils/FrameTransform.js @@ -0,0 +1,65 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + ns.FrameTransform = { + VERTICAL : 'vertical', + HORIZONTAL : 'HORIZONTAL', + flip : function (frame, axis) { + var clone = frame.clone(); + var w = frame.getWidth(); + var h = frame.getHeight(); + + clone.forEachPixel(function (color, x, y) { + if (axis === ns.FrameTransform.VERTICAL) { + x = w-x-1; + } else if (axis === ns.FrameTransform.HORIZONTAL) { + y = h-y-1; + } + frame.pixels[x][y] = color; + }); + frame.version++; + return frame; + }, + + CLOCKWISE : 'clockwise', + COUNTERCLOCKWISE : 'counterclockwise', + rotate : function (frame, direction) { + var clone = frame.clone(); + var w = frame.getWidth(); + var h = frame.getHeight(); + + var max = Math.max(w, h); + var xDelta = Math.ceil((max - w)/2); + var yDelta = Math.ceil((max - h)/2); + + frame.forEachPixel(function (color, x, y) { + var _x = x, _y = y; + + // Convert to square coords + x = x + xDelta; + y = y + yDelta; + + // Perform the rotation + var tmpX = x, tmpY = y; + if (direction === ns.FrameTransform.CLOCKWISE) { + x = tmpY; + y = max - 1 - tmpX; + } else if (direction === ns.FrameTransform.COUNTERCLOCKWISE) { + y = tmpX; + x = max - 1 - tmpY; + } + + // Convert the coordinates back to the rectangular grid + x = x - xDelta; + y = y - yDelta; + if (clone.containsPixel(x, y)) { + frame.pixels[_x][_y] = clone.getPixel(x, y); + } else { + frame.pixels[_x][_y] = Constants.TRANSPARENT_COLOR; + } + }); + frame.version++; + return frame; + } + }; +})(); \ No newline at end of file diff --git a/src/js/utils/FrameUtils.js b/src/js/utils/FrameUtils.js index a2094d43..4fa36252 100644 --- a/src/js/utils/FrameUtils.js +++ b/src/js/utils/FrameUtils.js @@ -2,11 +2,17 @@ var ns = $.namespace('pskl.utils'); var colorCache = {}; ns.FrameUtils = { - toImage : function (frame, zoom, bgColor) { + /** + * Render a Frame object as an image. + * Can optionally scale it (zoom) + * @param {Frame} frame + * @param {Number} zoom + * @return {Image} + */ + toImage : function (frame, zoom) { zoom = zoom || 1; - bgColor = bgColor || Constants.TRANSPARENT_COLOR; var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, zoom); - canvasRenderer.drawTransparentAs(bgColor); + canvasRenderer.drawTransparentAs(Constants.TRANSPARENT_COLOR); return canvasRenderer.render(); }, @@ -23,9 +29,9 @@ }, mergeFrames_ : function (frameA, frameB) { - frameB.forEachPixel(function (p, col, row) { - if (p != Constants.TRANSPARENT_COLOR) { - frameA.setPixel(col, row, p); + frameB.forEachPixel(function (color, col, row) { + if (color != Constants.TRANSPARENT_COLOR) { + frameA.setPixel(col, row, color); } }); }, diff --git a/src/js/utils/TooltipFormatter.js b/src/js/utils/TooltipFormatter.js new file mode 100644 index 00000000..e70ba7d7 --- /dev/null +++ b/src/js/utils/TooltipFormatter.js @@ -0,0 +1,37 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + ns.TooltipFormatter = {}; + + + ns.TooltipFormatter.formatForTool = function(shortcut, descriptors, helpText) { + var tpl = pskl.utils.Template.get('drawingTool-tooltipContainer-template'); + return pskl.utils.Template.replace(tpl, { + helptext : helpText, + shortcut : shortcut, + descriptors : this.formatToolDescriptors_(descriptors) + }); + }; + + + ns.TooltipFormatter.formatToolDescriptors_ = function(descriptors) { + descriptors = descriptors || []; + return descriptors.reduce(function (p, descriptor) { + return p += this.formatToolDescriptor_(descriptor); + }.bind(this), ''); + }; + + ns.TooltipFormatter.formatToolDescriptor_ = function(descriptor) { + var tpl; + if (descriptor.key) { + tpl = pskl.utils.Template.get('drawingTool-tooltipDescriptor-template'); + descriptor.key = descriptor.key.toUpperCase(); + if (pskl.utils.UserAgent.isMac) { + descriptor.key = descriptor.key.replace('CTRL', 'CMD'); + } + } else { + tpl = pskl.utils.Template.get('drawingTool-simpleTooltipDescriptor-template'); + } + return pskl.utils.Template.replace(tpl, descriptor); + }; +})(); \ No newline at end of file diff --git a/src/js/controller/widgets/ColorsList.js b/src/js/widgets/ColorsList.js similarity index 96% rename from src/js/controller/widgets/ColorsList.js rename to src/js/widgets/ColorsList.js index 1c137b5c..b4e7b795 100644 --- a/src/js/controller/widgets/ColorsList.js +++ b/src/js/widgets/ColorsList.js @@ -1,5 +1,5 @@ (function () { - var ns = $.namespace('pskl.controller.widgets'); + var ns = $.namespace('pskl.widgets'); var DEFAULT_COLOR = '#000000'; @@ -20,7 +20,7 @@ this.colorsList.addEventListener('click', this.onColorContainerClick_.bind(this)); var colorPickerContainer = container.querySelector('.color-picker-container'); - this.hslRgbColorPicker = new pskl.controller.widgets.HslRgbColorPicker(colorPickerContainer, this.onColorUpdated_.bind(this)); + this.hslRgbColorPicker = new pskl.widgets.HslRgbColorPicker(colorPickerContainer, this.onColorUpdated_.bind(this)); this.hslRgbColorPicker.init(); }; diff --git a/src/js/controller/widgets/HslRgbColorPicker.js b/src/js/widgets/HslRgbColorPicker.js similarity index 99% rename from src/js/controller/widgets/HslRgbColorPicker.js rename to src/js/widgets/HslRgbColorPicker.js index f7e539d5..744eb7fe 100644 --- a/src/js/controller/widgets/HslRgbColorPicker.js +++ b/src/js/widgets/HslRgbColorPicker.js @@ -1,5 +1,5 @@ (function () { - var ns = $.namespace('pskl.controller.widgets'); + var ns = $.namespace('pskl.widgets'); ns.HslRgbColorPicker = function (container, colorUpdatedCallback) { this.container = container; diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index cbfedc78..e1c2e2bb 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -11,6 +11,7 @@ // Libraries "js/utils/core.js", "js/utils/UserAgent.js", + "js/utils/Array.js", "js/utils/Base64.js", "js/utils/BlobUtils.js", "js/utils/CanvasUtils.js", @@ -18,12 +19,14 @@ "js/utils/Dom.js", "js/utils/Math.js", "js/utils/FileUtils.js", + "js/utils/FrameTransform.js", "js/utils/FrameUtils.js", "js/utils/LayerUtils.js", "js/utils/ImageResizer.js", "js/utils/PixelUtils.js", "js/utils/PiskelFileUtils.js", "js/utils/Template.js", + "js/utils/TooltipFormatter.js", "js/utils/UserSettings.js", "js/utils/Uuid.js", "js/utils/WorkerUtils.js", @@ -88,6 +91,7 @@ "js/controller/PalettesListController.js", "js/controller/ProgressBarController.js", "js/controller/NotificationController.js", + "js/controller/TransformationsController.js", "js/controller/CanvasBackgroundController.js", // Settings sub-controllers @@ -112,9 +116,9 @@ // Dialogs controller "js/controller/dialogs/DialogsController.js", - // Widget controller - "js/controller/widgets/ColorsList.js", - "js/controller/widgets/HslRgbColorPicker.js", + // Widgets + "js/widgets/ColorsList.js", + "js/widgets/HslRgbColorPicker.js", // Services "js/service/LocalStorageService.js", @@ -142,22 +146,28 @@ "js/service/FileDropperService.js", // Tools - "js/drawingtools/BaseTool.js", - "js/drawingtools/ShapeTool.js", - "js/drawingtools/SimplePen.js", - "js/drawingtools/Lighten.js", - "js/drawingtools/VerticalMirrorPen.js", - "js/drawingtools/Eraser.js", - "js/drawingtools/Stroke.js", - "js/drawingtools/PaintBucket.js", - "js/drawingtools/Rectangle.js", - "js/drawingtools/Circle.js", - "js/drawingtools/Move.js", - "js/drawingtools/selectiontools/BaseSelect.js", - "js/drawingtools/selectiontools/RectangleSelect.js", - "js/drawingtools/selectiontools/ShapeSelect.js", - "js/drawingtools/ColorPicker.js", - "js/drawingtools/ColorSwap.js", + "js/tools/Tool.js", + "js/tools/IconMarkupRenderer.js", + "js/tools/drawing/BaseTool.js", + "js/tools/drawing/ShapeTool.js", + "js/tools/drawing/SimplePen.js", + "js/tools/drawing/Lighten.js", + "js/tools/drawing/VerticalMirrorPen.js", + "js/tools/drawing/Eraser.js", + "js/tools/drawing/Stroke.js", + "js/tools/drawing/PaintBucket.js", + "js/tools/drawing/Rectangle.js", + "js/tools/drawing/Circle.js", + "js/tools/drawing/Move.js", + "js/tools/drawing/selection/BaseSelect.js", + "js/tools/drawing/selection/RectangleSelect.js", + "js/tools/drawing/selection/ShapeSelect.js", + "js/tools/drawing/ColorPicker.js", + "js/tools/drawing/ColorSwap.js", + "js/tools/transform/Transform.js", + "js/tools/transform/Clone.js", + "js/tools/transform/Flip.js", + "js/tools/transform/Rotate.js", // Devtools "js/devtools/DrawingTestPlayer.js", diff --git a/src/piskel-style-list.js b/src/piskel-style-list.js index fdb8e0c9..70a6a84f 100644 --- a/src/piskel-style-list.js +++ b/src/piskel-style-list.js @@ -3,6 +3,7 @@ (typeof exports != "undefined" ? exports : pskl_exports).styles = [ "css/reset.css", "css/style.css", + "css/layout.css", "css/font-icon.css", "css/forms.css", "css/settings.css", @@ -21,6 +22,7 @@ "css/toolbox-layers-list.css", "css/toolbox-palettes-list.css", "css/toolbox-animated-preview.css", + "css/transformations.css", "css/spectrum/spectrum.css", "css/spectrum/spectrum-overrides.css", "css/bootstrap/bootstrap.css", diff --git a/src/templates/drawing-tools.html b/src/templates/drawing-tools.html index 623e7141..20fb8290 100644 --- a/src/templates/drawing-tools.html +++ b/src/templates/drawing-tools.html @@ -34,20 +34,20 @@ - - - -