56 Commits

Author SHA1 Message Date
dc61be27f0 Update README.md 2014-11-26 08:55:53 +01:00
7fd49aaccb Removed localhost url ... 2014-11-26 07:48:15 +01:00
cffaec09b2 Prepare release 0.4.0 2014-11-25 22:54:18 +01:00
62a7755407 Merge pull request #235 from juliandescottes/feature-add-effects
Feature add effects
2014-11-25 22:43:12 +01:00
2ab1e29365 Merge branch 'master' into feature-add-effects 2014-11-23 21:54:31 +01:00
fe110a3d8e Merge pull request #233 from juliandescottes/enhancement-move-viewport
Enhancement move viewport
2014-11-23 21:53:34 +01:00
5afec16258 Cleanup of console.log in MinimapController.js-n 2014-11-23 21:48:32 +01:00
fad483ce7a Increased movement speed 2014-11-23 21:44:51 +01:00
b10e87d2b7 Fix for issue #189 : user can move the viewport via click n drag of middle mouse button 2014-11-23 21:37:34 +01:00
61ee1d9b32 Added clone tool + icon 2014-11-23 16:27:12 +01:00
ce1a5c4918 Rotate non square sprites, added rotate icon, unit tests for transforms 2014-11-23 15:03:35 +01:00
796cd4466e Added Rotate tool + abstract Transform tool 2014-11-22 00:07:11 +01:00
0f49c884f2 Mutualize HTML generation for drawing tools and transform 2014-11-21 01:15:55 +01:00
c8dae1cb79 Added mirror transformation 2014-11-19 23:00:25 +01:00
54837d0e21 Issue #228 : Zoom is very slow on Firefox 2014-11-01 14:00:35 +01:00
001e35cf7b Merge pull request #229 from etumyan/fps-oninput
Combining oninput and onchange events for the FPS counter. Close #225
2014-11-01 13:57:49 +01:00
ac5083633b Combining oninput and onchange events for the FPS counter. 2014-10-31 22:38:11 +04:00
c32af500dc add notification if image upload fails 2014-10-01 01:21:49 +02:00
dc4de32162 Added support for .PAL palettes 2014-09-30 00:58:15 +02:00
243990a90f Fixed : cache issue coming from piskel-boot file 2014-09-30 00:19:54 +02:00
96ef362cf8 preparing release v0.3.0 2014-09-28 11:20:34 +02:00
e1e029a849 Merge pull request #221 from juliandescottes/enhancement-palette-sorting
Enhancement palette sorting
2014-09-27 11:06:43 +02:00
fe5e8966a5 added shortcuts to select previous / next color in palette 2014-09-27 11:04:03 +02:00
37aa6c3d72 sort colors on image import for palette 2014-09-27 01:22:20 +02:00
d805e13d57 sort colors on image import for palette 2014-09-27 01:10:54 +02:00
a7ef57b6ee fixed color sorting for desaturated colors 2014-09-26 00:03:24 +02:00
ac08775406 improved current colors sort 2014-09-25 00:13:23 +02:00
6583d3d560 moved rgbToHex correct implementation to pskl core utils 2014-09-24 21:53:41 +02:00
b5465ca066 fixed palette import bug 2014-09-24 21:50:16 +02:00
258d13371d improved current colors sort algorithm 2014-09-24 08:15:18 +02:00
e3e6730b45 improved current colors sort algorithm 2014-09-24 07:43:04 +02:00
6ef99bba15 improved current colors sort algorithm 2014-09-24 00:26:31 +02:00
afe790e5e3 Removed unused CSS rules for old edit/merge layer actions 2014-09-23 08:05:31 +02:00
8989e984cb added dedicated style for colors-list for IE and FF + bug fixing on ProgressBarCOntroller for FF 2014-09-23 08:00:46 +02:00
00dd660571 Use dedicated service to display progress information 2014-09-22 23:51:28 +02:00
8a29b78af8 Merge branch 'master' into enhancement-palette-sorting
Conflicts:
	src/js/utils/FrameUtils.js
2014-09-21 21:56:22 +02:00
9ef46d5ec5 added FrameUtils unit tests 2014-09-21 21:39:54 +02:00
6445b44d02 Moved image import to worker 2014-09-20 09:14:21 +02:00
9afe69cb87 Split CreatePaletteControllers in ctrl + widget for colors list 2014-09-18 07:59:56 +02:00
508fb79c32 Homogeneize layout, drop palette 2014-09-18 07:18:07 +02:00
8ebdc4cd41 Enhancement palettes : Added download palette
- palettes can be downloaded as GPL palettes
- slightly tweaked the UI of hsl rgb picker
- switched preferred format of spectrum to hex
2014-09-17 01:32:59 +02:00
fab9c6e836 select new palette after saving 2014-09-16 00:37:24 +02:00
f7f9587520 Merge pull request #220 from juliandescottes/enhancement-layers-options
Enhancement layers options
2014-09-16 00:10:42 +02:00
12dcacea5a increased the timeout for Travis tests 2014-09-13 20:32:01 +02:00
9325abb924 Enhancement : Layers merge
Added drawing test + fixed drawing test runner on Mac OS X
2014-09-13 20:21:40 +02:00
4ed7338f25 Feature : merge layers
Added feature to merge a layer with the layer below
Done at #jsconfeu2014 :)

New icon in icons : merge-icon.png
TODO : reorder the icons folder, it's waaaaaaay too messy !!
2014-09-13 20:10:05 +02:00
90845b3a62 Enhancement : Color palettes
- Added clone feature when editing existing palette
- Added arrow up/down to increase decrease input values
- Paint.net palettes are supported
2014-09-09 23:53:57 +02:00
125e332b7c Enhancement : palette color creator
- Added import of GPL files
2014-09-07 18:25:17 +02:00
e457209c8f Enhancement : Palette color creator
- Added import button on create palette dialog
- implemented import from images
- missing limitation on color count when importing !!
- should remove button when editing existing palette
2014-09-07 14:31:28 +02:00
8643f4402a Moved PaletteService from pskl.service to piskel.service.palette 2014-09-07 12:27:06 +02:00
92d7109ef7 Enhancement : Palette colors creation
- Added cancel button to create palette dialog
- Added escape/unescapeHtml methods to pskl.utils
- Escaping palette name now ...
- Removed outdated comment in app.js regarding appEngine token
- Added a call to destroy() during dialogClose of AbstractDlgCtrl
2014-09-07 12:22:44 +02:00
6b32239fa1 fixed bug with hue slider capped to 255 2014-09-06 22:37:05 +02:00
8441f28ac1 Palette creator can save palettes to local storage 2014-09-06 12:37:11 +02:00
e8db80a0ec Extracted ColorPicker code to dedicated widget package (noooooooo) ; Added basic palette creation mechanism (list colors + add color) 2014-09-04 08:34:17 +02:00
7d9f8a8ccf Added color picker in create palette popup 2014-09-04 00:22:02 +02:00
073f46b0d7 starting palette implementation using creation wizard 2014-08-30 18:39:54 +02:00
145 changed files with 3977 additions and 1493 deletions

View File

@ -36,7 +36,7 @@ module.exports = function(grunt) {
},
'travis' : {
suite : './test/casperjs/TravisTestSuite.js',
delay : 5000
delay : 10000
}
};
@ -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'
],

View File

@ -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
View File

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

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View 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

View 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.

View File

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

View 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.

View File

@ -0,0 +1,12 @@
01 - Run grunt desktop on mac os x
02 - Retrieve piskel.new.dmg.zip on Dropbox. Unzip it.
03 - Retrieve nw.icns on Dropbox
04 - Go to piskel/dest/desktop/releases/mac ; copy piskel.app to your working directory
05 - Expand piskel.app
06 - Replace nw.icns by the one from dropbox in Contents/Resources
07 - Open piskel.new.dmg
08 - Drag and drop piskel.app in it
09 - Update readme.txt
10 - Open disk utility, and open piskel.new.dmg in it
11 - Convert image, piskel-x.y.z.dmg
12 - Upload to Dropbox

View File

