Added mirror transformation

This commit is contained in:
jdescottes 2014-11-19 23:00:25 +01:00
parent 54837d0e21
commit c8dae1cb79
16 changed files with 335 additions and 167 deletions

88
misc/icons/SVG/flip.svg Normal file
View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="770.71875"
height="581.4375"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="mirror.svg"
inkscape:export-filename="C:\Development\git\piskel\src\img\tools\flip.png"
inkscape:export-xdpi="35.446629"
inkscape:export-ydpi="35.446629">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="612.40785"
inkscape:cy="222.08964"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1148"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-63.5625,-233.7818)">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 359.2768,233.7907 -295.7143,581.4286 295.7143,0 z"
id="rect2987"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:export-filename="C:\Development\git\piskel\src\img\tools\flip.png"
inkscape:export-xdpi="35.446629"
inkscape:export-ydpi="35.446629" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 538.5625,233.7818 295.71875,581.4375 -295.71875,0 0,-581.4375 z m 29.125,117.4375 0,434.28125 218.59375,0 L 567.6875,351.2193 z"
id="rect2987-1"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Development\git\piskel\src\img\tools\flip.png"
inkscape:export-xdpi="35.446629"
inkscape:export-ydpi="35.446629" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 435.5625,233.93805 0,41.28125 25.71875,0 0,-41.28125 -25.71875,0 z m 0,91.28125 0,40 25.71875,0 0,-40 -25.71875,0 z m 0,90 0,40 25.71875,0 0,-40 -25.71875,0 z m 0,90 0,40 25.71875,0 0,-40 -25.71875,0 z m 0,90 0,40 25.71875,0 0,-40 -25.71875,0 z m 0,90 0,40 25.71875,0 0,-40 -25.71875,0 z m 0,90 0,40 25.71875,0 0,-40 -25.71875,0 z"
id="rect3796"
inkscape:export-filename="C:\Development\git\piskel\src\img\tools\flip.png"
inkscape:export-xdpi="35.446629"
inkscape:export-ydpi="35.446629"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

154
src/css/layout.css Normal file
View file

@ -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;}

View file

@ -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;
}

View file

@ -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,12 @@
background-size: 36px 36px;
}
.tool-icon.tool-flip {
background-image: url(../img/tools/flip.png);
background-position: 6px 6px;
background-size: 32px 32px;
}
/*
* Tool cursors:
*/

View file

@ -0,0 +1,3 @@
.transformations-container .tool-icon {
float:left;
}

BIN
src/img/tools/flip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -44,6 +44,7 @@
<div class="column right-column">
<iframe src="templates/preview.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/layers-list.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/transformations.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/palettes-list.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<div class="pull-bottom cursor-coordinates"></div>
</div>

View file

@ -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();

View file

@ -136,7 +136,7 @@
classList.push('selected');
}
var tpl = pskl.utils.Template.get('drawing-tool-item-template');
var tpl = pskl.utils.Template.get('drawingTool-item-template');
return pskl.utils.Template.replace(tpl, {
cssclass : classList.join(' '),
toolid : toolId,

View file

@ -0,0 +1,56 @@
(function () {
var ns = $.namespace('pskl.controller');
ns.TransformationsController = function () {
};
ns.TransformationsController.prototype.init = function () {
var container = document.querySelector('.transformations-container');
container.addEventListener('click', this.onTransformationClick.bind(this));
};
ns.TransformationsController.prototype.onTransformationClick = function (evt) {
var target = evt.target;
if (target.dataset.transformationId === 'flip') {
var allFrames = evt.shiftKey;
var allLayers = evt.ctrlKey;
if (evt.altKey) {
this.flip('vertical', allFrames, allLayers);
} else {
this.flip('horizontal', allFrames, allLayers);
}
}
};
ns.TransformationsController.prototype.flipFrame_ = function (frame, axis) {
var clone = frame.clone();
var w = frame.getWidth();
var h = frame.getHeight();
clone.forEachPixel(function (color, x, y) {
if (axis === 'horizontal') {
x = w-x-1;
} else if (axis === 'vertical') {
y = h-y-1;
}
frame.pixels[x][y] = color;
});
frame.version++;
};
ns.TransformationsController.prototype.flip = function (axis, 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.flipFrame_(frame, axis);
}.bind(this));
}.bind(this));
$.publish(Events.PISKEL_RESET);
$.publish(Events.PISKEL_SAVE_STATE, {
type : pskl.service.HistoryService.SNAPSHOT
});
};
})();

