Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
dc61be27f0 | |||
7fd49aaccb | |||
cffaec09b2 | |||
62a7755407 | |||
2ab1e29365 | |||
fe110a3d8e | |||
5afec16258 | |||
fad483ce7a | |||
b10e87d2b7 | |||
61ee1d9b32 | |||
ce1a5c4918 | |||
796cd4466e | |||
0f49c884f2 | |||
c8dae1cb79 | |||
54837d0e21 | |||
001e35cf7b | |||
ac5083633b | |||
c32af500dc | |||
dc4de32162 | |||
243990a90f |
@ -161,7 +161,7 @@ module.exports = function(grunt) {
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{expand: true, flatten: true, src: ['src/piskel-boot-0.1.0.js'], dest: 'dest/'}
|
||||
{src: ['src/piskel-boot.js'], dest: 'dest/piskel-boot.js'}
|
||||
]
|
||||
},
|
||||
editor: {
|
||||
@ -170,6 +170,9 @@ module.exports = function(grunt) {
|
||||
{
|
||||
match: /templates\//g,
|
||||
replacement: "../templates"+version+"/"
|
||||
},{
|
||||
match: /piskel-boot.js/g,
|
||||
replacement: "../piskel-boot"+version+".js"
|
||||
},{
|
||||
match: /^(.|[\r\n])*<!--body-main-start-->/,
|
||||
replacement: "",
|
||||
@ -194,6 +197,7 @@ module.exports = function(grunt) {
|
||||
main: {
|
||||
files: [
|
||||
{src: ['dest/js/piskel-packaged-min.js'], dest: 'dest/js/piskel-packaged-min' + version + '.js'},
|
||||
{src: ['dest/piskel-boot.js'], dest: 'dest/piskel-boot' + version + '.js'},
|
||||
{src: ['src/logo.png'], dest: 'dest/logo.png'},
|
||||
{src: ['src/js/lib/iframeLoader-0.1.0.js'], dest: 'dest/js/lib/iframeLoader-0.1.0.js'},
|
||||
{src: ['src/js/lib/gif/gif.ie.worker.js'], dest: 'dest/js/lib/gif/gif.ie.worker.js'},
|
||||
@ -246,7 +250,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
src: [
|
||||
'src/js/**/*.js',
|
||||
'src/piskel-boot-0.1.0.js',
|
||||
'src/piskel-boot.js',
|
||||
'src/piskel-script-list.js',
|
||||
'!src/js/lib/**/*.js'
|
||||
],
|
||||
|
@ -32,7 +32,7 @@ Integrated in **[piskelapp.com](http://piskelapp.com)**, you can share everythin
|
||||
Piskel supports the following browsers :
|
||||
* **Chrome** (latest)
|
||||
* **Firefox** (latest)
|
||||
* **Internet Explorer** 10+
|
||||
* **Internet Explorer** 11+
|
||||
|
||||
... and a fairly recent computer.
|
||||
|
||||
|
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.
|
@ -3,7 +3,7 @@
|
||||
"name": "piskel",
|
||||
"main": "./dest/index.html",
|
||||
"description": "Web based 2d animations editor",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"homepage": "http://github.com/juliandescottes/piskel",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
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>
|
||||
@ -75,10 +76,11 @@
|
||||
|
||||
<iframe src="templates/cheatsheet.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
|
||||
<iframe src="templates/misc-templates.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
|
||||
|
||||
<script type="text/javascript" src="piskel-boot.js"></script>
|
||||
<!--body-main-end-->
|
||||
<!-- the comment above indicates the end of the markup reused by the editor integrated in piskelapp.com -->
|
||||
<!-- do not delete, do not move :) -->
|
||||
|
||||
<script type="text/javascript" src="piskel-boot-0.1.0.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -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();
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
// the oninput event won't work on IE10 unfortunately, but at least will provide a
|
||||
// consistent behavior across all other browsers that support the input type range
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=853670
|
||||
$("#preview-fps")[0].addEventListener('change', this.onFPSSliderChange.bind(this));
|
||||
$("#preview-fps").on('input change', this.onFPSSliderChange.bind(this));
|
||||
document.querySelector(".right-column").style.width = Constants.ANIMATED_PREVIEW_WIDTH + 'px';
|
||||
|
||||
this.toggleOnionSkinEl = document.querySelector(".preview-toggle-onion-skin");
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
this.paletteController = paletteController;
|
||||
|
||||
this.dragHandler = new ns.drawing.DragHandler(this);
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -138,13 +140,12 @@
|
||||
var frame = this.piskelController.getCurrentFrame();
|
||||
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
|
||||
|
||||
this.isClicked = true;
|
||||
this.setCurrentButton(event);
|
||||
|
||||
if (event.button === Constants.MIDDLE_BUTTON) {
|
||||
if (frame.containsPixel(coords.x, coords.y)) {
|
||||
$.publish(Events.SELECT_PRIMARY_COLOR, [frame.getPixel(coords.x, coords.y)]);
|
||||
}
|
||||
this.dragHandler.startDrag(event.clientX, event.clientY);
|
||||
} else {
|
||||
this.isClicked = true;
|
||||
this.setCurrentButton(event);
|
||||
this.currentToolBehavior.hideHighlightedPixel(this.overlayFrame);
|
||||
|
||||
this.currentToolBehavior.applyToolAt(
|
||||
@ -174,29 +175,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.resetZoom_ = function () {
|
||||
this.setZoom_(this.calculateZoom_());
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.increaseZoom_ = function (zoomMultiplier) {
|
||||
var step = (zoomMultiplier || 1) * this.getZoomStep_();
|
||||
this.setZoom_(this.renderer.getZoom() + step);
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.decreaseZoom_ = function (zoomMultiplier) {
|
||||
var step = (zoomMultiplier || 1) * this.getZoomStep_();
|
||||
this.setZoom_(this.renderer.getZoom() - step);
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.getZoomStep_ = function () {
|
||||
return this.calculateZoom_() / 10;
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.setZoom_ = function (zoom) {
|
||||
this.compositeRenderer.setZoom(zoom);
|
||||
$.publish(Events.ZOOM_CHANGED);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@ -209,19 +187,22 @@
|
||||
var currentFrame = this.piskelController.getCurrentFrame();
|
||||
|
||||
if (this.isClicked) {
|
||||
$.publish(Events.MOUSE_EVENT, [event, this]);
|
||||
// Warning : do not call setCurrentButton here
|
||||
// mousemove do not have the correct mouse button information on all browsers
|
||||
this.currentToolBehavior.moveToolAt(
|
||||
coords.x | 0,
|
||||
coords.y | 0,
|
||||
this.getCurrentColor_(),
|
||||
currentFrame,
|
||||
this.overlayFrame,
|
||||
event
|
||||
);
|
||||
if(this.currentMouseButton_ == Constants.MIDDLE_BUTTON) {
|
||||
this.dragHandler.updateDrag(x, y);
|
||||
} else {
|
||||
$.publish(Events.MOUSE_EVENT, [event, this]);
|
||||
// Warning : do not call setCurrentButton here
|
||||
// mousemove do not have the correct mouse button information on all browsers
|
||||
this.currentToolBehavior.moveToolAt(
|
||||
coords.x | 0,
|
||||
coords.y | 0,
|
||||
this.getCurrentColor_(),
|
||||
currentFrame,
|
||||
this.overlayFrame,
|
||||
event
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
this.currentToolBehavior.moveUnactiveToolAt(
|
||||
coords.x,
|
||||
coords.y,
|
||||
@ -236,7 +217,8 @@
|
||||
|
||||
ns.DrawingController.prototype.onMousewheel_ = function (jQueryEvent) {
|
||||
var event = jQueryEvent.originalEvent;
|
||||
var delta = event.wheelDeltaY || (-2 * event.deltaY);
|
||||
// Ratio between wheelDeltaY (mousewheel event) and deltaY (wheel event) is -40
|
||||
var delta = event.wheelDeltaY || (-40 * event.deltaY);
|
||||
var modifier = Math.abs(delta/120);
|
||||
if (delta > 0) {
|
||||
this.increaseZoom_(modifier);
|
||||
@ -249,6 +231,8 @@
|
||||
* @private
|
||||
*/
|
||||
ns.DrawingController.prototype.onMouseup_ = function (event) {
|
||||
var frame = this.piskelController.getCurrentFrame();
|
||||
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
|
||||
if(this.isClicked) {
|
||||
$.publish(Events.MOUSE_EVENT, [event, this]);
|
||||
// A mouse button was clicked on the drawing canvas before this mouseup event,
|
||||
@ -259,17 +243,24 @@
|
||||
this.isClicked = false;
|
||||
this.setCurrentButton(event);
|
||||
|
||||
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
|
||||
this.currentToolBehavior.releaseToolAt(
|
||||
coords.x,
|
||||
coords.y,
|
||||
this.getCurrentColor_(),
|
||||
this.piskelController.getCurrentFrame(),
|
||||
this.overlayFrame,
|
||||
event
|
||||
);
|
||||
if (event.button === Constants.MIDDLE_BUTTON) {
|
||||
if (this.dragHandler.isDragging()) {
|
||||
this.dragHandler.stopDrag();
|
||||
} else if (frame.containsPixel(coords.x, coords.y)) {
|
||||
$.publish(Events.SELECT_PRIMARY_COLOR, [frame.getPixel(coords.x, coords.y)]);
|
||||
}
|
||||
} else {
|
||||
this.currentToolBehavior.releaseToolAt(
|
||||
coords.x,
|
||||
coords.y,
|
||||
this.getCurrentColor_(),
|
||||
this.piskelController.getCurrentFrame(),
|
||||
this.overlayFrame,
|
||||
event
|
||||
);
|
||||
|
||||
$.publish(Events.TOOL_RELEASED);
|
||||
$.publish(Events.TOOL_RELEASED);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -389,8 +380,36 @@
|
||||
return this.compositeRenderer;
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.getOffset = function () {
|
||||
return this.compositeRenderer.getOffset();
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.setOffset = function (x, y) {
|
||||
this.compositeRenderer.setOffset(x, y);
|
||||
$.publish(Events.ZOOM_CHANGED);
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.resetZoom_ = function () {
|
||||
this.setZoom_(this.calculateZoom_());
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.increaseZoom_ = function (zoomMultiplier) {
|
||||
var step = (zoomMultiplier || 1) * this.getZoomStep_();
|
||||
this.setZoom_(this.renderer.getZoom() + step);
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.decreaseZoom_ = function (zoomMultiplier) {
|
||||
var step = (zoomMultiplier || 1) * this.getZoomStep_();
|
||||
this.setZoom_(this.renderer.getZoom() - step);
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.getZoomStep_ = function () {
|
||||
return this.calculateZoom_() / 10;
|
||||
};
|
||||
|
||||
ns.DrawingController.prototype.setZoom_ = function (zoom) {
|
||||
this.compositeRenderer.setZoom(zoom);
|
||||
$.publish(Events.ZOOM_CHANGED);
|
||||
};
|
||||
|
||||
})();
|
@ -23,10 +23,15 @@
|
||||
message.innerHTML = messageInfo.content;
|
||||
message.innerHTML = message.innerHTML + "<div title='Close message' class='close'>x</div>";
|
||||
document.body.appendChild(message);
|
||||
$(message).find(".close").click($.proxy(this.removeMessage_, this));
|
||||
if(messageInfo.behavior) {
|
||||
|
||||
message.querySelector('.close').addEventListener('click', this.removeMessage_.bind(this));
|
||||
if (messageInfo.behavior) {
|
||||
messageInfo.behavior(message);
|
||||
}
|
||||
|
||||
if (messageInfo.hideDelay) {
|
||||
window.setTimeout(this.removeMessage_.bind(this), messageInfo.hideDelay);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
84
src/js/controller/drawing/DragHandler.js
Normal file
@ -0,0 +1,84 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.drawing');
|
||||
|
||||
/**
|
||||
* Multiplier applied between the mouse movement and viewport movement
|
||||
* @type {Number}
|
||||
*/
|
||||
var MULTIPLIER = 2;
|
||||
|
||||
/**
|
||||
* Dedicated handler to drag the drawing canvas using the mouse
|
||||
* Will store the initial coordinates as well as the status of the drag
|
||||
* @param {DrawingController} drawingController
|
||||
*/
|
||||
ns.DragHandler = function (drawingController) {
|
||||
this.drawingController = drawingController;
|
||||
|
||||
this.isDragging_ = false;
|
||||
this.updateOrigin_(-1, -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a drag session.
|
||||
* @param {Number} x : x coordinate of the mouse event that initiated the drag
|
||||
* @param {Number} y : y coordinate of the mouse event that initiated the drag
|
||||
*/
|
||||
ns.DragHandler.prototype.startDrag = function (x, y) {
|
||||
var coords = this.drawingController.getSpriteCoordinates(x, y);
|
||||
this.updateOrigin_(coords.x, coords.y);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the drag status
|
||||
* @param {Number} x : x coordinate of the mouse event that triggered the update
|
||||
* @param {Number} y : y coordinate of the mouse event that triggered the update
|
||||
*/
|
||||
ns.DragHandler.prototype.updateDrag = function (x, y) {
|
||||
var currentOffset = this.drawingController.getOffset();
|
||||
var offset = this.calculateOffset_(x, y);
|
||||
if (currentOffset.y !== offset.y || currentOffset.x !== offset.x) {
|
||||
this.isDragging_ = true;
|
||||
this.drawingController.setOffset(offset.x, offset.y);
|
||||
|
||||
// retrieve the updated coordinates after moving the sprite
|
||||
// and store them as the new drag origin
|
||||
var coords = this.drawingController.getSpriteCoordinates(x, y);
|
||||
this.updateOrigin_(coords.x, coords.y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the drag session
|
||||
*/
|
||||
ns.DragHandler.prototype.stopDrag = function () {
|
||||
this.isDragging_ = false;
|
||||
this.origin = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will return true if the drag handler effectively MOVED the offset
|
||||
* during the current drag session
|
||||
*/
|
||||
ns.DragHandler.prototype.isDragging = function () {
|
||||
return this.isDragging_;
|
||||
};
|
||||
|
||||
ns.DragHandler.prototype.calculateOffset_ = function (x, y) {
|
||||
var coords = this.drawingController.getSpriteCoordinates(x, y);
|
||||
var currentOffset = this.drawingController.getOffset();
|
||||
|
||||
var offset = {
|
||||
x : currentOffset.x - MULTIPLIER * (coords.x - this.origin.x),
|
||||
y : currentOffset.y - MULTIPLIER * (coords.y - this.origin.y)
|
||||
};
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
ns.DragHandler.prototype.updateOrigin_ = function (x, y) {
|
||||
this.origin = this.origin || {};
|
||||
this.origin.x = x;
|
||||
this.origin.y = y;
|
||||
};
|
||||
})();
|
@ -44,25 +44,30 @@
|
||||
var zoom = this.getSelectedZoom_(),
|
||||
fps = this.piskelController.getFPS();
|
||||
|
||||
this.renderAsImageDataAnimatedGIF(zoom, fps, this.onGifRenderingCompleted_.bind(this));
|
||||
this.renderAsImageDataAnimatedGIF(zoom, fps, this.uploadImageData_.bind(this));
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.onDownloadButtonClick_ = function (evt) {
|
||||
var fileName = this.piskelController.getPiskel().getDescriptor().name + '.gif';
|
||||
var zoom = this.getSelectedZoom_(),
|
||||
fps = this.piskelController.getFPS();
|
||||
|
||||
this.renderAsImageDataAnimatedGIF(zoom, fps, function (imageData) {
|
||||
pskl.utils.BlobUtils.dataToBlob(imageData, "image/gif", function(blob) {
|
||||
pskl.utils.FileUtils.downloadAsFile(blob, fileName);
|
||||
});
|
||||
}.bind(this));
|
||||
this.renderAsImageDataAnimatedGIF(zoom, fps, this.downloadImageData_.bind(this));
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.onGifRenderingCompleted_ = function (imageData) {
|
||||
ns.GifExportController.prototype.downloadImageData_ = function (imageData) {
|
||||
var fileName = this.piskelController.getPiskel().getDescriptor().name + '.gif';
|
||||
pskl.utils.BlobUtils.dataToBlob(imageData, "image/gif", function(blob) {
|
||||
pskl.utils.FileUtils.downloadAsFile(blob, fileName);
|
||||
});
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.uploadImageData_ = function (imageData) {
|
||||
this.updatePreview_(imageData);
|
||||
this.previewContainerEl.classList.add("preview-upload-ongoing");
|
||||
pskl.app.imageUploadService.upload(imageData, this.onImageUploadCompleted_.bind(this));
|
||||
|
||||
console.log(imageData.length);
|
||||
|
||||
pskl.app.imageUploadService.upload(imageData, this.onImageUploadCompleted_.bind(this), this.onImageUploadFailed_.bind(this));
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.onImageUploadCompleted_ = function (imageUrl) {
|
||||
@ -71,6 +76,15 @@
|
||||
this.previewContainerEl.classList.remove("preview-upload-ongoing");
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.onImageUploadFailed_ = function (event, xhr) {
|
||||
if (xhr.status === 500) {
|
||||
$.publish(Events.SHOW_NOTIFICATION, [{
|
||||
"content": "Upload failed : " + xhr.responseText,
|
||||
"hideDelay" : 5000
|
||||
}]);
|
||||
}
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.updatePreview_ = function (src) {
|
||||
this.previewContainerEl.innerHTML = "<div><img style='max-width:32px;' src='"+src+"'/></div>";
|
||||
};
|
||||
@ -104,10 +118,10 @@
|
||||
var colorCount = pskl.app.currentColorsService.getCurrentColors().length;
|
||||
var preserveColors = colorCount < MAX_GIF_COLORS;
|
||||
var gif = new window.GIF({
|
||||
workers: 2,
|
||||
workers: 5,
|
||||
quality: 1,
|
||||
width: this.piskelController.getWidth()*zoom,
|
||||
height: this.piskelController.getHeight()*zoom,
|
||||
width: this.piskelController.getWidth() * zoom,
|
||||
height: this.piskelController.getHeight() * zoom,
|
||||
preserveColors : preserveColors
|
||||
});
|
||||
|
||||
|
@ -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_();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
var file = files[i];
|
||||
var isImage = file.type.indexOf('image') === 0;
|
||||
var isPiskel = /\.piskel$/i.test(file.name);
|
||||
var isPalette = /\.(gpl|txt)$/i.test(file.name);
|
||||
var isPalette = /\.(gpl|txt|pal)$/i.test(file.name);
|
||||
if (isImage) {
|
||||
this.readImageFile_(file);
|
||||
} else if (isPiskel) {
|
||||
|
@ -1,50 +0,0 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
|
||||
var RE_COLOR_LINE = /^(\s*\d{1,3})(\s*\d{1,3})(\s*\d{1,3})/;
|
||||
var RE_EXTRACT_NAME = /^name\s*\:\s*(.*)$/i;
|
||||
|
||||
ns.PaletteGplReader = function (file, onSuccess, onError) {
|
||||
this.file = file;
|
||||
this.onSuccess = onSuccess;
|
||||
this.onError = onError;
|
||||
};
|
||||
|
||||
ns.PaletteGplReader.prototype.read = function () {
|
||||
pskl.utils.FileUtils.readFile(this.file, this.onFileLoaded_.bind(this));
|
||||
};
|
||||
|
||||
ns.PaletteGplReader.prototype.onFileLoaded_ = function (content) {
|
||||
var text = pskl.utils.Base64.toText(content);
|
||||
var lines = text.match(/[^\r\n]+/g);
|
||||
|
||||
var name = lines.map(function (l) {
|
||||
var matches = l.match(RE_EXTRACT_NAME);
|
||||
return matches ? matches[1] : '';
|
||||
}).join('');
|
||||
|
||||
var colorLines = lines.filter(function (l) {
|
||||
return RE_COLOR_LINE.test(l);
|
||||
});
|
||||
|
||||
var colors = colorLines.map(function (l) {
|
||||
var matches = l.match(RE_COLOR_LINE);
|
||||
var color = window.tinycolor({
|
||||
r : parseInt(matches[1], 10),
|
||||
g : parseInt(matches[2], 10),
|
||||
b : parseInt(matches[3], 10)
|
||||
});
|
||||
|
||||
return color.toRgbString();
|
||||
});
|
||||
|
||||
if (name && colors.length) {
|
||||
var uuid = pskl.utils.Uuid.generate();
|
||||
var palette = new pskl.model.Palette(uuid, name, colors);
|
||||
this.onSuccess(palette);
|
||||
} else {
|
||||
this.onError();
|
||||
}
|
||||
|
||||
};
|
||||
})();
|
@ -2,8 +2,10 @@
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
|
||||
var fileReaders = {
|
||||
'gpl' : ns.PaletteGplReader,
|
||||
'txt' : ns.PaletteTxtReader
|
||||
'gpl' : ns.reader.PaletteGplReader,
|
||||
'pal' : ns.reader.PalettePalReader,
|
||||
'txt' : ns.reader.PaletteTxtReader,
|
||||
'img' : ns.reader.PaletteImageReader
|
||||
};
|
||||
|
||||
ns.PaletteImportService = function () {};
|
||||
@ -33,7 +35,7 @@
|
||||
ns.PaletteImportService.prototype.getReaderClass_ = function (file) {
|
||||
var readerClass;
|
||||
if (this.isImage_(file)) {
|
||||
readerClass = ns.PaletteImageReader;
|
||||
readerClass = fileReaders.img;
|
||||
} else {
|
||||
var extension = this.getExtension_(file);
|
||||
readerClass = fileReaders[extension];
|
||||
|
@ -1,38 +0,0 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
|
||||
var RE_COLOR_LINE = /^[A-F0-9]{2}([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/;
|
||||
|
||||
ns.PaletteTxtReader = function (file, onSuccess, onError) {
|
||||
this.file = file;
|
||||
this.onSuccess = onSuccess;
|
||||
this.onError = onError;
|
||||
};
|
||||
|
||||
ns.PaletteTxtReader.prototype.read = function () {
|
||||
pskl.utils.FileUtils.readFile(this.file, this.onFileLoaded_.bind(this));
|
||||
};
|
||||
|
||||
ns.PaletteTxtReader.prototype.onFileLoaded_ = function (content) {
|
||||
var text = pskl.utils.Base64.toText(content);
|
||||
var lines = text.match(/[^\r\n]+/g);
|
||||
|
||||
var colorLines = lines.filter(function (l) {
|
||||
return RE_COLOR_LINE.test(l);
|
||||
});
|
||||
|
||||
var colors = colorLines.map(function (l) {
|
||||
var matches = l.match(RE_COLOR_LINE);
|
||||
var color = "#" + matches[1] + matches[2] + matches[3];
|
||||
return color;
|
||||
});
|
||||
|
||||
if (colors.length) {
|
||||
var uuid = pskl.utils.Uuid.generate();
|
||||
var palette = new pskl.model.Palette(uuid, 'Imported palette', colors);
|
||||
this.onSuccess(palette);
|
||||
} else {
|
||||
this.onError();
|
||||
}
|
||||
};
|
||||
})();
|
35
src/js/service/palette/reader/AbstractPaletteFileReader.js
Normal file
@ -0,0 +1,35 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette.reader');
|
||||
|
||||
ns.AbstractPaletteFileReader = function (file, onSuccess, onError, colorLineRegexp) {
|
||||
this.file = file;
|
||||
this.onSuccess = onSuccess;
|
||||
this.onError = onError;
|
||||
this.colorLineRegexp = colorLineRegexp;
|
||||
};
|
||||
|
||||
ns.AbstractPaletteFileReader.prototype.extractColorFromLine = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractPaletteFileReader.prototype.read = function () {
|
||||
pskl.utils.FileUtils.readFile(this.file, this.onFileLoaded_.bind(this));
|
||||
};
|
||||
|
||||
ns.AbstractPaletteFileReader.prototype.onFileLoaded_ = function (content) {
|
||||
var text = pskl.utils.Base64.toText(content);
|
||||
var lines = text.match(/[^\r\n]+/g);
|
||||
|
||||
var colorLines = lines.filter(function (l) {
|
||||
return this.colorLineRegexp.test(l);
|
||||
}.bind(this));
|
||||
|
||||
var colors = colorLines.map(this.extractColorFromLine.bind(this));
|
||||
|
||||
if (colors.length) {
|
||||
var uuid = pskl.utils.Uuid.generate();
|
||||
var palette = new pskl.model.Palette(uuid, this.file.name, colors);
|
||||
this.onSuccess(palette);
|
||||
} else {
|
||||
this.onError();
|
||||
}
|
||||
};
|
||||
})();
|
23
src/js/service/palette/reader/PaletteGplReader.js
Normal file
@ -0,0 +1,23 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette.reader');
|
||||
|
||||
var RE_COLOR_LINE = /^(\s*\d{1,3})(\s*\d{1,3})(\s*\d{1,3})/;
|
||||
var RE_EXTRACT_NAME = /^name\s*\:\s*(.*)$/i;
|
||||
|
||||
ns.PaletteGplReader = function (file, onSuccess, onError) {
|
||||
this.superclass.constructor.call(this, file, onSuccess, onError, RE_COLOR_LINE);
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.PaletteGplReader, ns.AbstractPaletteFileReader);
|
||||
|
||||
ns.PaletteGplReader.prototype.extractColorFromLine = function (line) {
|
||||
var matches = line.match(RE_COLOR_LINE);
|
||||
var color = window.tinycolor({
|
||||
r : parseInt(matches[1], 10),
|
||||
g : parseInt(matches[2], 10),
|
||||
b : parseInt(matches[3], 10)
|
||||
});
|
||||
|
||||
return color.toRgbString();
|
||||
};
|
||||
})();
|
@ -1,5 +1,5 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
var ns = $.namespace('pskl.service.palette.reader');
|
||||
|
||||
ns.PaletteImageReader = function (file, onSuccess, onError) {
|
||||
this.file = file;
|
||||
@ -19,7 +19,6 @@
|
||||
this.onWorkerStep_.bind(this),
|
||||
this.onWorkerError_.bind(this));
|
||||
|
||||
|
||||
$.publish(Events.SHOW_PROGRESS, [{"name": 'Processing image colors ...'}]);
|
||||
|
||||
imageProcessor.process();
|
17
src/js/service/palette/reader/PalettePalReader.js
Normal file
@ -0,0 +1,17 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette.reader');
|
||||
|
||||
var RE_COLOR_LINE = /^(\d{1,3})\s+(\d{1,3})\s+(\d{1,3})/;
|
||||
|
||||
ns.PalettePalReader = function (file, onSuccess, onError) {
|
||||
this.superclass.constructor.call(this, file, onSuccess, onError, RE_COLOR_LINE);
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.PalettePalReader, ns.AbstractPaletteFileReader);
|
||||
|
||||
ns.PalettePalReader.prototype.extractColorFromLine = function (line) {
|
||||
var matches = line.match(RE_COLOR_LINE);
|
||||
var color = 'rgb(' + matches[1] + ',' + matches[2] + ',' + matches[3] + ')';
|
||||
return color;
|
||||
};
|
||||
})();
|
17
src/js/service/palette/reader/PaletteTxtReader.js
Normal file
@ -0,0 +1,17 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette.reader');
|
||||
|
||||
var RE_COLOR_LINE = /^[A-F0-9]{2}([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/;
|
||||
|
||||
ns.PaletteTxtReader = function (file, onSuccess, onError) {
|
||||
this.superclass.constructor.call(this, file, onSuccess, onError, RE_COLOR_LINE);
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.PaletteTxtReader, ns.AbstractPaletteFileReader);
|
||||
|
||||
ns.PaletteTxtReader.prototype.extractColorFromLine = function (line) {
|
||||
var matches = line.match(RE_COLOR_LINE);
|
||||
var color = "#" + matches[1] + matches[2] + matches[3];
|
||||
return color;
|
||||
};
|
||||
})();
|
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);
|
||||
};
|
||||
})();
|
@ -37,7 +37,7 @@
|
||||
};
|
||||
|
||||
xhr.onerror = function(e) {
|
||||
error(e);
|
||||
error(e, this);
|
||||
};
|
||||
|
||||
return xhr;
|
||||
|
@ -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",
|
||||
@ -78,6 +81,7 @@
|
||||
"js/controller/piskel/PublicPiskelController.js",
|
||||
"js/controller/CursorCoordinatesController.js",
|
||||
"js/controller/DrawingController.js",
|
||||
"js/controller/drawing/DragHandler.js",
|
||||
"js/controller/PreviewFilmController.js",
|
||||
"js/controller/LayersListController.js",
|
||||
"js/controller/AnimatedPreviewController.js",
|
||||
@ -87,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
|
||||
@ -111,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",
|
||||
@ -125,10 +130,12 @@
|
||||
"js/service/color/ColorSorter.js",
|
||||
"js/service/palette/CurrentColorsPalette.js",
|
||||
"js/service/palette/PaletteService.js",
|
||||
"js/service/palette/PaletteTxtReader.js",
|
||||
"js/service/palette/PaletteGplReader.js",
|
||||
"js/service/palette/PaletteGplWriter.js",
|
||||
"js/service/palette/PaletteImageReader.js",
|
||||
"js/service/palette/reader/AbstractPaletteFileReader.js",
|
||||
"js/service/palette/reader/PaletteGplReader.js",
|
||||
"js/service/palette/reader/PaletteImageReader.js",
|
||||
"js/service/palette/reader/PalettePalReader.js",
|
||||
"js/service/palette/reader/PaletteTxtReader.js",
|
||||
"js/service/palette/PaletteImportService.js",
|
||||
"js/service/SavedStatusService.js",
|
||||
"js/service/keyboard/ShortcutService.js",
|
||||
@ -139,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,7 +4,7 @@
|
||||
<div class="settings-item">
|
||||
<div class="settings-form-section" style="overflow:hidden">
|
||||
<label class="row" style="float:left;line-height:28px;">Title : </label>
|
||||
<input id="save-name" type="text" class="save-field textfield" style="float:left;width:200px;margin-left:10px;"/>
|
||||
<input id="save-name" type="text" class="save-field textfield" style="float:left;width:198px;margin-left:10px;"/>
|
||||
</div>
|
||||
<div class="settings-form-section">
|
||||
<textarea id="save-description" class="save-field textfield" placeholder="Description ..."></textarea>
|
||||
|
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;
|
||||
|
||||
// })
|
||||
});
|