@ -3,7 +3,7 @@
"name": "piskel",
"main": "./dest/index.html",
"description": "Web based 2d animations editor",
"version": "0.2.0",
"version": "0.4.0",
"homepage": "http://github.com/juliandescottes/piskel",
"repository": {
"type": "git",
@ -33,7 +33,7 @@
"karma": "0.12.17",
"karma-chrome-launcher": "^0.1.4",
"karma-phantomjs-launcher": "^0.1.4",
"karma-jasmine": "^0.1.5",
"karma-jasmine": "^0.2.0",
"nodewebkit": "~0.10.1"
},
"window": {

View File

@ -36,7 +36,7 @@
}
.tooltip {
position: absolute;
z-index: 1030;
z-index: 30000;
display: block;
visibility: visible;
padding: 5px;

View File

@ -0,0 +1,96 @@
.color-picker-slider * {
box-sizing: border-box;
}
.color-picker-slider input[type="range"] {
-webkit-appearance: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
width: 100%;
border: none;
padding: 1px 2px;
border-radius: 3px;
background-image: linear-gradient(to right, hsl(0, 30%, 70%) 0, hsl(359, 30%, 70%) 100%);
box-shadow: inset 0 1px 0 0 #0d0e0f, inset 0 -1px 0 0 #3a3d42;
outline: none; /* no focus outline */
}
/* thumb */
.color-picker-slider input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
cursor:pointer;
width: 7px;
height: 18px;
border: none;
border-radius: 2px;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #529de1), color-stop(100%, #245e8f)); /* android <= 2.2 */
background-image: -webkit-linear-gradient(top , #529de1 0, #245e8f 100%); /* older mobile safari and android > 2.2 */;
background-image: linear-gradient(to bottom, #529de1 0, #245e8f 100%); /* W3C */
}
.color-picker-slider input[type="range"]::-moz-range-thumb {
width: 7px;
height: 18px;
border: none;
border-radius: 2px;
background-image: linear-gradient(to bottom, #529de1 0, #245e8f 100%); /* W3C */
}
.color-picker-slider input[type="range"]::-ms-thumb {
width: 7px;
height: 18px;
border-radius: 2px;
border: 0;
background-image: linear-gradient(to bottom, #529de1 0, #245e8f 100%); /* W3C */
}
/*CROSS BROWSER RESET*/
.color-picker-slider input[type="range"]::-moz-range-track {
border: inherit;
background: transparent;
}
.color-picker-slider input[type="range"]::-ms-track {
border: inherit;
color: transparent; /* don't drawn vertical reference line */
background: transparent;
}
.color-picker-slider input[type="range"]::-ms-fill-lower,
.color-picker-slider input[type="range"]::-ms-fill-upper {
background: transparent;
}
.color-picker-slider input[type="range"]::-ms-tooltip {
display: none;
}
.color-picker-slider {
padding: 0 10px;
height : 25px;
overflow: hidden;
}
.color-picker-slider span{
line-height : 25px;
width : 10px;
float:left;
}
.color-picker-slider input[type="range"]{
float:left;
height : 10px;
width : 100px;
margin: 7px 1px 7px 8px;
}
.color-picker-slider input[type="text"]{
float:left;
width : 47px;
margin-left: 5px;
}
.color-picker-slider input[type="range"][data-dimension="h"] {
background-image:linear-gradient(to right, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}

View File

@ -0,0 +1,169 @@
#dialog-container.create-palette {
width: 500px;
height: 600px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -250px;
}
.show #dialog-container.create-palette {
margin-top: -300px;
}
.create-palette-section {
position: absolute;
left: 10px;
top: 50px;
}
.create-palette-import-section {
display : inline-block;
}
.colors-container {
position: absolute;
left: 10px;
right: 10px;
top: 85px;
height: 460px;
border: 1px solid black;
background: #333;
}
.color-picker-container {
position:absolute;
left : 280px;
top:0;
bottom:0;
right:0;
background: #222;
}
.create-palette-actions {
position: absolute;
box-sizing: border-box;
width:100%;
height: 45px;
left: 0;
right: 0;
bottom: 0;
padding:10px;
text-align:right;
}
.color-preview {
width: 170px;
height: 76px;
margin: 11px;
}
.colors-list {
overflow: auto;
width: 280px;
box-sizing: border-box;
height: 100%;
padding-bottom: 10px;
}
.create-palette-color, .create-palette-new-color, .colors-list-drop-proxy{
position:relative;
float : left;
width : 44px;
height : 44px;
margin : 10px 0 0 10px;
box-sizing : border-box;
cursor : pointer;
}
@-moz-document url-prefix() {
.create-palette-color, .create-palette-new-color, .colors-list-drop-proxy{
margin : 7px 0 0 7px;
}
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.create-palette-color, .create-palette-new-color, .colors-list-drop-proxy{
margin : 7px 0 0 7px;
}
}
.create-palette-color {
border:1px solid #2c2c2c;
transition : border-color 0.2s;
}
.create-palette-color:hover {
border:1px solid gold;
}
.colors-list-drop-proxy {
border:2px dotted #eee;
}
.create-palette-new-color {
border:2px dotted gold;
border-radius: 2px;
line-height: 40px;
text-align: center;
font-size: 20px;
color: gold;
}
.create-palette-color.selected {
border:2px solid gold;
}
.create-palette-remove-color {
position: absolute;
top: 0;
right: 0;
padding: 2px 4px 0 0;
opacity : 0.2;
font-weight: bold;
color: rgb(255,255,255);
text-shadow : 0 0 1px rgb(0,0,0);
transition : opacity 0.3s, color 0.1s;
}
.light-color .create-palette-remove-color {
color: rgb(0,0,0);
text-shadow : 0 0 1px rgb(255,255,255);
}
.selected .create-palette-remove-color {
top: -1px;
right: -1px;
}
.create-palette-color:hover .create-palette-remove-color {
opacity: 0.6;
}
.create-palette-color .create-palette-remove-color:hover {
opacity: 1;
color: rgb(240,80,80);
text-shadow : 0 0 1px rgb(0,0,0);
}
/*SPECTRUM OVERRIDES*/
.create-palette .sp-container{
background-color: transparent;
border: none;
box-shadow : none;
border-radius:0;
padding:5px;
}

View File

@ -1,222 +0,0 @@
.palette-manager-wrapper {
height: 100%;
position: relative;
}
.palette-manager-body {
position: absolute;
top: 45px;
bottom: 0;
right: 0;
left: 0;
}
.palette-manager-head {
position: absolute;
width: 100%;
background: gold;
margin: 0;
padding: 10px;
color: black;
font-size: 1.8em;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.palette-manager-close {
position: absolute;
top: 0;
right: 0;
line-height: 45px;
margin-right: 10px;
font-size: 1.3em;
cursor: pointer;
}
.palette-manager-drawer {
width: 200px;
position: absolute;
top: 0;
bottom: 0;
}
.palette-manager-list {
position: absolute;
top:40px;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
}
.palette-manager-actions {
position: absolute;
height:40px;
line-height:40px;
width: 100%;
text-align: center;
}
.palette-manager-actions-button {
width: 80px;
margin: 5px;
}
.palette-manager-palette-button,
.palette-manager-actions-button {
line-height: 20px;
}
.palette-manager-list li {
height: 48px;
line-height: 48px;
padding-left:10px;
font-size: 1.4em;
box-sizing: border-box;
-moz-box-sizing: border-box;
border-bottom: 1px solid #666;
cursor:pointer;
}
.palette-manager-list li:hover {
background : #222;
}
.palette-manager-list li.selected {
color : gold;
font-weight: bold;
}
.palette-manager-list li:nth-child(1) {
border-top: 1px solid #666;
}
.palette-manager-details {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
box-sizing: border-box;
-moz-box-sizing: border-box;
border-left:1px solid #666;
}
.palette-manager-details-head {
position: absolute;
height:40px;
line-height:40px;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.palette-manager-details-head-name {
padding: 0 10px 0 20px;
font-size: 1.5em;
font-weight: bold;
}
.palette-manager-details-head .edit-icon {
width: 24px;
display: inline-block;
background-size: 16px;
}
.palette-manager-details-head-actions {
float: right;
line-height: 40px;
padding-right: 10px;
}
.palette-manager-details-body {
position: absolute;
top:40px;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.palette-manager-color-card {
width: 120px;
height: 180px;
display: inline-block;
position: relative;
margin: 20px 0 20px 20px;
box-shadow: 0 0 0px 0px gold;
transition: box-shadow 0.3s;
}
.palette-manager-color-card:hover {
box-shadow: 0 0 4px 1px gold;
}
.palette-manager-delete-card {
position: absolute;
top: 0;
right: 0;
width: 20px;
text-align: center;
font-size: 1.6em;
font-weight: bold;
color: rgb(255,255,255);
text-shadow : 0 0 2px rgb(0,0,0);
cursor: pointer;
opacity : 0.2;
transition : opacity 0.3s, color 0.1s;
}
.palette-manager-color-card:hover .palette-manager-delete-card {
opacity : 0.6;
}
.palette-manager-color-card .palette-manager-delete-card:hover {
opacity : 1;
color: rgb(240,80,80);
}
.palette-manager-new-color .palette-manager-color-square {
border: 3px dotted #888;
border-bottom-width: 0;
box-sizing: border-box;
-moz-box-sizing: border-box;
border-radius: 3px 3px 0 0;
cursor: pointer;
text-align: center;
font-size: 24px;
color: #888;
line-height: 120px;
}
.palette-manager-color-square {
width: 120px;
height: 120px;
cursor: pointer;
/*background-image:url(../img/tools/eyedropper.png);*/
}
.palette-manager-color-details {
color : #666;
background: #eee;
height: 60px;
padding-left: 5px;
}
.palette-manager-color-details li{
line-height: 20px;
font-weight: bold;
}

View File

@ -79,6 +79,7 @@
}
.dialog-wrapper {
height: 100%;
position : relative;
}
@ -101,4 +102,4 @@
margin-right: 10px;
font-size: 1.3em;
cursor: pointer;
}
}

View File

@ -1,10 +1,10 @@
@font-face {
font-family: 'piskel';
src:url('fonts/piskel.eot?-3olv93');
src:url('fonts/piskel.eot?#iefix-3olv93') format('embedded-opentype'),
url('fonts/piskel.woff?-3olv93') format('woff'),
url('fonts/piskel.ttf?-3olv93') format('truetype'),
url('fonts/piskel.svg?-3olv93#icomoon') format('svg');
src:url('fonts/icomoon.eot?-3olv93');
src:url('fonts/icomoon.eot?#iefix-3olv93') format('embedded-opentype'),
url('fonts/icomoon.woff?-3olv93') format('woff'),
url('fonts/icomoon.ttf?-3olv93') format('truetype'),
url('fonts/icomoon.svg?-3olv93#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
@ -31,3 +31,66 @@
content: "\e601";
}
.piskel-icon-download:before {
content: "\e600";
}
.piskel-icon-rotateleft:before {
content: "\e603";
}
.piskel-icon-rotateright:before {
content: "\e604";
}
.piskel-icon-fliph:before {
content: "\e605";
}
.piskel-icon-flipv:before {
content: "\e606";
}
.piskel-icon-trashplain:before {
content: "\e607";
}
.piskel-icon-trash:before {
content: "\e608";
}
.piskel-icon-merge:before {
content: "\e609";
}
.piskel-icon-pencil:before {
content: "\e610";
}
.piskel-icon-close:before {
content: "\e611";
}
.piskel-icon-minus:before {
content: "\e60a";
}
.piskel-icon-plus:before {
content: "\e60b";
}
.piskel-icon-arrow-up-fat:before {
content: "\e60c";
}
.piskel-icon-arrow-down-fat:before {
content: "\e60d";
}
.piskel-icon-arrow-up-thin:before {
content: "\e60e";
}
.piskel-icon-arrow-down-thin:before {
content: "\e60f";
}

BIN
src/css/fonts/icomoon.eot Normal file

Binary file not shown.

28
src/css/fonts/icomoon.svg Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="512">
<font-face units-per-em="512" ascent="480" descent="-32" />
<missing-glyph horiz-adv-x="512" />
<glyph unicode="&#x20;" d="" horiz-adv-x="256" />
<glyph unicode="&#xe600;" d="M256 192l128 128h-96v128h-64v-128h-96zM372.363 244.364l-35.87-35.871 130.040-48.493-210.533-78.509-210.533 78.509 130.040 48.493-35.871 35.871-139.636-52.364v-128l256-96 256 96v128z" />
<glyph unicode="&#xe601;" d="M327.755 416.174l-24.759-21.971-1.481 8.030-14.159-4.099v-27.379l0.914-19.404 26.988 23.949c-0.347-4.934-0.51-10.141-0.166-15.921 0.543-9.151 3.055-17.374 8.057-23.811s11.74-10.557 19.211-13.967c14.942-6.822 33.56-18.012 56.377-36.978 43.203-35.907 48.548-53.828 56.334-85.404 7.412-41.045-4.368-70.606-21.368-95.68-12.144-17.918-27.179-33.815-60.225-40.518s-63.992-8.866-86.123-8.866v-22.304c23.555 0 55.469 2.195 90.553 9.313s69.693 18.531 90.832 40.649c22.885 23.941 44.76 67.328 31.672 135.162l-0.055 0.223c-5.829 27.055-23.529 67.689-92.729 97.775-28.624 12.445-44.153 20.477-55.829 25.809-5.837 2.666-9.197 6.119-11.030 8.475s-3.034 5.246-3.401 11.43c-0.827 13.918 1.198 24.507 3.318 31.505s3.904 9.702 3.904 9.702l-16.84 14.276zM303.444 372.291c0 0-16.082 4.204-16.082-1.173 0-29.786-0.407-35.048 9.808-56.095s23.399-42.701 43.302-61.078c37.637-34.753 34.591-40.033 40.837-57.911 2.3-6.582 3.27-21.87 1.673-33.875s-6.074-27.851-11.959-36.856c-9.25-14.152-16.702-28.62-34.395-38.447-18.488-10.269-34.432-12.486-49.265-12.486v-22.304c18.579 0 39.728 4.476 62.060 13.494s43.831 22.548 56.848 42.462c8.719 13.341 17.897 33.653 19.924 49.887s6.051 30.237-4.534 52.106c-16.294 33.661-37.961 43.77-64.413 66.162-16.375 13.863-31.099 30.183-40.029 48.578s-13.219 37.077-13.772 47.536zM300.488 357.961l-13.128-1.2c0.667-12.589 0-38.494 0-63.093 0-11.679 1.942-25.867 3.768-35.663 3.517-18.873 9.378-31.122 13.056-42.974 2.921-9.421 6.195-22.61 8.376-27.676 5.897-13.728 6.717-30.505 0.674-49.822-6.121-19.563-15.663-38.313-31.608-44.469l5.736-18.915c23.072 8.907 55.35 34.019 64.177 62.238 7.959 25.431 2.932 48.415-4.32 65.295-4.397 10.236-8.579 17.284-13.263 25.818-5.764 10.5-18.011 23.661-21.517 34.382-3.19 9.75-6.983 21.54-7.96 33.601-1.955 24.118-3.242 48.871-3.986 62.479zM248.405 416.148l24.758-21.971 1.481 8.029 14.159-4.099v-27.379l-0.914-19.403-26.988 23.949c0.347-4.933 0.51-10.141 0.166-15.92-0.543-9.152 0.548-18.276-4.452-24.711s-10.838-15.063-18.308-18.475c-14.942-6.823-32.661-18.010-55.476-36.978-43.203-35.907-42.239-45.718-50.025-77.294-2.905-41.947-5.284-41.359 4.244-70.447 5.757-17.579 19.97-34.716 53.016-50.429 30.453-14.481 76.609-26.889 98.737-26.889v-22.304c-23.555 0-55.469 2.195-90.553 9.309s-69.692 18.531-90.832 40.649c-22.885 23.94-44.76 67.329-31.671 135.162l0.055 0.223c5.829 27.055 23.529 67.689 92.731 97.775 28.623 12.445 44.153 20.477 55.826 25.808 5.839 2.665 9.197 6.119 11.034 8.474s3.034 5.246 3.401 11.43c0.827 13.918-1.198 24.507-3.318 31.505s-3.903 9.702-3.903 9.702l16.84 14.274zM281.987 374.814l8.031-11.395c-0.667-12.589 0-38.494 0-63.093 0-11.68 3.154-27.141 1.329-36.938-3.517-18.873-3.009-25.387-6.684-37.239-2.921-9.421-6.195-25.794-8.376-30.864-5.897-13.728-7.354-45.161-1.31-64.478 6.121-19.563 9.928-44.689 19.498-59.125l3.56-36.712c-21.161 28.662-42.512 61.597-51.342 89.814-7.958 25.431-7.393 70.082-0.139 86.961 4.398 10.236 8.578 20.472 13.263 29.004 5.764 10.5 9.043 20.958 11.649 32.578 2.245 10.010 6.192 26.31 7.168 38.372 1.955 24.121 2.604 49.509 3.351 63.117z" horiz-adv-x="576" />
<glyph unicode="&#xe602;" d="M256 384c-111.659 0-208.441-65.021-256-160 47.559-94.979 144.341-160 256-160 111.657 0 208.439 65.021 256 160-47.558 94.979-144.343 160-256 160zM382.225 299.148c30.081-19.187 55.571-44.887 74.717-75.148-19.146-30.261-44.637-55.961-74.718-75.149-37.797-24.108-81.445-36.851-126.224-36.851-44.78 0-88.428 12.743-126.225 36.852-30.080 19.186-55.57 44.886-74.717 75.148 19.146 30.262 44.637 55.962 74.717 75.148 1.959 1.25 3.938 2.461 5.929 3.65-4.979-13.664-7.704-28.411-7.704-43.798 0-70.692 57.308-128 128-128s128 57.308 128 128c0 15.387-2.725 30.134-7.704 43.799 1.99-1.189 3.969-2.401 5.929-3.651zM256 275c0-26.51-21.49-48-48-48s-48 21.49-48 48 21.49 48 48 48 48-21.49 48-48z" />
<glyph unicode="&#xe603;" d="M256 448c-70.692 0-134.688-28.66-181.016-74.989l-74.984 74.989v-192h192l-71.766 71.761c34.748 34.746 82.746 56.239 135.766 56.239 106.034 0 192-85.962 192-192 0-57.348-25.146-108.818-65.009-144l42.333-48c53.151 46.908 86.676 115.538 86.676 192 0 141.385-114.615 256-256 256z" />
<glyph unicode="&#xe604;" d="M0 192c0-76.462 33.524-145.092 86.675-192l42.333 48c-39.863 35.182-65.008 86.652-65.008 144 0 106.038 85.965 192 192 192 53.021 0 101.019-21.493 135.765-56.239l-71.765-71.761h192v192l-74.985-74.989c-46.327 46.329-110.322 74.989-181.015 74.989-141.385 0-256-114.615-256-256z" />
<glyph unicode="&#xe605;" d="M0 288h512v192zM512 0v192h-512z" />
<glyph unicode="&#xe606;" d="M288 480v-512h192zM0-32h192v512z" />
<glyph unicode="&#xe607;" d="M96-32h320l32 352h-384zM320 416v64h-128v-64h-160v-96l32 32h384l32-32v96h-160zM288 416h-64v32h64v-32z" />
<glyph unicode="&#xe608;" d="M400 416h-288c-26.51 0-48-21.49-48-48v-16h384v16c0 26.51-21.49 48-48 48zM316.16 448l7.058-50.5h-134.436l7.057 50.5h120.321zM320 480h-128c-13.2 0-25.495-10.696-27.321-23.769l-9.357-66.962c-1.827-13.073 7.478-23.769 20.678-23.769h160c13.2 0 22.505 10.696 20.679 23.769l-9.357 66.962c-1.827 13.073-14.122 23.769-27.322 23.769v0zM408 320h-304c-17.6 0-30.696-14.341-29.103-31.869l26.206-288.263c1.593-17.527 17.297-31.868 34.897-31.868h240c17.6 0 33.304 14.341 34.897 31.868l26.205 288.263c1.594 17.528-11.502 31.869-29.102 31.869zM192 32h-48l-16 224h64v-224zM288 32h-64v224h64v-224zM368 32h-48v224h64l-16-224z" />
<glyph unicode="&#xe609;" d="M448 224h-80l-112-112-112 112h-80l-64-128v-32h512v32l-64 128zM0 32h512v-32h-512v32zM288 320v128h-64v-128h-112l144-144 144 144h-112z" />
<glyph unicode="&#xe60a;" d="M0 272v-96c0-8.836 7.164-16 16-16h480c8.836 0 16 7.164 16 16v96c0 8.836-7.164 16-16 16h-480c-8.836 0-16-7.164-16-16z" />
<glyph unicode="&#xe60b;" d="M496 288h-176v176c0 8.836-7.164 16-16 16h-96c-8.836 0-16-7.164-16-16v-176h-176c-8.836 0-16-7.164-16-16v-96c0-8.836 7.164-16 16-16h176v-176c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v176h176c8.836 0 16 7.164 16 16v96c0 8.836-7.164 16-16 16z" />
<glyph unicode="&#xe60c;" d="M256.001 480l-256.001-256h160v-255.999l192-0.001v256h160z" />
<glyph unicode="&#xe60d;" d="M256-32l256 256h-160v255.999l-192 0.001v-256h-160z" />
<glyph unicode="&#xe60e;" d="M438.627 278.627l-160 160c-12.496 12.497-32.757 12.497-45.254 0l-160-160c-12.497-12.497-12.497-32.758 0-45.255 12.497-12.498 32.758-12.498 45.255 0l105.372 105.373v-306.745c0-17.673 14.327-32 32-32s32 14.327 32 32v306.745l105.373-105.373c6.248-6.248 14.438-9.372 22.627-9.372s16.379 3.124 22.627 9.373c12.497 12.497 12.497 32.757 0 45.254z" />
<glyph unicode="&#xe60f;" d="M73.373 169.373l160-160c12.496-12.497 32.758-12.497 45.255 0l160 160c12.496 12.497 12.496 32.758 0 45.255-12.497 12.497-32.758 12.497-45.255 0l-105.373-105.373v306.745c0 17.673-14.327 32-32 32s-32-14.327-32-32v-306.745l-105.373 105.373c-6.248 6.248-14.438 9.372-22.627 9.372s-16.379-3.124-22.627-9.372c-12.497-12.497-12.497-32.758 0-45.255z" />
<glyph unicode="&#xe610;" d="M432 480c44.182 0 80-35.817 80-80 0-18.010-5.955-34.629-16-48l-32-32-112 112 32 32c13.371 10.045 29.989 16 48 16zM32 112l-32-144 144 32 296 296-112 112-296-296zM357.789 298.211l-224-224-27.578 27.578 224 224 27.578-27.578z" />
<glyph unicode="&#xe611;" d="M507.331 68.67c-0.002 0.002-0.004 0.004-0.006 0.005l-155.322 155.325 155.322 155.325c0.002 0.002 0.004 0.003 0.006 0.005 1.672 1.673 2.881 3.627 3.656 5.708 2.123 5.688 0.912 12.341-3.662 16.915l-73.373 73.373c-4.574 4.573-11.225 5.783-16.914 3.66-2.080-0.775-4.035-1.984-5.709-3.655 0-0.002-0.002-0.003-0.004-0.005l-155.324-155.326-155.324 155.325c-0.002 0.002-0.003 0.003-0.005 0.005-1.673 1.671-3.627 2.88-5.707 3.655-5.69 2.124-12.341 0.913-16.915-3.66l-73.374-73.374c-4.574-4.574-5.784-11.226-3.661-16.914 0.776-2.080 1.985-4.036 3.656-5.708 0.002-0.001 0.003-0.003 0.005-0.005l155.325-155.324-155.325-155.326c-0.001-0.002-0.003-0.003-0.004-0.005-1.671-1.673-2.88-3.627-3.657-5.707-2.124-5.688-0.913-12.341 3.661-16.915l73.374-73.373c4.575-4.574 11.226-5.784 16.915-3.661 2.080 0.776 4.035 1.985 5.708 3.656 0.001 0.002 0.003 0.003 0.005 0.005l155.324 155.325 155.324-155.325c0.002-0.001 0.004-0.003 0.006-0.004 1.674-1.672 3.627-2.881 5.707-3.657 5.689-2.123 12.342-0.913 16.914 3.661l73.373 73.374c4.574 4.574 5.785 11.227 3.662 16.915-0.776 2.080-1.985 4.034-3.657 5.707z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
src/css/fonts/icomoon.ttf Normal file

Binary file not shown.

BIN
src/css/fonts/icomoon.woff Normal file

Binary file not shown.

View File

@ -5,6 +5,20 @@
background-position: 50%;
}
.action-icon.edit-icon {
.edit-icon {
background-image: url('../img/tools/pen.png');
background-repeat: no-repeat;
}
.merge-icon {
background-image: url('../img/merge-icon.png');
background-repeat: no-repeat;
}
.plus-icon {
font-size:15px;
text-align:center;
}
.delete-icon {
}

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

@ -0,0 +1,154 @@
/**
* Application layout
*/
.main-wrapper {
position: absolute;
top: 5px;
right: 0;
bottom: 5px;
left: 0;
}
.column-wrapper {
text-align: center;
font-size: 0;
position: absolute;
left: 100px; /* Reserve room for tools on the left edge of the screen. */
top: 0;
right: 50px; /* Reserve room for actions on the right edge of the screen. */
bottom: 0;
}
.column {
display: inline-block;
}
.left-column {
vertical-align: top;
height: 100%;
margin-right: 7px;
}
.main-column {
height: 100%;
position: relative;
}
.right-column {
vertical-align: top;
margin-left: 10px;
height: 100%;
position: relative;
}
.drawing-canvas-container {
font-size: 0;
}
.sticky-section {
position: fixed;
top: 0;
bottom: 0;
z-index: 1000;
}
.sticky-section .sticky-section-wrap {
display: table;
height: 100%;
}
.sticky-section .vertical-centerer {
display: table-cell;
vertical-align: middle;
}
.left-sticky-section.sticky-section {
left: 0;
max-width: 100px;
}
.left-sticky-section .tool-icon {
float: left;
}
.cursor-coordinates {
color:#888;
font-size:12px;
font-weight:bold;
font-family:Courier;
}
/**
* Canvases layout
*/
.canvas {
position: relative;
z-index: 1;
}
.canvas-container {
position: relative;
display: block;
}
.canvas-container .canvas-background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.light-picker-background,
.light-canvas-background .canvas-background {
background: url(../img/canvas_background/light_canvas_background.png) repeat;
}
.medium-picker-background,
.medium-canvas-background .canvas-background {
background: url(../img/canvas_background/medium_canvas_background.png) repeat;
}
.lowcont-medium-picker-background,
.lowcont-medium-canvas-background .canvas-background {
background: url(../img/canvas_background/lowcont_medium_canvas_background.png) repeat;
}
.lowcont-dark-picker-background,
.lowcont-dark-canvas-background .canvas-background {
background: url(../img/canvas_background/lowcont_dark_canvas_background.png) repeat;
}
.layers-canvas,
.canvas.onion-skin-canvas {
opacity: 0.2;
}
.canvas.canvas-overlay,
.canvas.layers-canvas,
.canvas.onion-skin-canvas {
position: absolute;
top: 0;
left: 0;
}
.tools-wrapper,
.options-wrapper,
.palette-wrapper {
float : left;
}
/**
* Z-indexes should match the drawing area canvas superposition order :
* - 1 : draw layers below current layer
* - 2 : draw current layer
* - 3 : draw layers above current layer
* - 4 : draw the tools overlay
*/
.canvas.layers-below-canvas {z-index: 7;}
.canvas.drawing-canvas {z-index: 8;}
.canvas.canvas-overlay {z-index: 9;}
.canvas.onion-skin-canvas {z-index: 10;}
.canvas.layers-above-canvas {z-index: 11;}

74
src/css/notifications.css Normal file
View File

@ -0,0 +1,74 @@
.user-message {
position: absolute;
right: 0;
bottom: 0;
padding: 10px 47px;
max-width: 300px;
border-top-left-radius: 7px;
border: #F0C36D 1px solid;
border-right: 0;
border-bottom: 0;
color: #222;
background-color: #F9EDBE;
font-weight: bold;
font-size: 13px;
z-index: 30000;
}
.user-message .close {
position: absolute;
top: 6px;
right: 17px;
color: gray;
font-size: 18px;
font-weight: bold;
cursor: pointer;
}
.user-message .close:hover {
color: black;
}
.progress-bar-container {
position: absolute;
left: 0;
bottom: 0;
padding: 10px;
width: 360px;
border-top-right-radius: 2px;
border: gold 2px solid;
border-left: 0;
border-bottom: 0;
background-color: #444;
font-size: 14px;
z-index: 30000;
color: #eee;
}
.progress-bar-item {
float: left;
height:20px;
}
.progress-bar-status {
line-height: 20px;
width : 40px;
overflow : hidden;
margin: 0 0 0 10px;
}
.progress-bar {
border : 1px solid grey;
margin-top: 8px;
height : 4px;
width : 300px;
background : linear-gradient(to left, gold, gold) no-repeat -300px 0;
background-color : black;
}

View File

@ -51,15 +51,4 @@
-moz-box-sizing:border-box;
background: rgba(0,0,0,0.5);
color: white;
}
.gif-export-progress-status {
margin-left: 5px;
}
.gif-export-progress-bar {
margin-top:5px;
height:3px;
width: 0;
background:gold;
}
}

View File

@ -20,182 +20,8 @@ body {
user-select: initial;
}
/**
* 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;
}
/**
* 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;}
/**
* User messages
*/
.user-message {
position: absolute;
right: 0;
bottom: 0;
background-color: #F9EDBE;
padding: 10px 47px;
border-top-left-radius: 7px;
color: #222;
border: #F0C36D 1px solid;
border-right: 0;
border-bottom: 0;
font-weight: bold;
font-size: 13px;
z-index: 30000;
max-width: 300px;
}
.user-message .close {
position: absolute;
top: 6px;
right: 17px;
color: gray;
font-weight: bold;
cursor: pointer;
font-size: 18px;
}
.user-message .close:hover {
color: black;
.no-overflow {
overflow : hidden;
}
.image-link {
@ -224,10 +50,3 @@ body {
.pull-left {
left:0;
}
.cursor-coordinates {
color:#888;
font-size:12px;
font-weight:bold;
font-family:Courier;
}

View File

@ -5,18 +5,21 @@
.layers-list-container {
}
.layers-title {
/*.layers-title {
background-image: url('../img/layers.svg');
background-size: 22px;
background-repeat: no-repeat;
background-position: 97%;
}*/
.layers-title {
position: relative;
}
.layers-toggle-preview {
position: absolute;
top: 0.3em;
right: 2em;
right: 0.5em;
color: #999;
font-size: 1.3em;
@ -46,22 +49,6 @@
cursor : pointer;
}
.layer-item .edit-icon {
float: right;
width: 30px;
background-size: 12px;
opacity: 0;
transition : opacity 0.2s;
}
.layer-item:hover .edit-icon {
opacity : 0.6;
}
.layer-item:hover .edit-icon:hover {
opacity : 1;
}
.layer-item:hover {
background : #222;
}
@ -72,7 +59,21 @@
color: gold;
}
.layers-button-arrow {
font-family : 'Lucida Grande', Calibri;
padding : 2px 6px 0 6px;
.layers-button-container {
overflow : hidden;
}
.layers-button {
margin: 0;
width: 16.66667%;
float : left;
}
/* @override */
.layers-button-container .layers-button {
border-left-width: 0;
}
.layers-button:last-child {
border-right-width: 0;
}

View File

@ -1,63 +1,106 @@
.palettes-list-select {
float:right;
max-width:90px;
margin-top: 3px;
}
.palettes-title {
background-size: 22px;
background-repeat: no-repeat;
background-position: 97%;
background-size: 22px;
background-repeat: no-repeat;
background-position: 97%;
}
.palettes-list-colors {
overflow: auto;
max-height: 160px;
overflow: auto;
max-height: 160px;
}
.palettes-list-color {
cursor : pointer;
float: left;
margin : 0 0 5px 5px;
width : 32px;
height : 32px;
position: relative;
cursor: pointer;
float: left;
margin: 0 0 5px 5px;
width: 32px;
height: 32px;
position: relative;
}
.palettes-list-color:nth-child(-n+5) {
margin-top: 5px;
margin-top: 5px;
}
.palettes-list-color div{
width : 32px;
height : 32px;
.palettes-list-color div {
width: 32px;
height: 32px;
}
.palettes-list-has-scrollbar .palettes-list-color,
.palettes-list-has-scrollbar .palettes-list-color div{
width: 29px
.palettes-list-has-scrollbar .palettes-list-color, .palettes-list-has-scrollbar .palettes-list-color div {
width: 29px
}
.palettes-list-primary-color:before,
.palettes-list-secondary-color:before {
content: "";
position: absolute;
bottom: 1px;
display: inline-block;
border: 7px solid gold;
border-top-color: transparent;
width: 0px;
height: 0px;
.palettes-list-primary-color:before, .palettes-list-secondary-color:before {
content: "";
position: absolute;
bottom: 1px;
display: inline-block;
border: 7px solid gold;
border-top-color: transparent;
width: 0px;
height: 0px;
}
.palettes-list-primary-color:before {
left: 1px;
border-right-color: transparent;
left: 1px;
border-right-color: transparent;
}
.palettes-list-secondary-color:before {
right: 1px;
border-left-color: transparent;
}
.palettes-list-actions {
background-color: #3f3f3f;
border-bottom-color: #222;
height: 24px;
padding: 0;
overflow: hidden;
}
.palettes-list-button,
.palettes-list-select {
margin: 0;
float: left;
}
.palettes-list-secondary-color:before {
right: 1px;
border-left-color: transparent;
}
.palettes-list-button {
width: 16.66667%;
}
.palettes-list-select {
width: 66.66667%;
height: 100%;
padding: 0 5px 0 5px;
border-style: solid;
border-width: 1px 0 1px 0;
color: #aaa;
font-size : 0.75em;
/*thanks firefox, you suck*/
text-align:left;
/*text-shadow:none;*/
font-weight: normal;
transition : background-color 0.3s, color 0.3s;
cursor:pointer;
}
.palettes-list-select:hover {
color: white;
background-color: #484848;
}
.palettes-list-select:focus {
background-color: #484848;
color: white;
outline: none;
}
.palettes-list-actions .edit-icon {
background-size: 15px;
background-position: 50%;
}
.palettes-list-no-colors {
height: 42px;
width: 100%;
color: grey;
font-size: 0.7em;
font-style: italic;
line-height: 42px;
text-align: center
}

View File

@ -14,23 +14,4 @@
margin: 0;
font-size: 15px;
background: #222;
}
.toolbox-button-container {
overflow : hidden;
}
.toolbox-button {
margin: 0;
width: 25%;
float : left;
}
/* @override */
.button.toolbox-button {
border-left-width: 0;
}
.toolbox-button:last-child {
border-right-width: 0;
}

View File

@ -1,10 +1,3 @@
.tools-wrapper,
.options-wrapper,
.palette-wrapper {
float: left;
}
.tool-icon {
position : relative;
cursor : pointer;
@ -88,8 +81,8 @@
.tool-icon.tool-lighten {
background-image: url(../img/tools/lighten.png);
background-size: 30px 30px;
background-position: 8px 8px;
background-size: 30px 30px;
}
.tool-icon.tool-colorpicker {
@ -103,6 +96,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:
*/

View File

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

BIN
src/img/merge-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -44,6 +44,7 @@
<div class="column right-column">
<iframe src="templates/preview.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/layers-list.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/transformations.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<iframe src="templates/palettes-list.html" onload="iframeloader.onLoad(event)" data-iframe-loader="display"></iframe>
<div class="pull-bottom cursor-coordinates"></div>
</div>
@ -67,17 +68,19 @@
<div id="dialog-container-wrapper">
<div id="dialog-container">
<iframe src="templates/dialogs/manage-palettes.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
<iframe src="templates/dialogs/create-palette.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
<iframe src="templates/dialogs/import-image.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
<iframe src="templates/dialogs/browse-local.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
</div>
</div>
<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>

View File

@ -27,7 +27,6 @@ var Constants = {
NO_PALETTE_ID : '__no-palette',
CURRENT_COLORS_PALETTE_ID : '__current-colors',
MANAGE_PALETTE_ID : '__manage-palettes',
// Used for Spectrum input
PREFERRED_COLOR_FORMAT : 'rgb',

View File

@ -47,6 +47,10 @@ var Events = {
SHOW_NOTIFICATION: "SHOW_NOTIFICATION",
HIDE_NOTIFICATION: "HIDE_NOTIFICATION",
SHOW_PROGRESS: "SHOW_PROGRESS",
UPDATE_PROGRESS: "UPDATE_PROGRESS",
HIDE_PROGRESS: "HIDE_PROGRESS",
ZOOM_CHANGED : "ZOOM_CHANGED",
CURRENT_COLORS_UPDATED : "CURRENT_COLORS_UPDATED",

View File

@ -11,7 +11,6 @@
init : function () {
/**
* True when piskel is running in static mode (no back end needed).
* When started from APP Engine, appEngineToken_ (Boolean) should be set on window.pskl
*/
this.isAppEngineVersion = !!pskl.appEngineToken_;
@ -39,6 +38,10 @@
this.piskelController = new pskl.controller.piskel.PublicPiskelController(this.corePiskelController);
this.piskelController.init();
this.paletteImportService = new pskl.service.palette.PaletteImportService();
this.paletteService = new pskl.service.palette.PaletteService();
this.paletteService.addDynamicPalette(new pskl.service.palette.CurrentColorsPalette());
this.paletteController = new pskl.controller.PaletteController();
this.paletteController.init();
@ -84,6 +87,12 @@
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();
this.canvasBackgroundController = new pskl.controller.CanvasBackgroundController();
this.canvasBackgroundController.init();

View File

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

View File

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

View File

@ -28,6 +28,31 @@
this.layersListEl.innerHTML = '';
var layers = this.piskelController.getLayers();
layers.forEach(this.addLayerItem.bind(this));
this.updateButtonStatus_();
};
ns.LayersListController.prototype.updateButtonStatus_ = function () {
var layers = this.piskelController.getLayers();
var currentLayer = this.piskelController.getCurrentLayer();
var index = this.piskelController.getCurrentLayerIndex();
var isLast = index === 0;
var isOnly = layers.length === 1;
var isFirst = index === layers.length - 1;
this.toggleButtonDisabledState_('up', isFirst);
this.toggleButtonDisabledState_('down', isLast);
this.toggleButtonDisabledState_('merge', isLast);
this.toggleButtonDisabledState_('delete', isOnly);
};
ns.LayersListController.prototype.toggleButtonDisabledState_ = function (buttonAction, isDisabled) {
var button = document.querySelector('.layers-button[data-action="'+buttonAction+'"]');
if (isDisabled) {
button.setAttribute('disabled', 'disabled');
} else {
button.removeAttribute('disabled');
}
};
ns.LayersListController.prototype.updateToggleLayerPreview_ = function () {
@ -64,21 +89,25 @@
} else if (el.classList.contains('layer-item')) {
index = el.dataset.layerIndex;
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
} else if (el.classList.contains('edit-icon')) {
index = el.parentNode.dataset.layerIndex;
this.renameLayerAt_(index);
}
};
ns.LayersListController.prototype.renameLayerAt_ = function (index) {
var layer = this.piskelController.getLayerAt(index);
ns.LayersListController.prototype.renameCurrentLayer_ = function () {
var layer = this.piskelController.getCurrentLayer();
var name = window.prompt("Please enter the layer name", layer.getName());
if (name) {
var index = this.piskelController.getCurrentLayerIndex();
this.piskelController.renameLayerAt(index, name);
this.renderLayerList_();
}
};
ns.LayersListController.prototype.mergeDownCurrentLayer_ = function () {
var index = this.piskelController.getCurrentLayerIndex();
this.piskelController.mergeDownLayerAt(index);
this.renderLayerList_();
};
ns.LayersListController.prototype.onButtonClick_ = function (button) {
var action = button.getAttribute('data-action');
if (action == 'up') {
@ -89,6 +118,10 @@
this.piskelController.createLayer();
} else if (action == 'delete') {
this.piskelController.removeCurrentLayer();
} else if (action == 'merge') {
this.mergeDownCurrentLayer_();
} else if (action == 'edit') {
this.renameCurrentLayer_();
}
};

View File

@ -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);
}
};
/**

View File

@ -13,70 +13,82 @@
ns.PalettesListController = function (paletteController, usedColorService) {
this.usedColorService = usedColorService;
this.paletteService = pskl.app.paletteService;
this.paletteController = paletteController;
};
ns.PalettesListController.prototype.init = function () {
this.paletteColorTemplate_ = pskl.utils.Template.get('palette-color-template');
this.colorListContainer_ = document.querySelector('.palettes-list-colors');
this.colorPaletteSelect_ = document.querySelector('.palettes-list-select');
this.paletteListOptGroup_ = document.querySelector('.palettes-list-select-group');
var createPaletteButton_ = document.querySelector('.create-palette-button');
var editPaletteButton_ = document.querySelector('.edit-palette-button');
this.colorPaletteSelect_.addEventListener('change', this.onPaletteSelected_.bind(this));
this.colorListContainer_.addEventListener('mouseup', this.onColorContainerMouseup.bind(this));
this.colorListContainer_.addEventListener('contextmenu', this.onColorContainerContextMenu.bind(this));
createPaletteButton_.addEventListener('click', this.onCreatePaletteClick_.bind(this));
editPaletteButton_.addEventListener('click', this.onEditPaletteClick_.bind(this));
$.subscribe(Events.PALETTE_LIST_UPDATED, this.onPaletteListUpdated.bind(this));
$.subscribe(Events.CURRENT_COLORS_UPDATED, this.fillColorListContainer.bind(this));
$.subscribe(Events.PRIMARY_COLOR_SELECTED, this.highlightSelectedColors.bind(this));
$.subscribe(Events.SECONDARY_COLOR_SELECTED, this.highlightSelectedColors.bind(this));
$.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this));
pskl.app.shortcutService.addShortcuts(['>', 'shift+>'], this.selectNextColor_.bind(this));
pskl.app.shortcutService.addShortcut('<', this.selectPreviousColor_.bind(this));
this.fillPaletteList();
this.selectPaletteFromUserSettings();
this.updateFromUserSettings();
this.fillColorListContainer();
};
ns.PalettesListController.prototype.fillPaletteList = function () {
var palettes = [{
id : Constants.NO_PALETTE_ID,
name : 'No palette'
}];
palettes = palettes.concat(this.retrievePalettes());
var palettes = this.paletteService.getPalettes();
var html = palettes.map(function (palette) {
return pskl.utils.Template.replace('<option value="{{id}}">{{name}}</option>', palette);
}).join('');
this.paletteListOptGroup_.innerHTML = html;
this.colorPaletteSelect_.innerHTML = html;
};
ns.PalettesListController.prototype.fillColorListContainer = function () {
var colors = this.getSelectedPaletteColors_();
var html = colors.map(function (color) {
return pskl.utils.Template.replace(this.paletteColorTemplate_, {color : color});
}.bind(this)).join('');
this.colorListContainer_.innerHTML = html;
if (colors.length > 0) {
var html = colors.map(function (color, index) {
return pskl.utils.Template.replace(this.paletteColorTemplate_, {color : color, index : index});
}.bind(this)).join('');
this.colorListContainer_.innerHTML = html;
this.highlightSelectedColors();
this.highlightSelectedColors();
var hasScrollbar = colors.length > NO_SCROLL_MAX_COLORS;
if (hasScrollbar && !pskl.utils.UserAgent.isChrome) {
this.colorListContainer_.classList.add(HAS_SCROLL_CLASSNAME);
var hasScrollbar = colors.length > NO_SCROLL_MAX_COLORS;
if (hasScrollbar && !pskl.utils.UserAgent.isChrome) {
this.colorListContainer_.classList.add(HAS_SCROLL_CLASSNAME);
} else {
this.colorListContainer_.classList.remove(HAS_SCROLL_CLASSNAME);
}
} else {
this.colorListContainer_.classList.remove(HAS_SCROLL_CLASSNAME);
this.colorListContainer_.innerHTML = pskl.utils.Template.get('palettes-list-no-colors-partial');
}
};
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, paletteId);
};
ns.PalettesListController.prototype.getSelectedPaletteColors_ = function () {
var colors = [];
var paletteId = this.colorPaletteSelect_.value;
if (paletteId === Constants.CURRENT_COLORS_PALETTE_ID) {
colors = this.usedColorService.getCurrentColors();
} else {
var palette = this.getPaletteById(paletteId, this.retrievePalettes());
if (palette) {
colors = palette.colors;
}
var palette = this.getSelectedPalette_();
if (palette) {
colors = palette.getColors();
}
if (colors.length > Constants.MAX_CURRENT_COLORS_DISPLAYED) {
@ -86,27 +98,65 @@
return colors;
};
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
this.colorPaletteSelect_.value = paletteId;
ns.PalettesListController.prototype.getSelectedPalette_ = function () {
var paletteId = pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE);
return this.paletteService.getPaletteById(paletteId);
};
ns.PalettesListController.prototype.selectPaletteFromUserSettings = function () {
this.selectPalette(pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE));
ns.PalettesListController.prototype.selectNextColor_ = function () {
this.selectColor_(this.getCurrentColorIndex_() + 1);
};
ns.PalettesListController.prototype.selectPreviousColor_ = function () {
this.selectColor_(this.getCurrentColorIndex_() - 1);
};
ns.PalettesListController.prototype.getCurrentColorIndex_ = function () {
var currentIndex = 0;
var selectedColor = document.querySelector('.' + PRIMARY_COLOR_CLASSNAME);
if (selectedColor) {
currentIndex = parseInt(selectedColor.dataset.colorIndex, 10);
}
return currentIndex;
};
ns.PalettesListController.prototype.selectColor_ = function (index) {
var colors = this.getSelectedPaletteColors_();
var color = colors[index];
if (color) {
$.publish(Events.SELECT_PRIMARY_COLOR, [color]);
}
};
ns.PalettesListController.prototype.onUserSettingsChange_ = function (evt, name, value) {
if (name == pskl.UserSettings.SELECTED_PALETTE) {
this.updateFromUserSettings();
}
};
ns.PalettesListController.prototype.updateFromUserSettings = function () {
var paletteId = pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE);
this.fillColorListContainer();
this.colorPaletteSelect_.value = paletteId;
};
ns.PalettesListController.prototype.onPaletteSelected_ = function (evt) {
var paletteId = this.colorPaletteSelect_.value;
if (paletteId === Constants.MANAGE_PALETTE_ID) {
$.publish(Events.DIALOG_DISPLAY, 'manage-palettes');
this.selectPaletteFromUserSettings();
} else {
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, paletteId);
}
this.fillColorListContainer();
this.selectPalette(paletteId);
this.colorPaletteSelect_.blur();
};
ns.PalettesListController.prototype.onCreatePaletteClick_ = function (evt) {
$.publish(Events.DIALOG_DISPLAY, 'create-palette');
};
ns.PalettesListController.prototype.onEditPaletteClick_ = function (evt) {
var paletteId = this.colorPaletteSelect_.value;
$.publish(Events.DIALOG_DISPLAY, {
dialogId : 'create-palette',
initArgs : paletteId
});
};
ns.PalettesListController.prototype.onColorContainerContextMenu = function (event) {
event.preventDefault();
@ -155,24 +205,6 @@
ns.PalettesListController.prototype.onPaletteListUpdated = function () {
this.fillPaletteList();
this.selectPaletteFromUserSettings();
this.fillColorListContainer();
};
ns.PalettesListController.prototype.getPaletteById = function (paletteId, palettes) {
var match = null;
palettes.forEach(function (palette) {
if (palette.id === paletteId) {
match = palette;
}
});
return match;
};
ns.PalettesListController.prototype.retrievePalettes = function () {
var palettesString = window.localStorage.getItem('piskel.palettes');
return JSON.parse(palettesString) || [];
this.updateFromUserSettings();
};
})();

View File

@ -218,7 +218,7 @@
};
ns.PreviewFilmController.prototype.clonePreviewCanvas_ = function (canvas) {
var clone = pskl.CanvasUtils.clone(canvas);
var clone = pskl.utils.CanvasUtils.clone(canvas);
clone.classList.add('tile-view', 'canvas');
return clone;
};

View File

@ -0,0 +1,61 @@
(function () {
var ns = $.namespace('pskl.controller');
ns.ProgressBarController = function () {
this.template = pskl.utils.Template.get('progress-bar-template');
this.progressBar = null;
this.progressBarStatus = null;
this.showProgressTimer_ = 0;
};
ns.ProgressBarController.prototype.init = function () {
$.subscribe(Events.SHOW_PROGRESS, $.proxy(this.showProgress_, this));
$.subscribe(Events.UPDATE_PROGRESS, $.proxy(this.updateProgress_, this));
$.subscribe(Events.HIDE_PROGRESS, $.proxy(this.hideProgress_, this));
};
ns.ProgressBarController.prototype.showProgress_ = function (event, progressInfo) {
this.removeProgressBar_();
this.showProgressTimer_ = window.setTimeout(this.onTimerExpired_.bind(this, progressInfo), 300);
};
ns.ProgressBarController.prototype.onTimerExpired_ = function (progressInfo) {
var progressBarHtml = pskl.utils.Template.replace(this.template, {
name : progressInfo.name,
status : 0
});
var progressBarEl = pskl.utils.Template.createFromHTML(progressBarHtml);
document.body.appendChild(progressBarEl);
this.progressBar = document.querySelector('.progress-bar');
this.progressBarStatus = document.querySelector('.progress-bar-status');
};
ns.ProgressBarController.prototype.updateProgress_ = function (event, progressInfo) {
if (this.progressBar && this.progressBarStatus) {
var progress = progressInfo.progress;
var width = this.progressBar.offsetWidth;
var progressWidth = width - ((progress * width) / 100);
this.progressBar.style.backgroundPosition = (-progressWidth) + 'px 0';
this.progressBarStatus.innerHTML = progress + '%';
}
};
ns.ProgressBarController.prototype.hideProgress_ = function (event, progressInfo) {
if (this.showProgressTimer_) {
window.clearTimeout(this.showProgressTimer_);
}
this.removeProgressBar_();
};
ns.ProgressBarController.prototype.removeProgressBar_ = function () {
var progressBarContainer = document.querySelector('.progress-bar-container');
if (progressBarContainer) {
progressBarContainer.parentNode.removeChild(progressBarContainer);
this.progressBar = null;
this.progressBarStatus = null;
}
};
})();

View File

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

View 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;
};
})();

View File

@ -12,7 +12,15 @@
ns.AbstractDialogController.prototype.destroy = function () {};
ns.AbstractDialogController.prototype.closeDialog = function () {
this.destroy();
$.publish(Events.DIALOG_HIDE);
};
ns.AbstractDialogController.prototype.setTitle = function (title) {
var dialogTitle = document.querySelector('.dialog-title');
if (dialogTitle) {
dialogTitle.innerText = title;
}
};
})();

View File

@ -0,0 +1,127 @@
(function () {
var ns = $.namespace('pskl.controller.dialogs');
ns.CreatePaletteController = function (piskelController) {
this.paletteService = pskl.app.paletteService;
this.paletteImportService = pskl.app.paletteImportService;
};
pskl.utils.inherit(ns.CreatePaletteController, ns.AbstractDialogController);
ns.CreatePaletteController.prototype.init = function (paletteId) {
this.superclass.init.call(this);
this.hiddenFileInput = document.querySelector('.create-palette-import-input');
this.nameInput = document.querySelector('input[name="palette-name"]');
var buttonsContainer = document.querySelector('.create-palette-actions');
var deleteButton = document.querySelector('.create-palette-delete');
var downloadButton = document.querySelector('.create-palette-download-button');
var importFileButton = document.querySelector('.create-palette-import-button');
this.nameInput.addEventListener('input', this.onNameInputChange_.bind(this));
this.hiddenFileInput.addEventListener('change', this.onFileInputChange_.bind(this));
buttonsContainer.addEventListener('click', this.onButtonClick_.bind(this));
downloadButton.addEventListener('click', this.onDownloadButtonClick_.bind(this));
importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this));
var colorsListContainer = document.querySelector('.colors-container');
this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer);
var palette;
var isCurrentColorsPalette = paletteId == Constants.CURRENT_COLORS_PALETTE_ID;
if (paletteId && !isCurrentColorsPalette) {
importFileButton.style.display = 'none';
this.setTitle('Edit Palette');
var paletteObject = this.paletteService.getPaletteById(paletteId);
palette = pskl.model.Palette.fromObject(paletteObject);
} else {
downloadButton.style.display = 'none';
deleteButton.style.display = 'none';
this.setTitle('Create Palette');
var uuid = pskl.utils.Uuid.generate();
if (isCurrentColorsPalette) {
palette = new pskl.model.Palette(uuid, 'Current colors clone', this.getCurrentColors_());
} else {
palette = new pskl.model.Palette(uuid, 'New palette', []);
}
}
this.setPalette_(palette);
};
ns.CreatePaletteController.prototype.getCurrentColors_ = function () {
var palette = this.paletteService.getPaletteById(Constants.CURRENT_COLORS_PALETTE_ID);
return palette.getColors();
};
ns.CreatePaletteController.prototype.setPalette_ = function (palette) {
this.palette = palette;
this.nameInput.value = pskl.utils.unescapeHtml(palette.name);
this.colorsListWidget.setColors(palette.getColors());
};
ns.CreatePaletteController.prototype.destroy = function () {
this.colorsListWidget.destroy();
this.nameInput = null;
};
ns.CreatePaletteController.prototype.onButtonClick_ = function (evt) {
var target = evt.target;
if (target.dataset.action === 'submit') {
this.saveAndSelectPalette_();
} else if (target.dataset.action === 'cancel') {
this.closeDialog();
} else if (target.dataset.action === 'delete') {
this.deletePalette_();
}
};
ns.CreatePaletteController.prototype.saveAndSelectPalette_ = function () {
this.palette.setColors(this.colorsListWidget.getColors());
this.paletteService.savePalette(this.palette);
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, this.palette.id);
this.closeDialog();
};
ns.CreatePaletteController.prototype.deletePalette_ = function () {
if (window.confirm('Are you sure you want to delete palette ' + this.palette.name)) {
this.paletteService.deletePaletteById(this.palette.id);
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, Constants.CURRENT_COLORS_PALETTE_ID);
this.closeDialog();
}
};
ns.CreatePaletteController.prototype.onDownloadButtonClick_ = function () {
var paletteWriter = new pskl.service.palette.PaletteGplWriter(this.palette);
var paletteAsString = paletteWriter.write();
pskl.utils.BlobUtils.stringToBlob(paletteAsString, function(blob) {
pskl.utils.FileUtils.downloadAsFile(blob, this.palette.name + '.gpl');
}.bind(this), "application/json");
};
ns.CreatePaletteController.prototype.onImportFileButtonClick_ = function () {
this.hiddenFileInput.click();
};
ns.CreatePaletteController.prototype.onFileInputChange_ = function (evt) {
var files = this.hiddenFileInput.files;
if (files.length == 1) {
this.paletteImportService.read(files[0], this.setPalette_.bind(this), this.displayErrorMessage_.bind(this));
}
};
ns.CreatePaletteController.prototype.displayErrorMessage_ = function (message) {
message = "Could not import palette : " + message;
$.publish(Events.SHOW_NOTIFICATION, [{"content": message}]);
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
};
ns.CreatePaletteController.prototype.onNameInputChange_ = function (evt) {
this.palette.name = pskl.utils.escapeHtml(this.nameInput.value);
};
})();

View File

@ -2,9 +2,9 @@
var ns = $.namespace('pskl.controller.dialogs');
var dialogs = {
'manage-palettes' : {
template : 'templates/dialogs/manage-palettes.html',
controller : ns.PaletteManagerController
'create-palette' : {
template : 'templates/dialogs/create-palette.html',
controller : ns.CreatePaletteController
},
'browse-local' : {
template : 'templates/dialogs/browse-local.html',
@ -27,7 +27,8 @@
$.subscribe(Events.DIALOG_DISPLAY, this.onDialogDisplayEvent_.bind(this));
$.subscribe(Events.DIALOG_HIDE, this.onDialogHideEvent_.bind(this));
pskl.app.shortcutService.addShortcut('alt+P', this.onDialogDisplayEvent_.bind(this, null, 'manage-palettes'));
pskl.app.shortcutService.addShortcut('alt+P', this.onDialogDisplayEvent_.bind(this, null, 'create-palette'));
this.dialogWrapper_.classList.add('animated');
};
@ -42,8 +43,8 @@
if (!this.isDisplayed()) {
var config = dialogs[dialogId];
if (config) {
this.dialogContainer_.innerHTML = pskl.utils.Template.get(config.template);
this.dialogContainer_.classList.add(dialogId);
this.dialogContainer_.innerHTML = pskl.utils.Template.get(config.template);
var controller = new config.controller(this.piskelController);
controller.init(initArgs);

View File

@ -28,7 +28,7 @@
this.importImageForm = $('[name=import-image-form]');
this.importImageForm.submit(this.onImportFormSubmit_.bind(this));
pskl.utils.FileUtils.readFile(this.file_, this.processImageSource_.bind(this));
pskl.utils.FileUtils.readImageFile(this.file_, this.onImageLoaded_.bind(this));
};
ns.ImportImageController.prototype.onImportFormSubmit_ = function (evt) {
@ -55,18 +55,9 @@
}
};
/**
* Create an image from the given source (url or data-url), and onload forward to onImageLoaded
* TODO : should be a generic utility method, should take a callback
* @param {String} imageSource url or data-url, will be used as src for the image
*/
ns.ImportImageController.prototype.processImageSource_ = function (imageSource) {
this.importedImage_ = new Image();
this.importedImage_.onload = this.onImageLoaded_.bind(this);
this.importedImage_.src = imageSource;
};
ns.ImportImageController.prototype.onImageLoaded_ = function (image) {
this.importedImage_ = image;
ns.ImportImageController.prototype.onImageLoaded_ = function (evt) {
var w = this.importedImage_.width,
h = this.importedImage_.height;
@ -115,7 +106,7 @@
gifLoader.load({
success : function(){
var images = gifLoader.getFrames().map(function (frame) {
return pskl.CanvasUtils.createFromImageData(frame.data);
return pskl.utils.CanvasUtils.createFromImageData(frame.data);
});
this.createPiskelFromImages_(images);
this.closeDialog();

View File

@ -1,382 +0,0 @@
(function () {
var ns = $.namespace('pskl.controller.dialogs');
var tinycolor = window.tinycolor;
var SELECTED_CLASSNAME = 'selected';
var NEW_COLOR_CLASS = 'palette-manager-new-color';
var CLOSE_ICON_CLASS = 'palette-manager-delete-card';
var EDIT_NAME_CLASS = 'edit-icon';
ns.PaletteManagerController = function (piskelController) {
this.piskelController = piskelController;
this.palettes = this.retrieveUserPalettes();
this.originalPalettes = this.retrieveUserPalettes();
this.selectedPaletteId = null;
// Keep track of all spectrum instances created, to dispose them when closing the popup
this.spectrumContainers = [];
};
pskl.utils.inherit(ns.PaletteManagerController, ns.AbstractDialogController);
ns.PaletteManagerController.prototype.init = function () {
this.superclass.init.call(this);
this.palettesList = document.querySelector('.palette-manager-list');
this.paletteBody = document.querySelector('.palette-manager-details-body');
this.paletteHead = document.querySelector('.palette-manager-details-head');
this.createButton = document.querySelector('.palette-manager-actions-button[data-action="create"]');
this.saveAllButton = document.querySelector('.palette-manager-actions-button[data-action="save-all"]');
this.colorCardTemplate = pskl.utils.Template.get('palette-color-card-template');
this.newColorTemplate = pskl.utils.Template.get('palette-new-color-template');
this.paletteHeadTemplate = pskl.utils.Template.get('palette-details-head-template');
// Events
this.palettesList.addEventListener('click', this.onPaletteListClick.bind(this));
// Delegated event listener for events repeated on all cards
this.paletteBody.addEventListener('click', this.delegatedPaletteBodyClick.bind(this));
this.paletteHead.addEventListener('click', this.delegatedPaletteHeadClick.bind(this));
this.createButton.addEventListener('click', this.onCreateClick_.bind(this));
this.saveAllButton.addEventListener('click', this.saveAll.bind(this));
// Init markup
this.createPaletteListMarkup();
if (this.palettes.length > 0) {
this.selectPalette(this.palettes[0].id);
} else {
this.createPalette('New palette');
}
};
ns.PaletteManagerController.prototype.destroy = function () {
this.destroySpectrumPickers();
};
ns.PaletteManagerController.prototype.onCreateClick_ = function (evt) {
this.createPalette();
};
ns.PaletteManagerController.prototype.createPalette = function (name) {
if (!name) {
name = window.prompt('Please enter a name for your palette', 'New palette');
}
if (name) {
var palette = this.createPaletteObject(name);
this.palettes.push(palette);
this.createPaletteListMarkup();
this.selectPalette(palette.id);
}
};
ns.PaletteManagerController.prototype.createPaletteObject = function (name) {
return {
id : 'palette-' + Date.now() + '-' + Math.floor(Math.random()*1000),
name : name,
colors : []
};
};
ns.PaletteManagerController.prototype.redraw = function () {
this.createPaletteListMarkup();
this.selectPalette(this.selectedPaletteId);
};
ns.PaletteManagerController.prototype.selectPalette = function (paletteId) {
this.deselectCurrentPalette();
var paletteListItem = this.palettesList.querySelector('[data-palette-id='+paletteId+']');
if (paletteListItem) {
this.selectedPaletteId = paletteId;
paletteListItem.classList.add(SELECTED_CLASSNAME);
this.refreshPaletteDetails();
}
};
ns.PaletteManagerController.prototype.refreshPaletteDetails = function () {
this.createPaletteHeadMarkup();
this.createPaletteBodyMarkup();
this.initPaletteDetailsEvents();
this.initPaletteCardsSpectrum();
};
ns.PaletteManagerController.prototype.createPaletteListMarkup = function () {
var html = this.palettes.map(function (palette) {
var paletteCopy = {
id : palette.id,
name : this.isPaletteModified(palette) ? palette.name + " *" : palette.name
};
return pskl.utils.Template.replace('<li data-palette-id="{{id}}">{{name}}</li>', paletteCopy);
}.bind(this)).join('');
this.palettesList.innerHTML = html;
};
/**
* Fill the palette body container with color cards for the selected palette
*/
ns.PaletteManagerController.prototype.createPaletteHeadMarkup = function () {
var palette = this.getSelectedPalette();
var dict = {
'name' : palette.name,
'save:disabled' : !this.isPaletteModified(palette),
'revert:disabled' : !this.isPaletteModified(palette),
'delete:disabled' : this.palettes.length < 2
};
var html = pskl.utils.Template.replace(this.paletteHeadTemplate, dict);
this.paletteHead.innerHTML = html;
};
ns.PaletteManagerController.prototype.isPaletteModified = function (palette) {
var isModified = false;
var originalPalette = this.getPaletteById(palette.id, this.originalPalettes);
if (originalPalette) {
var differentName = originalPalette.name !== palette.name;
var differentColors = palette.colors.join('') !== originalPalette.colors.join('');
isModified = differentName || differentColors;
} else {
isModified = true;
}
return isModified;
};
/**
* Fill the palette body container with color cards for the selected palette
*/
ns.PaletteManagerController.prototype.createPaletteBodyMarkup = function () {
var palette = this.getSelectedPalette();
var html = this.getColorCardsMarkup(palette.colors);
html += pskl.utils.Template.replace(this.newColorTemplate, {classname : NEW_COLOR_CLASS});
this.paletteBody.innerHTML = html;
};
ns.PaletteManagerController.prototype.initPaletteDetailsEvents = function () {
// New Card click event
var newCard = this.paletteBody.querySelector('.' + NEW_COLOR_CLASS);
newCard.addEventListener('click', this.onNewCardClick.bind(this));
if (this.palettes.length < 2) {
var deleteButton = this.paletteHead.querySelector('.palette-manager-palette-button[data-action="delete"]');
deleteButton.setAttribute("disabled", "disabled");
}
};
ns.PaletteManagerController.prototype.onNewCardClick = function () {
var color;
var palette = this.getSelectedPalette();
if (palette && palette.colors.length > 0) {
color = palette.colors[palette.colors.length-1];
} else {
color = '#FFFFFF';
}
this.addColorInSelectedPalette(color);
};
ns.PaletteManagerController.prototype.delegatedPaletteBodyClick = function (event) {
var target = event.target;
if (target.classList.contains(CLOSE_ICON_CLASS)) {
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
this.removeColorInSelectedPalette(colorId);
}
};
ns.PaletteManagerController.prototype.delegatedPaletteHeadClick = function (event) {
var target = event.target;
if (target.classList.contains(EDIT_NAME_CLASS)) {
this.renameSelectedPalette();
} else if (target.classList.contains('palette-manager-palette-button')) {
var action = target.dataset.action;
if (action === 'save') {
this.savePalette(this.getSelectedPalette().id);
this.redraw();
} else if (action === 'revert') {
this.revertChanges();
} else if (action === 'delete') {
this.deleteSelectedPalette();
}
}
};
ns.PaletteManagerController.prototype.getSpectrumSelector_ = function () {
return ':not(.' + NEW_COLOR_CLASS + ')>.palette-manager-color-square';
};
ns.PaletteManagerController.prototype.initPaletteCardsSpectrum = function () {
var oSelf = this;
var container = $(this.getSpectrumSelector_());
container.spectrum({
clickoutFiresChange : true,
showInput: true,
showButtons: false,
change : function (color) {
var target = this;
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
oSelf.updateColorInSelectedPalette(colorId, color);
},
beforeShow : function() {
var target = this;
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
var palette = oSelf.getSelectedPalette();
var color = palette.colors[colorId];
container.spectrum("set", color);
}
});
this.spectrumContainers.push(container);
};
/**
* Destroy all spectrum instances generated by the palette manager
*/
ns.PaletteManagerController.prototype.destroySpectrumPickers = function () {
this.spectrumContainers.forEach(function (container) {
container.spectrum("destroy");
});
this.spectrumContainers = [];
};
ns.PaletteManagerController.prototype.updateColorInSelectedPalette = function (colorId, color) {
var palette = this.getSelectedPalette();
var hexColor = '#' + (color.toHex().toUpperCase());
palette.colors.splice(colorId, 1, hexColor);
this.redraw();
};
ns.PaletteManagerController.prototype.addColorInSelectedPalette = function (color) {
var selectedPalette = this.getSelectedPalette();
selectedPalette.colors.push(color);
this.redraw();
};
ns.PaletteManagerController.prototype.removeColorInSelectedPalette = function (colorId) {
var palette = this.getSelectedPalette();
palette.colors.splice(colorId, 1);
this.redraw();
};
ns.PaletteManagerController.prototype.renameSelectedPalette = function () {
var palette = this.getSelectedPalette();
var name = window.prompt('Please enter a new name for palette "' + palette.name + '"', palette.name);
if (name) {
palette.name = name;
this.redraw();
}
};
ns.PaletteManagerController.prototype.getSelectedPalette = function () {
return this.getPaletteById(this.selectedPaletteId, this.palettes);
};
ns.PaletteManagerController.prototype.getColorCardsMarkup = function (colors) {
var html = colors.map(function (color, index) {
var dict = {
colorId : index,
hex : color,
rgb : tinycolor(color).toRgbString(),
hsl : tinycolor(color).toHslString()
};
return pskl.utils.Template.replace(this.colorCardTemplate, dict);
}.bind(this)).join('');
return html;
};
ns.PaletteManagerController.prototype.getPaletteById = function (paletteId, palettes) {
var match = null;
palettes.forEach(function (palette) {
if (palette.id === paletteId) {
match = palette;
}
});
return match;
};
ns.PaletteManagerController.prototype.removePaletteById = function (paletteId, palettes) {
var palette = this.getPaletteById(paletteId, palettes);
if (palette) {
var index = palettes.indexOf(palette);
palettes.splice(index, 1);
}
};
ns.PaletteManagerController.prototype.deselectCurrentPalette = function () {
var selectedItem = this.palettesList.querySelector('.' + SELECTED_CLASSNAME);
if (selectedItem) {
this.selectedPaletteId = null;
selectedItem.classList.remove(SELECTED_CLASSNAME);
}
};
ns.PaletteManagerController.prototype.revertChanges = function () {
var palette = this.getSelectedPalette();
var originalPalette = this.getPaletteById(palette.id, this.originalPalettes);
palette.name = originalPalette.name;
palette.colors = originalPalette.colors.slice(0);
this.redraw();
};
ns.PaletteManagerController.prototype.deleteSelectedPalette = function () {
var palette = this.getSelectedPalette();
if (this.palettes.length > 1) {
if (window.confirm('Are you sure you want to delete "' + palette.name + '" ?')) {
this.removePaletteById(palette.id, this.palettes);
this.removePaletteById(palette.id, this.originalPalettes);
this.persistToLocalStorage();
this.createPaletteListMarkup();
this.selectPalette(this.palettes[0].id);
}
}
};
ns.PaletteManagerController.prototype.onPaletteListClick = function (event) {
var target = event.target;
if (target.dataset.paletteId) {
this.selectPalette(target.dataset.paletteId);
}
};
ns.PaletteManagerController.prototype.saveAll = function () {
this.palettes.forEach(function (palette) {
this.savePalette(palette.id);
}.bind(this));
this.redraw();
};
ns.PaletteManagerController.prototype.savePalette = function (paletteId) {
var palette = this.getPaletteById(paletteId, this.palettes);
var originalPalette = this.getPaletteById(paletteId, this.originalPalettes);
if (originalPalette) {
originalPalette.name = palette.name;
originalPalette.colors = palette.colors;
} else {
this.originalPalettes.push(palette);
}
this.persistToLocalStorage();
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Palette " + palette.name + " successfully saved !"}]);
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
};
ns.PaletteManagerController.prototype.persistToLocalStorage = function () {
window.localStorage.setItem('piskel.palettes', JSON.stringify(this.originalPalettes));
this.originalPalettes = this.retrieveUserPalettes();
$.publish(Events.PALETTE_LIST_UPDATED);
};
ns.PaletteManagerController.prototype.retrieveUserPalettes = function () {
var palettesString = window.localStorage.getItem('piskel.palettes');
return JSON.parse(palettesString) || [];
};
})();

View 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;
};
})();

View File

@ -158,7 +158,7 @@
ns.PiskelController.prototype.getFrameCount = function () {
var layer = this.piskel.getLayerAt(0);
return layer.length();
return layer.size();
};
ns.PiskelController.prototype.setCurrentFrameIndex = function (index) {
@ -205,6 +205,18 @@
}
};
ns.PiskelController.prototype.mergeDownLayerAt = function (index) {
var layer = this.getLayerByIndex(index);
var downLayer = this.getLayerByIndex(index-1);
if (layer && downLayer) {
var mergedLayer = pskl.utils.LayerUtils.mergeLayers(layer, downLayer);
this.removeLayerAt(index);
this.piskel.addLayerAt(mergedLayer, index);
this.removeLayerAt(index-1);
this.selectLayer(mergedLayer);
}
};
ns.PiskelController.prototype.generateLayerName_ = function () {
var name = "Layer " + this.layerIdCounter;
while (this.hasLayerForName_(name)) {

View File

@ -99,6 +99,12 @@
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.mergeDownLayerAt = function (index) {
this.raiseSaveStateEvent_(this.piskelController.mergeDownLayerAt, [index]);
this.piskelController.mergeDownLayerAt(index);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.moveLayerUp = function () {
this.raiseSaveStateEvent_(this.piskelController.moveLayerUp, []);
this.piskelController.moveLayerUp();

View File

@ -36,9 +36,6 @@
this.downloadButton = $(".gif-download-button");
this.downloadButton.click(this.onDownloadButtonClick_.bind(this));
this.exportProgressStatusEl = document.querySelector('.gif-export-progress-status');
this.exportProgressBarEl = document.querySelector('.gif-export-progress-bar');
this.createOptionElements_();
};
@ -47,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) {
@ -74,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>";
};
@ -107,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
});
@ -123,29 +134,19 @@
});
}
$.publish(Events.SHOW_PROGRESS, [{"name": 'Building animated GIF ...'}]);
gif.on('progress', function(percentage) {
this.updateProgressStatus_((percentage*100).toFixed(2));
$.publish(Events.UPDATE_PROGRESS, [{"progress": (percentage*100).toFixed(1)}]);
}.bind(this));
gif.on('finished', function(blob) {
this.hideProgressStatus_();
$.publish(Events.HIDE_PROGRESS);
pskl.utils.FileUtils.readFile(blob, cb);
}.bind(this));
gif.render();
};
ns.GifExportController.prototype.updateProgressStatus_ = function (percentage) {
this.exportProgressStatusEl.innerHTML = percentage + '%';
this.exportProgressBarEl.style.width = percentage + "%";
};
ns.GifExportController.prototype.hideProgressStatus_ = function () {
this.exportProgressStatusEl.innerHTML = '';
this.exportProgressBarEl.style.width = "0";
};
// FIXME : HORRIBLE COPY/PASTA
ns.GifExportController.prototype.updateStatus_ = function (imageUrl, error) {

View File

@ -34,7 +34,7 @@
var canvas = this.getFrameAsCanvas_(frame);
var basename = this.pngFilePrefixInput.value;
var filename = basename + (i+1) + ".png";
zip.file(filename, pskl.CanvasUtils.getBase64FromCanvas(canvas) + '\n', {base64: true});
zip.file(filename, pskl.utils.CanvasUtils.getBase64FromCanvas(canvas) + '\n', {base64: true});
}
var fileName = this.getPiskelName_() + '.zip';

View File

@ -47,7 +47,7 @@
var then = function () {};
image.onload = function () {
this.referencePng = pskl.CanvasUtils.createFromImage(image).toDataURL();
this.referencePng = pskl.utils.CanvasUtils.createFromImage(image).toDataURL();
then();
}.bind(this);
image.src = this.referencePng;
@ -101,6 +101,10 @@
var screenCoordinates = pskl.app.drawingController.getScreenCoordinates(recordEvent.coords.x, recordEvent.coords.y);
event.clientX = screenCoordinates.x;
event.clientY = screenCoordinates.y;
if (pskl.utils.UserAgent.isMac && event.ctrlKey) {
event.metaKey = true;
}
if (event.type == 'mousedown') {
pskl.app.drawingController.onMousedown_(event);
} else if (event.type == 'mouseup') {

View File

@ -624,6 +624,7 @@ var SuperGif = function ( opts ) {
};
var load_callback = false;
var step_callback = false;
var error_callback = false;
var tmpCanvas = document.createElement('canvas');
@ -632,6 +633,7 @@ var SuperGif = function ( opts ) {
load: function (callback) {
load_callback = callback.success;
step_callback = callback.step;
error_callback = callback.error;
loading = true;

View File

@ -504,8 +504,10 @@
$(doc).bind("mousedown.spectrum", onMousedown);
// Piskel-specific : change the color as soon as the user does a mouseup
$(doc).bind("mouseup.spectrum", updateColor);
if (!flat) {
// Piskel-specific : change the color as soon as the user does a mouseup
$(doc).bind("mouseup.spectrum", updateColor);
}
$(window).bind("resize.spectrum", resize);
replacer.addClass("sp-active");
@ -667,10 +669,9 @@
}
}
// Update the text entry input as it changes happen
if (opts.showInput) {
textInput.val(realColor.toString(Constants.PREFERRED_COLOR_FORMAT || format));
textInput.val(realColor.toString(format));
}
if (opts.showPalette) {

View File

@ -56,7 +56,7 @@
if (this.frames[index]) {
this.frames.splice(index, 1);
} else {
throw 'Invalid index in removeFrameAt : ' + index + ' (size : ' + this.length() + ')';
throw 'Invalid index in removeFrameAt : ' + index + ' (size : ' + this.size() + ')';
}
};
@ -93,7 +93,7 @@
}
};
ns.Layer.prototype.length = function () {
ns.Layer.prototype.size = function () {
return this.frames.length;
};

46
src/js/model/Palette.js Normal file
View File

@ -0,0 +1,46 @@
(function () {
var ns = $.namespace('pskl.model');
ns.Palette = function (id, name, colors) {
this.id = id;
this.name = name;
this.colors = colors;
};
ns.Palette.fromObject = function (paletteObj) {
var colors = paletteObj.colors.slice(0 , paletteObj.colors.length);
return new ns.Palette(paletteObj.id, paletteObj.name, colors);
};
ns.Palette.prototype.getColors = function () {
return this.colors;
};
ns.Palette.prototype.setColors = function (colors) {
this.colors = colors;
};
ns.Palette.prototype.get = function (index) {
return this.colors[index];
};
ns.Palette.prototype.set = function (index, color) {
this.colors[index] = color;
};
ns.Palette.prototype.add = function (color) {
this.colors.push(color);
};
ns.Palette.prototype.size = function () {
return this.colors.length;
};
ns.Palette.prototype.removeAt = function (index) {
this.colors.splice(index, 1);
};
ns.Palette.prototype.move = function (oldIndex, newIndex) {
this.colors.splice(newIndex, 0, this.colors.splice(oldIndex, 1)[0]);
};
})();

View File

@ -33,7 +33,7 @@
*/
ns.Piskel.fromLayers = function (layers, descriptor) {
var piskel = null;
if (layers.length > 0 && layers[0].length() > 0) {
if (layers.length > 0 && layers[0].size() > 0) {
var sampleFrame = layers[0].getFrameAt(0);
piskel = new pskl.model.Piskel(sampleFrame.getWidth(), sampleFrame.getHeight(), descriptor);
layers.forEach(piskel.addLayer.bind(piskel));
@ -73,6 +73,10 @@
this.layers.push(layer);
};
ns.Piskel.prototype.addLayerAt = function (layer, index) {
this.layers.splice(index, 0, layer);
};
ns.Piskel.prototype.moveLayerUp = function (layer) {
var index = this.layers.indexOf(layer);
if (index > -1 && index < this.layers.length-1) {

View File

@ -25,7 +25,7 @@
var scaledCanvas = this.createCanvas_(this.zoom);
var scaledContext = scaledCanvas.getContext('2d');
pskl.CanvasUtils.disableImageSmoothing(scaledCanvas);
pskl.utils.CanvasUtils.disableImageSmoothing(scaledCanvas);
scaledContext.scale(this.zoom, this.zoom);
scaledContext.drawImage(canvas, 0, 0);
@ -44,6 +44,6 @@
zoom = zoom || 1;
var width = this.frame.getWidth() * zoom;
var height = this.frame.getHeight() * zoom;
return pskl.CanvasUtils.createCanvas(width, height);
return pskl.utils.CanvasUtils.createCanvas(width, height);
};
})();

View File

@ -37,7 +37,7 @@
var count = this.frames.length;
var width = count * sampleFrame.getWidth();
var height = sampleFrame.getHeight();
return pskl.CanvasUtils.createCanvas(width, height);
return pskl.utils.CanvasUtils.createCanvas(width, height);
};
})();

View File

@ -70,8 +70,8 @@
};
ns.FrameRenderer.prototype.clear = function () {
pskl.CanvasUtils.clear(this.canvas);
pskl.CanvasUtils.clear(this.displayCanvas);
pskl.utils.CanvasUtils.clear(this.canvas);
pskl.utils.CanvasUtils.clear(this.displayCanvas);
};
ns.FrameRenderer.prototype.setZoom = function (zoom) {
@ -153,8 +153,8 @@
var height = this.displayHeight;
var width = this.displayWidth;
this.displayCanvas = pskl.CanvasUtils.createCanvas(width, height, this.classes);
pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas);
this.displayCanvas = pskl.utils.CanvasUtils.createCanvas(width, height, this.classes);
pskl.utils.CanvasUtils.disableImageSmoothing(this.displayCanvas);
this.container.append(this.displayCanvas);
};
@ -223,7 +223,7 @@
*/
ns.FrameRenderer.prototype.renderFrame_ = function (frame) {
if (!this.canvas || frame.getWidth() != this.canvas.width || frame.getHeight() != this.canvas.height) {
this.canvas = pskl.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight());
this.canvas = pskl.utils.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight());
}
var context = this.canvas.getContext('2d');

View File

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

View File

@ -5,37 +5,59 @@
this.piskelController = piskelController;
this.currentColors = [];
this.cachedFrameProcessor = new pskl.model.frame.CachedFrameProcessor();
this.cachedFrameProcessor.setFrameProcessor(this.frameToColors_.bind(this));
this.cachedFrameProcessor.setFrameProcessor(this.getFrameColors_.bind(this));
this.framesColorsCache_ = {};
this.colorSorter = new pskl.service.color.ColorSorter();
this.paletteService = pskl.app.paletteService;
};
ns.CurrentColorsService.prototype.init = function () {
$.subscribe(Events.PISKEL_RESET, this.onPiskelUpdated_.bind(this));
$.subscribe(Events.TOOL_RELEASED, this.onPiskelUpdated_.bind(this));
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
};
ns.CurrentColorsService.prototype.getCurrentColors = function () {
return this.currentColors;
};
ns.CurrentColorsService.prototype.frameToColors_ = function (frame) {
var frameColors = {};
frame.forEachPixel(function (color, x, y) {
frameColors[color] = (frameColors[color] || 0) + 1;
});
return frameColors;
ns.CurrentColorsService.prototype.setCurrentColors = function (colors) {
if (colors.join('') !== this.currentColors.join('')) {
this.currentColors = colors;
$.publish(Events.CURRENT_COLORS_UPDATED);
}
};
ns.CurrentColorsService.prototype.onUserSettingsChange_ = function (evt, name, value) {
if (name == pskl.UserSettings.SELECTED_PALETTE) {
if (this.isCurrentColorsPaletteSelected_()) {
this.updateCurrentColors_();
}
}
};
ns.CurrentColorsService.prototype.onPiskelUpdated_ = function (evt) {
if (this.isCurrentColorsPaletteSelected_()) {
this.updateCurrentColors_();
}
};
ns.CurrentColorsService.prototype.isCurrentColorsPaletteSelected_ = function () {
var paletteId = pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE);
var palette = this.paletteService.getPaletteById(paletteId);
return palette.id === Constants.CURRENT_COLORS_PALETTE_ID;
};
ns.CurrentColorsService.prototype.updateCurrentColors_ = function () {
var layers = this.piskelController.getLayers();
var frames = layers.map(function (l) {return l.getFrames();}).reduce(function (p, n) {return p.concat(n);});
var colors = {};
frames.forEach(function (f) {
var frameColors = this.cachedFrameProcessor.get(f);
Object.keys(frameColors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED).forEach(function (color) {
colors[color] = (colors[color] || 0) + frameColors[color];
colors[color] = true;
});
}.bind(this));
@ -43,14 +65,36 @@
delete colors[Constants.TRANSPARENT_COLOR];
// limit the array to the max colors to display
this.currentColors = Object.keys(colors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED);
var colorsArray = Object.keys(colors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED);
var currentColors = this.colorSorter.sort(colorsArray);
// sort by most frequent color
this.currentColors = this.currentColors.sort(function (c1, c2) {
return colors[c2] - colors[c1];
});
this.setCurrentColors(currentColors);
};
// TODO : only fire if there was a change
$.publish(Events.CURRENT_COLORS_UPDATED, colors);
ns.CurrentColorsService.prototype.getFrameColors_ = function (frame) {
var frameColors = {};
frame.forEachPixel(function (color, x, y) {
var hexColor = this.toHexString_(color);
frameColors[hexColor] = true;
}.bind(this));
return frameColors;
};
ns.CurrentColorsService.prototype.toHexString_ = function (color) {
if (color === Constants.TRANSPARENT_COLOR) {
return color;
} else {
color = color.replace(/\s/g, '');
var hexRe = (/^#([a-f0-9]{3}){1,2}$/i);
var rgbRe = (/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/i);
if (hexRe.test(color)) {
return color.toUpperCase();
} else if (rgbRe.test(color)) {
var exec = rgbRe.exec(color);
return pskl.utils.rgbToHex(exec[1] * 1, exec[2] * 1, exec[3] * 1);
} else {
console.error('Could not convert color to hex : ', color);
}
}
};
})();

