Merge pull request #235 from juliandescottes/feature-add-effects
Feature add effects
88
misc/icons/SVG/flip.svg
Normal 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 |
BIN
misc/icons/noun-project/sheep/icon_8389.png
Normal file
After Width: | Height: | Size: 52 KiB |
41
misc/icons/noun-project/sheep/icon_8389.svg
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="99.997px" height="69.373px" viewBox="0 0 99.997 69.373" enable-background="new 0 0 99.997 69.373" xml:space="preserve">
|
||||
<path fill="#010101" d="M81.635,0.222c0.553-0.327,1.242-0.219,1.85-0.133c1.502,0.296,2.658,1.426,3.533,2.62
|
||||
c0.608-0.379,1.252-0.777,1.983-0.842c0.595-0.015,1.09,0.416,1.394,0.889c0.568,0.909,0.76,2.02,1.442,2.864
|
||||
C92,5.829,92.246,5.941,92.482,6.044c0.968,0.409,1.846,0.996,2.688,1.615c0.361,0.223,0.396,0.691,0.529,1.056
|
||||
c0.478,1.579,0.306,3.241,0.149,4.853c-0.035,0.812-0.104,1.659,0.172,2.438c0.42,0.954,1.229,1.655,1.746,2.547
|
||||
c1.191,2.13,2.146,4.467,2.229,6.937v0.088c-0.071,1.268-0.203,2.647-1.062,3.653c-0.707,0.846-1.85,1.101-2.896,1.223
|
||||
c-0.747,0.104-1.508,0.127-2.258,0.077c-1.912-0.275-3.812-0.628-5.724-0.911c-0.34-0.052-0.719-0.055-1,0.167
|
||||
c-0.391,0.281-0.494,0.786-0.537,1.235c-0.068,1.177,0.133,2.405-0.312,3.532c-0.227,0.604-0.768,0.999-1.266,1.371
|
||||
c-1.092,0.753-2.313,1.291-3.441,1.981c-0.164,0.115-0.125,0.348-0.125,0.521c0.075,0.916,0.332,1.821,0.253,2.747
|
||||
c-0.021,0.597-0.271,1.188-0.72,1.587c-0.768,0.709-1.434,1.519-2.068,2.346c-0.104,0.142-0.222,0.283-0.256,0.461
|
||||
c-0.264,1.272-0.385,2.576-0.74,3.83c-0.201,0.641-0.416,1.34-0.943,1.793c-0.633,0.492-1.456-0.342-2.098,0.164
|
||||
c-1.191,0.882-1.558,2.412-2.379,3.582c-0.469,0.595-1.104,1.039-1.805,1.319c-0.331,4.37-0.625,8.741-0.896,13.115h-5.166
|
||||
c0.16-2.783,0.32-5.567,0.486-8.351c0.203-1.728-0.097-3.444-0.312-5.152c-0.017-0.364-0.43-0.709-0.785-0.543
|
||||
c-1.037,0.3-2.131,0.459-3.204,0.289c-0.87-0.227-1.536-0.877-2.11-1.533c-1.765,1.695-4.326,2.275-6.712,2.025
|
||||
c-0.471-0.726-0.792-1.629-1.603-2.049c-0.539-0.324-1.198-0.155-1.729,0.098c-1.214,0.558-1.945,1.805-3.197,2.305
|
||||
c-1.1,0.51-2.359,0.188-3.41-0.291c-1.127-0.54-2.176-1.242-3.186-1.975c-0.52,0.236-0.837,0.728-1.123,1.195
|
||||
c-0.968,0.117-1.964,0.449-2.923,0.103c-1.548-0.399-2.625-1.652-3.94-2.472c-0.886,0.66-1.608,1.58-2.68,1.957
|
||||
c-0.698,0.24-1.468,0.399-2.196,0.207c-0.825-0.181-1.609-0.5-2.425-0.705c-0.27-0.078-0.558-0.037-0.807,0.082
|
||||
c-1.433,0.646-2.197,2.23-3.688,2.779c-0.307,0.148-0.632,0.043-0.936-0.047c-0.346,3.812-0.79,7.618-1.159,11.43
|
||||
c-1.811,0.006-3.623-0.002-5.434,0.004c-0.078-0.656-0.297-1.312-0.188-1.978c0.27-2.282,0.637-4.551,0.9-6.833
|
||||
c0.181-1.895-0.835-3.648-2.096-4.977c0.154-0.737-0.056-1.502-0.528-2.078c-1.24-1.65-3.362-2.342-4.546-4.043
|
||||
c-0.357-0.53-0.698-1.256-0.328-1.864c0.285-0.724,0.94-1.381,0.769-2.21c-0.04-0.262-0.165-0.502-0.347-0.691
|
||||
c-1.07-1.188-1.971-2.514-2.849-3.844c-0.403-0.59-0.372-1.338-0.438-2.02c-0.141-1.194,0.732-2.201,0.798-3.364
|
||||
c-0.196-0.665-0.84-1.073-1.192-1.654C0.638,31.785,0.077,30.231,0,28.62v-0.446c0.086-0.751,0.078-1.537,0.396-2.239
|
||||
c0.522-1.006,1.566-1.623,2.075-2.636c-0.222-0.968-0.747-1.833-0.966-2.799c-0.097-1.466,0.425-2.955,1.404-4.049
|
||||
c0.664-0.035,1.319-0.157,1.968-0.296c0.633-0.125,1.1-0.631,1.448-1.145c0.703-1.045,0.832-2.351,1.479-3.422
|
||||
c0.255-0.444,0.607-0.855,1.08-1.074c0.692-0.327,1.395-0.631,2.119-0.88c0.38-0.117,0.779-0.237,1.18-0.167
|
||||
c0.894,0.134,1.771,0.361,2.665,0.5c0.624,0.088,1.321-0.085,1.74-0.58c0.379-0.424,0.483-1.003,0.574-1.544
|
||||
c0.926-0.306,1.929-0.646,2.907-0.389c1.367,0.311,2.72,0.672,4.091,0.96c0.748-0.367,1.104-1.208,1.849-1.582
|
||||
c0.884-0.481,1.947-0.333,2.873-0.064c1.13,0.322,1.991,1.168,3.041,1.655c0.735-0.438,1.304-1.316,2.246-1.275
|
||||
c1.698,0.444,3.091,1.803,4.899,1.868c1.229,0.001,1.779-1.354,2.912-1.594c0.744-0.228,1.496,0.125,2.104,0.54
|
||||
c0.745,0.517,1.432,1.11,2.132,1.684c1.052-0.622,2.251-1.085,3.492-1.026c1.448,0.261,2.847,0.754,4.294,1.011
|
||||
c0.615-0.026,0.967-0.649,1.489-0.902c1.062-0.497,2.237-0.755,3.409-0.756c1.316,0.169,2.543,0.712,3.82,1.042
|
||||
c0.623-0.171,1.135-0.659,1.803-0.686c1.026-0.025,2.055-0.006,3.08-0.008c0.401-0.321,0.769-0.709,1.26-0.9
|
||||
c0.869-0.37,1.744-0.836,2.703-0.898c0.994,0.08,1.975,0.287,2.964,0.402c0.235-1.401,0.842-2.703,1.481-3.958
|
||||
c1.241-0.227,2.463-0.58,3.66-0.973C80.409,1.51,80.956,0.784,81.635,0.222z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
8
misc/icons/noun-project/sheep/license.txt
Normal file
@ -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.
|
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="89.231px" height="100px" viewBox="0 0 89.231 100" enable-background="new 0 0 89.231 100" xml:space="preserve">
|
||||
<path d="M14.652,64.026c-0.603-2.09-1-4.267-1.15-6.511H0c0.18,3.858,0.86,7.586,1.962,11.13L14.652,64.026z"/>
|
||||
<path d="M14.332,88.192l8.684-10.35c-2.899-2.792-5.273-6.127-6.926-9.857L3.402,72.604C5.9,78.563,9.655,83.87,14.332,88.192z"/>
|
||||
<path d="M42.483,86.499c-6.051-0.409-11.626-2.559-16.245-5.943l-8.681,10.346c6.985,5.336,15.582,8.661,24.926,9.099V86.499z"/>
|
||||
<path d="M44.589,10.768V0L14.266,17.506l30.323,17.506V24.245c17.186,0,31.166,13.98,31.166,31.165 c0,16.477-12.854,29.999-29.061,31.087v13.502C70.337,98.896,89.231,79.32,89.231,55.41C89.231,30.794,69.205,10.768,44.589,10.768z "/>
|
||||
</svg>
|
After Width: | Height: | Size: 843 B |
8
misc/icons/noun-project/undo-kyle_levi_fox/license.txt
Normal file
@ -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.
|
154
src/css/layout.css
Normal 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;}
|
@ -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;
|
||||
}
|
@ -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:
|
||||
*/
|
||||
|
3
src/css/transformations.css
Normal file
@ -0,0 +1,3 @@
|
||||
.transformations-container .tool-icon {
|
||||
float:left;
|
||||
}
|
BIN
src/img/tools/clone.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
src/img/tools/flip.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
src/img/tools/rotate.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
@ -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>
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 () {
|
||||
|
42
src/js/controller/TransformationsController.js
Normal file
@ -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;
|
||||
};
|
||||
})();
|
@ -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;
|
||||
|
@ -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_();
|
||||
}
|
||||
|
49
src/js/tools/IconMarkupRenderer.js
Normal file
@ -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);
|
||||
};
|
||||
})();
|
17
src/js/tools/Tool.js
Normal file
@ -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;
|
||||
};
|
||||
})();
|
@ -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) {};
|
||||
|
||||
/**
|
@ -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;
|
||||
};
|
||||
})();
|
@ -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";
|
@ -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";
|
@ -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);
|
@ -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() {
|
@ -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;
|
@ -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";
|
@ -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);
|
@ -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
|
@ -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";
|
@ -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";
|
@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var ns = $.namespace("pskl.drawingtools");
|
||||
var ns = $.namespace("pskl.tools.drawing");
|
||||
|
||||
ns.VerticalMirrorPen = function() {
|
||||
this.superclass.constructor.call(this);
|
@ -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)
|
@ -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";
|
@ -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";
|
25
src/js/tools/transform/Clone.js
Normal file
@ -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
|
||||
});
|
||||
};
|
||||
})();
|
28
src/js/tools/transform/Flip.js
Normal file
@ -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);
|
||||
};
|
||||
|
||||
})();
|
27
src/js/tools/transform/Rotate.js
Normal file
@ -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);
|
||||
};
|
||||
|
||||
})();
|
33
src/js/tools/transform/Transform.js
Normal file
@ -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
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
16
src/js/utils/Array.js
Normal file
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
65
src/js/utils/FrameTransform.js
Normal file
@ -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;
|
||||
}
|
||||
};
|
||||
})();
|
@ -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);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
37
src/js/utils/TooltipFormatter.js
Normal file
@ -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);
|
||||
};
|
||||
})();
|
@ -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();
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.widgets');
|
||||
var ns = $.namespace('pskl.widgets');
|
||||
|
||||
ns.HslRgbColorPicker = function (container, colorUpdatedCallback) {
|
||||
this.container = container;
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -34,20 +34,20 @@
|
||||
<!-- Templates -->
|
||||
|
||||
<!-- Drawing tool icon-button -->
|
||||
<script type="text/template" id="drawing-tool-item-template">
|
||||
<li rel="tooltip" data-placement="right" class="{{cssclass}}" data-tool-id="{{toolid}}" title="{{title}}"></li>
|
||||
<script type="text/template" id="drawingTool-item-template">
|
||||
<li rel="tooltip" data-placement="{{tooltipposition}}" 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>
|
||||
<div>{{helptext}} <span class='tools-tooltip-shortcut'>{{shortcut}}</span></div>
|
||||
{{descriptors}}
|
||||
</div>
|
||||
</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>
|
||||
|
@ -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"
|
||||
|
4
src/templates/transformations.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div class="toolbox-container transformations-container">
|
||||
<h3 class="toolbox-title transformations-title">Transform</h3>
|
||||
<ul class="tools-wrapper"></ul>
|
||||
</div>
|
253
test/js/utils/FrameTransformTest.js
Normal file
@ -0,0 +1,253 @@
|
||||
describe("FrameTransform suite", function() {
|
||||
var A = '#000000';
|
||||
var B = '#ff0000';
|
||||
var O = Constants.TRANSPARENT_COLOR;
|
||||
|
||||
var HORIZONTAL = pskl.utils.FrameTransform.HORIZONTAL;
|
||||
var VERTICAL = pskl.utils.FrameTransform.VERTICAL;
|
||||
|
||||
var CLOCKWISE = pskl.utils.FrameTransform.CLOCKWISE;
|
||||
var COUNTERCLOCKWISE = pskl.utils.FrameTransform.COUNTERCLOCKWISE;
|
||||
|
||||
/**
|
||||
* Check a frame has the pixels as a given grid
|
||||
* @param {Frame} frame [description]
|
||||
* @param {Array<Array<String|Color>>} grid
|
||||
*/
|
||||
var frameEqualsGrid = function (frame, grid) {
|
||||
frame.forEachPixel(function (color, col, row) {
|
||||
expect(color).toBe(grid[row][col]);
|
||||
});
|
||||
};
|
||||
|
||||
var toFrameGrid = function (normalGrid) {
|
||||
var frameGrid = [];
|
||||
var w = normalGrid[0].length;
|
||||
var h = normalGrid.length;
|
||||
for (var x = 0 ; x < w ; x++) {
|
||||
frameGrid[x] = [];
|
||||
for (var y = 0 ; y < h ; y++) {
|
||||
frameGrid[x][y] = normalGrid[y][x];
|
||||
}
|
||||
}
|
||||
return frameGrid;
|
||||
};
|
||||
|
||||
/*******************************/
|
||||
/************ FLIP *************/
|
||||
/*******************************/
|
||||
|
||||
it("flips a frame vertically", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[O, B]
|
||||
]));
|
||||
|
||||
// should have flipped
|
||||
pskl.utils.FrameTransform.flip(frame, VERTICAL);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A],
|
||||
[B, O]
|
||||
]);
|
||||
});
|
||||
|
||||
it("flips a frame horizontally", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[O, B]
|
||||
]));
|
||||
|
||||
// should have flipped
|
||||
pskl.utils.FrameTransform.flip(frame, HORIZONTAL);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, B],
|
||||
[A, O]
|
||||
]);
|
||||
});
|
||||
|
||||
it("flips rectangular frame", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[A, O],
|
||||
[A, O]
|
||||
]));
|
||||
|
||||
// should have flipped
|
||||
pskl.utils.FrameTransform.flip(frame, VERTICAL);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A],
|
||||
[O, A],
|
||||
[O, A]
|
||||
]);
|
||||
|
||||
// should be the same
|
||||
pskl.utils.FrameTransform.flip(frame, HORIZONTAL);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A],
|
||||
[O, A],
|
||||
[O, A]
|
||||
]);
|
||||
});
|
||||
|
||||
/*******************************/
|
||||
/*********** ROTATE ************/
|
||||
/*******************************/
|
||||
|
||||
it("rotates a frame counterclockwise", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[O, B]
|
||||
]));
|
||||
|
||||
// rotate once
|
||||
pskl.utils.FrameTransform.rotate(frame, COUNTERCLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, B],
|
||||
[A, O]
|
||||
]);
|
||||
|
||||
// rotate twice
|
||||
pskl.utils.FrameTransform.rotate(frame, COUNTERCLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[B, O],
|
||||
[O, A]
|
||||
]);
|
||||
|
||||
// rotate 3
|
||||
pskl.utils.FrameTransform.rotate(frame, COUNTERCLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A],
|
||||
[B, O]
|
||||
]);
|
||||
|
||||
// rotate 4 - back to initial state
|
||||
pskl.utils.FrameTransform.rotate(frame, COUNTERCLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[A, O],
|
||||
[O, B]
|
||||
]);
|
||||
});
|
||||
|
||||
it("rotates a frame clockwise", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[O, B]
|
||||
]));
|
||||
|
||||
// rotate once
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A],
|
||||
[B, O]
|
||||
]);
|
||||
|
||||
// rotate twice
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[B, O],
|
||||
[O, A]
|
||||
]);
|
||||
|
||||
// rotate 3
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, B],
|
||||
[A, O]
|
||||
]);
|
||||
|
||||
// rotate 4 - back to initial state
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[A, O],
|
||||
[O, B]
|
||||
]);
|
||||
});
|
||||
|
||||
it("rotates a rectangular frame", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[A, O],
|
||||
[A, O],
|
||||
[B, O],
|
||||
[B, O]
|
||||
]));
|
||||
|
||||
// rotate once
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O],
|
||||
[B, A],
|
||||
[O, O],
|
||||
[O, O]
|
||||
]);
|
||||
|
||||
// rotate twice
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O],
|
||||
[O, B],
|
||||
[O, A],
|
||||
[O, O]
|
||||
]);
|
||||
|
||||
// rotate 3
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O],
|
||||
[O, O],
|
||||
[A, B],
|
||||
[O, O]
|
||||
]);
|
||||
|
||||
// rotate 4
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O],
|
||||
[A, O],
|
||||
[B, O],
|
||||
[O, O]
|
||||
]);
|
||||
});
|
||||
|
||||
it("rotates a rectangular (horizontal) frame", function () {
|
||||
// create frame
|
||||
var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([
|
||||
[O, O, O, O],
|
||||
[A, A, B, B]
|
||||
]));
|
||||
|
||||
// rotate once
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, A, O, O],
|
||||
[O, B, O, O]
|
||||
]);
|
||||
|
||||
// rotate twice
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, B, A, O],
|
||||
[O, O, O, O]
|
||||
]);
|
||||
|
||||
// rotate 3
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O, B, O],
|
||||
[O, O, A, O]
|
||||
]);
|
||||
|
||||
// rotate 4
|
||||
pskl.utils.FrameTransform.rotate(frame, CLOCKWISE);
|
||||
frameEqualsGrid(frame, [
|
||||
[O, O, O, O],
|
||||
[O, A, B, O]
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
@ -101,45 +101,4 @@ describe("FrameUtils suite", function() {
|
||||
expect(frames[3].getPixel(0,1)).toBe(red);
|
||||
|
||||
});
|
||||
|
||||
// it("starts at -1", function() {
|
||||
// historyService = createMockHistoryService();
|
||||
// expect(historyService.currentIndex).toBe(-1);
|
||||
// });
|
||||
|
||||
// it("is at 0 after init", function() {
|
||||
// historyService = createMockHistoryService();
|
||||
// historyService.init();
|
||||
// expect(historyService.currentIndex).toBe(0);
|
||||
// });
|
||||
|
||||
// it("stores a piskel snapshot after 5 SAVE", function () {
|
||||
// // BEFORE
|
||||
// var SNAPSHOT_PERIOD_BACKUP = pskl.service.HistoryService.SNAPSHOT_PERIOD;
|
||||
// pskl.service.HistoryService.SNAPSHOT_PERIOD = 5;
|
||||
|
||||
// historyService = createMockHistoryService();
|
||||
// historyService.init();
|
||||
|
||||
// sendSaveEvents(pskl.service.HistoryService.REPLAY).times(5);
|
||||
|
||||
// expect(historyService.currentIndex).toBe(5);
|
||||
|
||||
// expect(getLastState().piskel).toBe(SERIALIZED_PISKEL);
|
||||
|
||||
// sendSaveEvents(pskl.service.HistoryService.REPLAY).times(4);
|
||||
|
||||
// sendSaveEvents(pskl.service.HistoryService.REPLAY_NO_SNAPSHOT).once();
|
||||
// expect(getLastState().piskel).toBeUndefined();
|
||||
|
||||
// sendSaveEvents(pskl.service.HistoryService.REPLAY_NO_SNAPSHOT).once();
|
||||
// expect(getLastState().piskel).toBeUndefined();
|
||||
|
||||
// sendSaveEvents(pskl.service.HistoryService.REPLAY).once();
|
||||
// expect(getLastState().piskel).toBe(SERIALIZED_PISKEL);
|
||||
|
||||
// // AFTER
|
||||
// pskl.service.HistoryService.SNAPSHOT_PERIOD = SNAPSHOT_PERIOD_BACKUP;
|
||||
|
||||
// })
|
||||
});
|