View file

@ -63,7 +63,7 @@
};
ns.BaseTool.prototype.getTooltipText = function(shortcut) {
var tpl = pskl.utils.Template.get('drawing-tool-tooltip-container-template');
var tpl = pskl.utils.Template.get('drawingTool-tooltipContainer-template');
var descriptors = "";
if (Array.isArray(this.tooltipDescriptors)) {
@ -82,13 +82,13 @@
ns.BaseTool.prototype.getTooltipDescription = function(descriptor) {
var tpl;
if (descriptor.key) {
tpl = pskl.utils.Template.get('drawing-tool-tooltip-descriptor-template');
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('drawing-tool-tooltip-descriptor-simple-template');
tpl = pskl.utils.Template.get('drawingTool-simpleTooltipDescriptor-template');
}
return pskl.utils.Template.replace(tpl, descriptor);
};

View file

@ -87,6 +87,7 @@
"js/controller/PalettesListController.js",
"js/controller/ProgressBarController.js",
"js/controller/NotificationController.js",
"js/controller/TransformationsController.js",
"js/controller/CanvasBackgroundController.js",
// Settings sub-controllers

View file

@ -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",

View file

@ -34,12 +34,12 @@
<!-- Templates -->
<!-- Drawing tool icon-button -->
<script type="text/template" id="drawing-tool-item-template">
<script type="text/template" id="drawingTool-item-template">
<li rel="tooltip" data-placement="right" class="{{cssclass}}" data-tool-id="{{toolid}}" title="{{title}}"></li>
</script>
<!-- Drawing tool tooltip container -->
<script type="text/template" id="drawing-tool-tooltip-container-template">
<script type="text/template" id="drawingTool-tooltipContainer-template">
<div class='tools-tooltip-container'>
<div>{{helptext}} <span class='tools-tooltip-shortcut'>({{shortcut}})</span></div>
{{descriptors}}
@ -47,7 +47,7 @@
</script>
<!-- Drawing tool tooltip line for modifier -->
<script type="text/template" id="drawing-tool-tooltip-descriptor-template">
<script type="text/template" id="drawingTool-tooltipDescriptor-template">
<div class='tools-tooltip-descriptor'>
<span class='tools-tooltip-descriptor-button'>{{key}}</span>
{{description}}
@ -55,7 +55,7 @@
</script>
<!-- Drawing tool tooltip line -->
<script type="text/template" id="drawing-tool-tooltip-descriptor-simple-template">
<script type="text/template" id="drawingTool-simpleTooltipDescriptor-template">
<div class='tools-tooltip-descriptor'>
{{description}}
</div>

View file

@ -1,8 +1,5 @@
<div class="toolbox-container palettes-list-container">
<h3 class="toolbox-title palettes-title"
style="overflow: hidden;height: 36px;box-sizing: border-box;border-bottom: 1px solid #444;">
<span style="line-height:20px ">Palettes</span>
</h3>
<h3 class="toolbox-title palettes-title">Palettes</h3>
<div class="palettes-list-actions">
<button
class="button palettes-list-button create-palette-button piskel-icon-plus" data-action="add"

View file

@ -0,0 +1,9 @@
<div class="toolbox-container transformations-container">
<h3 class="toolbox-title transformations-title">Transform</h3>
<ul class="tools-wrapper">
<li rel="tooltip" data-placement="right" class="tool-icon tool-flip" data-transformation-id="flip" title="flip"></li>
<li rel="tooltip" data-placement="right" class="tool-icon rotate" data-transformation-id="rotate" title="rotate"></li>
<li rel="tooltip" data-placement="right" class="tool-icon tool-flip" data-transformation-id="flip" title="flip"></li>
<li rel="tooltip" data-placement="right" class="tool-icon tool-flip" data-transformation-id="flip" title="flip"></li>
</ul>
</div>