View File

@ -31,14 +31,27 @@
for (var i = 0; i < files.length ; i++) {
var file = files[i];
var isImage = file.type.indexOf('image') === 0;
var isPiskel = /\.piskel$/i.test(file.name);
var isPalette = /\.(gpl|txt|pal)$/i.test(file.name);
if (isImage) {
this.readImageFile_(file);
} else if (/\.piskel$/i.test(file.name)) {
} else if (isPiskel) {
pskl.utils.PiskelFileUtils.loadFromFile(file, this.onPiskelFileLoaded_);
} else if (isPalette) {
pskl.app.paletteImportService.read(file, this.onPaletteLoaded_.bind(this));
}
}
};
ns.FileDropperService.prototype.readImageFile_ = function (imageFile) {
pskl.utils.FileUtils.readFile(imageFile, this.processImageSource_.bind(this));
};
ns.FileDropperService.prototype.onPaletteLoaded_ = function (palette) {
pskl.app.paletteService.savePalette(palette);
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, palette.id);
};
ns.FileDropperService.prototype.onPiskelFileLoaded_ = function (piskel, descriptor, fps) {
if (window.confirm('This will replace your current animation')) {
piskel.setDescriptor(descriptor);
@ -47,10 +60,6 @@
}
};
ns.FileDropperService.prototype.readImageFile_ = function (imageFile) {
pskl.utils.FileUtils.readFile(imageFile, this.processImageSource_.bind(this));
};
ns.FileDropperService.prototype.processImageSource_ = function (imageSource) {
this.importedImage_ = new Image();
this.importedImage_.onload = this.onImageLoaded_.bind(this);

View File

@ -0,0 +1,105 @@
(function () {
var ns = $.namespace('pskl.service.color');
var LOW_SAT = 0.1;
var LOW_LUM = 0.1;
var HI_LUM = 0.9;
var HUE_STEP = 36;
var HUE_BAGS = 10;
var HUE_BOUNDS = [];
for (var i = 0 ; i < HUE_BAGS ; i++) {
HUE_BOUNDS.push(i * HUE_STEP);
}
ns.ColorSorter = function () {
this.colorsHslMap_ = {};
};
ns.ColorSorter.prototype.sort = function (colors) {
this.colorsHslMap_ = {};
colors.forEach(function (color) {
this.colorsHslMap_[color] = window.tinycolor(color).toHsl();
}.bind(this));
// sort by most frequent color
var darkColors = colors.filter(function (c) {
var hsl = this.colorsHslMap_[c];
return hsl.l <= LOW_LUM;
}.bind(this));
var brightColors = colors.filter(function (c) {
var hsl = this.colorsHslMap_[c];
return hsl.l >= HI_LUM;
}.bind(this));
var desaturatedColors = colors.filter(function (c) {
return brightColors.indexOf(c) === -1 && darkColors.indexOf(c) === -1;
}).filter(function (c) {
var hsl = this.colorsHslMap_[c];
return hsl.s <= LOW_SAT;
}.bind(this));
darkColors = this.sortOnHslProperty_(darkColors, 'l');
brightColors = this.sortOnHslProperty_(brightColors, 'l');
desaturatedColors = this.sortOnHslProperty_(desaturatedColors, 'h');
var sortedColors = darkColors.concat(brightColors, desaturatedColors);
var regularColors = colors.filter(function (c) {
return sortedColors.indexOf(c) === -1;
});
var regularColorsBags = HUE_BOUNDS.map(function (hue) {
var bagColors = regularColors.filter(function (color) {
var hsl = this.colorsHslMap_[color];
return (hsl.h >= hue && hsl.h < hue + HUE_STEP);
}.bind(this));
return this.sortRegularColors_(bagColors);
}.bind(this));
return Array.prototype.concat.apply(sortedColors, regularColorsBags);
};
ns.ColorSorter.prototype.sortRegularColors_ = function (colors) {
var sortedColors = colors.sort(function (c1, c2) {
var hsl1 = this.colorsHslMap_[c1];
var hsl2 = this.colorsHslMap_[c2];
var hDiff = Math.abs(hsl1.h - hsl2.h);
var sDiff = Math.abs(hsl1.s - hsl2.s);
var lDiff = Math.abs(hsl1.l - hsl2.l);
if (hDiff < 10) {
if (sDiff > lDiff) {
return this.compareValues_(hsl1.s, hsl2.s);
} else {
return this.compareValues_(hsl1.l, hsl2.l);
}
} else {
return this.compareValues_(hsl1.h, hsl2.h);
}
}.bind(this));
return sortedColors;
};
ns.ColorSorter.prototype.sortOnHslProperty_ = function (colors, property) {
return colors.sort(function (c1, c2) {
var hsl1 = this.colorsHslMap_[c1];
var hsl2 = this.colorsHslMap_[c2];
return this.compareValues_(hsl1[property], hsl2[property]);
}.bind(this));
};
ns.ColorSorter.prototype.compareValues_ = function (v1, v2) {
if (v1 > v2) {
return 1;
} else if (v1 < v2) {
return -1;
}
return 0;
};
})();

View File

@ -11,12 +11,12 @@
throw 'cheatsheetEl_ DOM element could not be retrieved';
}
this.initMarkup_();
pskl.app.shortcutService.addShortcut('shift+?', this.toggleCheatsheet_.bind(this));
pskl.app.shortcutService.addShortcut('?', this.toggleCheatsheet_.bind(this));
pskl.app.shortcutService.addShortcuts(['?', 'shift+?'], this.toggleCheatsheet_.bind(this));
var link = $('.cheatsheet-link');
link.click(this.toggleCheatsheet_.bind(this));
$.subscribe(Events.TOGGLE_HELP, this.toggleCheatsheet_.bind(this));
$.subscribe(Events.ESCAPE, this.onEscape_.bind(this));
};
@ -106,7 +106,8 @@
this.toDescriptor_('N', 'Create new frame'),
this.toDescriptor_('shift + N', 'Duplicate selected frame'),
this.toDescriptor_('shift + ?', 'Open/Close this popup'),
this.toDescriptor_('alt + P', 'Open the Palette Manager'),
this.toDescriptor_('alt + P', 'Create a Palette'),
this.toDescriptor_('&lt;/&gt;', 'Select previous/next palette color'),
this.toDescriptor_('alt + O', 'Toggle Onion Skin'),
this.toDescriptor_('alt + L', 'Toggle Layer Preview')
];

View File

@ -7,7 +7,9 @@
40 : "down",
46 : "del",
189 : "-",
187 : "+"
187 : "+",
188 : "<",
190 : ">"
};
var ns = $.namespace('pskl.service.keyboard');

View File

@ -35,6 +35,12 @@
}
};
ns.ShortcutService.prototype.addShortcuts = function (keys, callback) {
keys.forEach(function (key) {
this.addShortcut(key, callback);
}.bind(this));
};
ns.ShortcutService.prototype.removeShortcut = function (rawKey) {
var parsedKey = this.parseKey_(rawKey.toLowerCase());

View File

@ -0,0 +1,12 @@
(function () {
var ns = $.namespace('pskl.service.palette');
ns.CurrentColorsPalette = function () {
this.name = 'Current colors';
this.id = Constants.CURRENT_COLORS_PALETTE_ID;
};
ns.CurrentColorsPalette.prototype.getColors = function () {
return pskl.app.currentColorsService.getCurrentColors();
};
})();

View File

@ -0,0 +1,40 @@
(function () {
var ns = $.namespace('pskl.service.palette');
ns.PaletteGplWriter = function (palette) {
this.palette = palette;
};
ns.PaletteGplWriter.prototype.write = function () {
var lines = [];
lines.push('GIMP Palette');
lines.push('Name: ' + this.palette.name);
lines.push('Columns: 0');
lines.push('#');
this.palette.getColors().forEach(function (color) {
lines.push(this.writeColorLine(color));
}.bind(this));
lines.push('\r\n');
return lines.join('\r\n');
};
ns.PaletteGplWriter.prototype.writeColorLine = function (color) {
var tinycolor = window.tinycolor(color);
var rgb = tinycolor.toRgb();
var strBuffer = [];
strBuffer.push(this.padString(rgb.r, 3));
strBuffer.push(this.padString(rgb.g, 3));
strBuffer.push(this.padString(rgb.b, 3));
strBuffer.push('Untitled');
return strBuffer.join(' ');
};
ns.PaletteGplWriter.prototype.padString = function (str, size) {
str = str.toString();
var pad = (new Array(1+size-str.length)).join(' ');
return pad + str;
};
})();

View File

@ -0,0 +1,51 @@
(function () {
var ns = $.namespace('pskl.service.palette');
var fileReaders = {
'gpl' : ns.reader.PaletteGplReader,
'pal' : ns.reader.PalettePalReader,
'txt' : ns.reader.PaletteTxtReader,
'img' : ns.reader.PaletteImageReader
};
ns.PaletteImportService = function () {};
ns.PaletteImportService.prototype.read = function (file, onSuccess, onError) {
var reader = this.getReader_(file, onSuccess, onError);
if (reader) {
reader.read();
} else {
throw 'Could not find reader for file : ' + file.name;
}
};
ns.PaletteImportService.prototype.isImage_ = function (file) {
return file.type.indexOf('image') === 0;
};
ns.PaletteImportService.prototype.getReader_ = function (file, onSuccess, onError) {
var readerClass = this.getReaderClass_(file);
if (readerClass) {
return new readerClass(file, onSuccess, onError);
} else {
return null;
}
};
ns.PaletteImportService.prototype.getReaderClass_ = function (file) {
var readerClass;
if (this.isImage_(file)) {
readerClass = fileReaders.img;
} else {
var extension = this.getExtension_(file);
readerClass = fileReaders[extension];
}
return readerClass;
};
ns.PaletteImportService.prototype.getExtension_ = function (file) {
var parts = file.name.split('.');
var extension = parts[parts.length-1];
return extension.toLowerCase();
};
})();

View File

@ -0,0 +1,72 @@
(function () {
var ns = $.namespace('pskl.service.palette');
ns.PaletteService = function () {
this.dynamicPalettes = [];
this.localStorageService = window.localStorage;
};
ns.PaletteService.prototype.getPalettes = function () {
var palettesString = this.localStorageService.getItem('piskel.palettes');
var palettes = JSON.parse(palettesString) || [];
palettes = palettes.map(function (palette) {
return pskl.model.Palette.fromObject(palette);
});
return this.dynamicPalettes.concat(palettes);
};
ns.PaletteService.prototype.getPaletteById = function (paletteId) {
var palettes = this.getPalettes();
return this.findPaletteInArray_(paletteId, palettes);
};
ns.PaletteService.prototype.savePalette = function (palette) {
var palettes = this.getPalettes();
var existingPalette = this.findPaletteInArray_(palette.id, palettes);
if (existingPalette) {
var currentIndex = palettes.indexOf(existingPalette);
palettes.splice(currentIndex, 1, palette);
} else {
palettes.push(palette);
}
this.savePalettes_(palettes);
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Palette " + palette.name + " successfully saved !"}]);
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
};
ns.PaletteService.prototype.addDynamicPalette = function (palette) {
this.dynamicPalettes.push(palette);
};
ns.PaletteService.prototype.deletePaletteById = function (id) {
var palettes = this.getPalettes();
var filteredPalettes = palettes.filter(function (palette) {
return palette.id !== id;
});
this.savePalettes_(filteredPalettes);
};
ns.PaletteService.prototype.savePalettes_ = function (palettes) {
palettes = palettes.filter(function (palette) {
return this.dynamicPalettes.indexOf(palette) === -1;
}.bind(this));
this.localStorageService.setItem('piskel.palettes', JSON.stringify(palettes));
$.publish(Events.PALETTE_LIST_UPDATED);
};
ns.PaletteService.prototype.findPaletteInArray_ = function (paletteId, palettes) {
var match = null;
palettes.forEach(function (palette) {
if (palette.id === paletteId) {
match = palette;
}
});
return match;
};
})();

View 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();
}
};
})();

View 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();
};
})();

View File

@ -0,0 +1,54 @@
(function () {
var ns = $.namespace('pskl.service.palette.reader');
ns.PaletteImageReader = function (file, onSuccess, onError) {
this.file = file;
this.onSuccess = onSuccess;
this.onError = onError;
this.colorSorter_ = new pskl.service.color.ColorSorter();
};
ns.PaletteImageReader.prototype.read = function () {
pskl.utils.FileUtils.readImageFile(this.file, this.onImageLoaded_.bind(this));
};
ns.PaletteImageReader.prototype.onImageLoaded_ = function (image) {
var imageProcessor = new pskl.worker.ImageProcessor(image,
this.onWorkerSuccess_.bind(this),
this.onWorkerStep_.bind(this),
this.onWorkerError_.bind(this));
$.publish(Events.SHOW_PROGRESS, [{"name": 'Processing image colors ...'}]);
imageProcessor.process();
};
ns.PaletteImageReader.prototype.onWorkerSuccess_ = function (event) {
var data = event.data;
var colorsMap = data.colorsMap;
var colors = Object.keys(colorsMap);
if (colors.length > 200) {
this.onError('Too many colors : ' + colors.length);
} else {
var uuid = pskl.utils.Uuid.generate();
var sortedColors = this.colorSorter_.sort(colors);
var palette = new pskl.model.Palette(uuid, this.file.name + ' palette', sortedColors);
this.onSuccess(palette);
}
$.publish(Events.HIDE_PROGRESS);
};
ns.PaletteImageReader.prototype.onWorkerStep_ = function (event) {
var progress = event.data.progress;
$.publish(Events.UPDATE_PROGRESS, [{"progress": progress}]);
};
ns.PaletteImageReader.prototype.onWorkerError_ = function (event) {
$.publish(Events.HIDE_PROGRESS);
this.onError('Unable to process the image : ' + event.data.message);
};
})();

View 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;
};
})();

View 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;
};
})();

View 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
View 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;
};
})();

View File

@ -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) {};
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
(function() {
var ns = $.namespace("pskl.drawingtools");
var ns = $.namespace("pskl.tools.drawing");
ns.VerticalMirrorPen = function() {
this.superclass.constructor.call(this);

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More