505 Commits

Author SHA1 Message Date
Julian Descottes
21b8bdd0f3 [chore] update version number to 15 2 snapshot 2021-07-02 15:12:00 +02:00
Julian Descottes
881d2f1100 Fix linting errors 2021-07-02 15:09:39 +02:00
Julian Descottes
117d094df9 [chore] Update all dependencies 2021-07-02 15:09:39 +02:00
Julian Descottes
ae8b2ade39 release 0.15.1 2021-07-02 15:09:39 +02:00
Julian Descottes
6943dc3ebe Fix deserialization of fps-less sprites 2021-07-02 15:09:39 +02:00
Dominik K
cb41a72b5b Fix #894: Replaced help text for flip &rotated tool-flip icon (#899)
* Fix #894: Replaced help text for flip &rotated tool-flip icon

* Undo changes to icons.
2020-02-03 06:44:38 +01:00
Todor Imreorov
17b1712b82 use grunt play instead of grunt serve 2020-02-02 12:17:44 +01:00
blurymind
24b28504a1 add npm run formt command 2020-02-02 12:17:44 +01:00
blurymind
3e926ff093 update start command 2020-02-02 12:17:44 +01:00
blurymind
b9d4c5c2a6 add build and serve commands 2020-02-02 12:17:44 +01:00
blurymind
c13acba6b1 update outdated/broken node-webkit start script 2020-02-02 12:17:44 +01:00
blurymind
cf92045489 add grunt-cli to devDependencies 2020-02-02 12:17:44 +01:00
juliandescottes
025c34d07c release: bump version to 0.16-SNAPSHOT 2018-11-25 18:10:55 +01:00
juliandescottes
eb14e489a7 Add some release documentation 2018-11-25 18:10:55 +01:00
juliandescottes
ef945ef8a6 bump version de 0.15 2018-11-25 18:10:55 +01:00
Julian Descottes
c5c8184ae3 Fix size picker display for pen size > 4 2018-11-24 21:03:09 +01:00
Julian Descottes
66452de1e5 Fix hidden frames bug when adding or removing frames 2018-11-24 20:48:47 +01:00
Jordan Watkins
fa62ae511e Fix to avoid double extension when using the dest argument 2018-10-25 18:30:44 +02:00
Jordan Watkins
f106909150 Replace backticks with single quotes 2018-10-25 18:30:44 +02:00
Jordan Watkins
b54efbde21 Add piskel-cli for exporting from .piskel files via command line 2018-10-25 18:30:44 +02:00
Jordan Watkins
5ebf83badf Add inline image option for PixiJS Movie export 2018-10-18 09:03:55 +02:00
Alex
3804afbeb5 Enabled inline editing of layer names 2018-10-18 08:14:23 +02:00
Julian Descottes
0a64d62b84 Add comments for hiddenFrames feature 2018-10-07 14:19:01 +02:00
Julian Descottes
af9095b934 Move hidden frames info to Piskel model 2018-10-07 14:19:01 +02:00
janczer
65f4fd0f27 Refactoring. Create function to get current frame 2018-10-05 23:41:55 +02:00
janczer
5e364e984c Add to frame size information about number of current frame and how much frames exists 2018-10-05 23:41:55 +02:00
janczer
5a0b6b90e4 Fit typos 2018-09-25 08:35:46 +02:00
juliandescottes
717e8dd52a Add keyboard shortcut to toggle grid (alt+G) 2018-09-19 23:24:52 +02:00
juliandescottes
bd0478fb35 Extract PreviewActionsController from PreviewController 2018-09-19 23:24:52 +02:00
juliandescottes
2bbbfd1219 Add integration test for grid icon in animated preview 2018-09-19 23:24:52 +02:00
juliandescottes
da4156912e Remove migration script for 0.12 to 0.13 2018-09-19 23:24:52 +02:00
juliandescottes
99c060f4a7 Cleanup local storage before integration tests 2018-09-19 23:24:52 +02:00
juliandescottes
52e49a1ed6 Add toggle grid icon to minimap 2018-09-19 23:24:52 +02:00
Grzegorz
6acfa2256c Fix in serialization 2018-09-17 22:19:14 +02:00
Grzegorz
89629d2939 Implemented with history management. 2018-09-17 22:19:14 +02:00
Grzegorz
e5d89104a1 Added frame toggling for preview 2018-09-17 22:19:14 +02:00
Zakar Handricken
6e84f0a2b5 Set color of Alpha icon based on opacity value. 2018-09-17 22:17:19 +02:00
Zakar Handricken
ba0e86dc7e Place opacity value in layer item title. 2018-09-17 22:17:19 +02:00
juliandescottes
27497313ff Issue #803 - Add integration test for single png export 2018-09-09 08:47:00 +02:00
juliandescottes
8662ab65ad Issue #803 - Reuse downloadCanvas_ to download single frame canvas 2018-09-09 08:47:00 +02:00
juliandescottes
594d748146 Issue #803 - Move single frame export to PNG tab and support scale 2018-09-09 08:47:00 +02:00
Joanne Hong
379c61a11d Fix grid bleeding through from other layers by only enabling support for
grid rendering for current layer.
2018-08-26 10:34:25 +02:00
Maxwell Paul Brickner
230a38bf07 Updated urls to use https
Updated urls to use https instead of http when possible to avoid redirects.
2018-05-23 07:12:10 +09:00
Julian Descottes
0e5d74e1d8 Issue #772 - flash colorpicker cursor when using middle click or alt+click 2018-04-08 17:59:01 +02:00
Julian Descottes
f462cd3b70 Remove jquery from app.js 2018-04-08 17:39:15 +02:00
Julian Descottes
45d2245346 Remove jquery from BrowseLocalController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
e5e85f67c2 Remove jquery from ColorsList.js 2018-04-08 17:39:15 +02:00
Julian Descottes
4836251bd3 Remove deprecated comment in FramesListController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
e3182504dd Remove jquery from FramesListController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
34a88b79a0 Remove jquery from MinimapController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
7b8978da7a Remove jquery from LayersListController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
1c3b359b5c Remove unused constant from LayersListController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
5c4cbbbba1 Remove jquery from NotificationController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
b9cc2eb4f8 Remove jquery from PaletteController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
ac13cf13c1 Remove jquery from PalettesListController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
32600f9e66 Remove jquery from LayersRenderer.js 2018-04-08 17:39:15 +02:00
Julian Descottes
39eb0d3143 Remove jquery from ProgressBarController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
6e53bce2cf Remove jquery from SelectionManager.js 2018-04-08 17:39:15 +02:00
Julian Descottes
090acee11a Remove jquery from PreviewController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
a1bb5f3b97 Remove jquery from DrawingController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
f69e502639 Remove jquery from FrameRenderer.js 2018-04-08 17:39:15 +02:00
Julian Descottes
027cd2e2a6 Remove jquery from BackgroundImageFrameRenderer.js 2018-04-08 17:39:15 +02:00
Julian Descottes
2726af2d81 Remove jquery from ShortcutService.js 2018-04-08 17:39:15 +02:00
Julian Descottes
22cec2e8c7 Remove jquery from BaseSelect.js 2018-04-08 17:39:15 +02:00
Julian Descottes
57ee8e4365 Remove jquery from FrameRenderer.js 2018-04-08 17:39:15 +02:00
Julian Descottes
a9cdf98281 Remove jquery from ToolController.js 2018-04-08 17:39:15 +02:00
Julian Descottes
0a9e7dcffb Update the no-colors message for palettes to be more readable 2018-04-08 17:03:07 +02:00
Julian Descottes
fe3f6996f1 release: update version to 0.15.0-SNAPSHOT 2018-03-11 23:48:06 +01:00
Julian Descottes
9d32a8c3aa release: bump to version 0.14.0 2018-03-04 13:04:20 +01:00
Alex
64cd724139 reverted checkbox class and added method to controller 2018-03-03 16:45:27 +01:00
Alex
dae08107e2 Added new checkbox to zip export html template and use layer name as prefix to file names (in ZipExportController) if checkbox is selected. 2018-03-03 16:45:27 +01:00
juliandescottes
779761628e Grid spacing: css nits, remove unused variable, string case fix 2018-02-18 13:29:37 +01:00
Craig Gilchrist
3e450c3d77 Changes requested in PR 2018-02-18 13:11:08 +01:00
Craig Gilchrist
5c7070b01b Add a Grid Spacing option to the GridSettings
Fixes #774
2018-02-18 13:11:08 +01:00
Guillaume Martigny
7c215ebcbe Remove use of grunt-open in favor of the option in grunt-contrib-connect 2018-02-07 18:52:03 +01:00
Carl Smith
bcee24609f Changed cursor coordinates color from gold to --highlight-color. 2017-11-16 21:20:49 +01:00
Carl Smith
f420c6f1fd Made cursor coordinates gold (and whitespace more consistent). 2017-11-16 21:20:49 +01:00
Alex K
76429dfd86 noloop gif should be -1
repeat	0	repeat count, -1 = no repeat, 0 = forever
https://github.com/jnordberg/gif.js
2017-11-10 10:13:08 +01:00
Jordan Watkins
4ebf43fda4 Display drawing zoom 2017-10-23 11:39:38 +02:00
juliandescottes
2f2b4cd9ba release: bump to version 0.13.0 2017-10-22 16:40:09 +02:00
juliandescottes
dfb049bbf0 release: bump version to 0.13.0-RC2 2017-10-22 16:40:09 +02:00
juliandescottes
8c54108a9b Remove html autocomplete fromt size input fields 2017-10-22 16:40:09 +02:00
juliandescottes
3dd72f9781 release: fix minor ui issues for checkbox containers 2017-10-22 16:40:09 +02:00
juliandescottes
80001eab0e release: bump version to 0.13.0-RC1 2017-10-22 16:40:09 +02:00
Julian Descottes
5ecf351e0f Return promise results from PiskelDB and IndexedDBStorageService 2017-10-21 23:48:51 +02:00
Julian Descottes
407b432227 Show error message if BackupDatabase promise rejected 2017-10-21 23:48:51 +02:00
Julian Descottes
69cc27557e Add templates for backup database errors 2017-10-21 23:48:51 +02:00
juliandescottes
cfd3773a2b Issue #751 - add repeat checkbox to GIF export panel 2017-10-08 19:46:43 +02:00
juliandescottes
0eface45f1 Issue #750 - drawing tests: always initialize penSize before starting test 2017-10-08 19:12:04 +02:00
juliandescottes
87893bb4ac Issue #750 - Fix mirror pen with even pensizes 2017-10-08 19:12:04 +02:00
juliandescottes
77d26bffa9 Issue #727 - add integration test for simple import flow 2017-10-08 18:19:52 +02:00
juliandescottes
652027bd3f Issue #727 - update integration tests to wait for color service update 2017-10-08 18:19:52 +02:00
Julian Descottes
bf4cc3302a Issue #727 - skip import steps if current piskel is empty 2017-10-08 18:19:52 +02:00
juliandescottes
95c8df1224 Issue #727 - simplify import: resize and insertion steps 2017-10-08 18:19:52 +02:00
juliandescottes
7445357368 Issue #727 - simplify import mode text 2017-10-08 18:19:52 +02:00
juliandescottes
a2369cac0c Issue #727 - remove border around meta info in import wizard 2017-10-08 18:19:52 +02:00
Julian Descottes
51538dff48 Make piskel performance warning less scary 2017-09-24 18:06:37 +02:00
Julian Descottes
da739e78da Issue #743 - bump color palette cap to 256 2017-09-24 17:39:03 +02:00
Julian Descottes
dd8217e21b Issue #744 - show notification when exporting to GIF can not preserve colors 2017-09-24 17:37:49 +02:00
Julian Descottes
d502d3416b Issue #745 - Add https support 2017-09-24 17:37:14 +02:00
juliandescottes
d1156954ca Issue #729 - implement custom PNG export viewer instead of opening window to data-uri 2017-09-24 17:36:02 +02:00
juliandescottes
dc5209628c fix selectionmanager unit test 2017-09-06 23:05:17 +02:00
juliandescottes
8568663949 Move clipboard events to dedicated service and fix tests 2017-09-06 23:05:17 +02:00
juliandescottes
fd3d828067 remove unused selection copy cut paste events 2017-09-06 23:05:17 +02:00
juliandescottes
e1797b2008 Fix SelectionManagerTest by using a clipboard event mock 2017-09-06 23:05:17 +02:00
juliandescottes
0a43f6bbec Fix copy to website script to work if main-partial is missing. 2017-09-06 23:05:17 +02:00
juliandescottes
b9423bc831 Issue #645: Support clipboard to paste images 2017-09-06 23:05:17 +02:00
juliandescottes
5e6280301d Issue #736 - cleanup selection tool state on SELECTION_DISMISSED event 2017-09-06 00:39:35 +02:00
juliandescottes
5671eb4782 Delete all extra backup sessions if MAX is reached 2017-08-06 22:56:43 +02:00
juliandescottes
35788b54ba update travis yml to upgrade node and stop downloading casper 2017-08-03 00:44:53 +02:00
juliandescottes
629ecf83b4 add comments for values synced between JS and CSS 2017-08-03 00:21:08 +02:00
juliandescottes
c037b07693 rename mergeData to backupsData in browse backups wizard 2017-08-03 00:21:08 +02:00
juliandescottes
c31b7a351c update piskel mock in BackupServiceTest 2017-08-03 00:21:08 +02:00
juliandescottes
7de03f1e73 show snpashot previews in the browse backups dialog 2017-08-03 00:21:08 +02:00
juliandescottes
eab21e0839 Show confirmation message when loading snapshot backup 2017-08-03 00:21:08 +02:00
juliandescottes
2b3bd02479 improve styling of snapshot list in browse backups dialog 2017-08-03 00:21:08 +02:00
juliandescottes
4e86fa1570 dev-environment: add ctrl+alt+R shortcut to reload styles 2017-08-03 00:21:08 +02:00
juliandescottes
170a7e4731 skip backups for current session in browse backups dialog 2017-08-03 00:21:08 +02:00
juliandescottes
6b7f04b63e browse backups dialog: add styling for empty session list 2017-08-03 00:21:08 +02:00
juliandescottes
da2e9f99e4 cleanup: remove title on backup session element 2017-08-03 00:21:08 +02:00
juliandescottes
530a949e54 add icon for backup dialog 2017-08-03 00:21:08 +02:00
Julian Descottes
4377c9e601 add disclaimer in the browse backups dialog 2017-08-03 00:21:08 +02:00
Julian Descottes
e0bbb88d47 confirm backup session delete, add animation 2017-08-03 00:21:08 +02:00
Julian Descottes
9ff2ecbb45 improve styling for browse-backups dialog 2017-08-03 00:21:08 +02:00
juliandescottes
8beba2088b remove useless console.log 2017-08-03 00:21:08 +02:00
juliandescottes
ee45cdcc45 add a browse backups dialog 2017-08-03 00:21:08 +02:00
juliandescottes
30ea7fa079 fix migration script for localstorage to indexeddb 2017-08-03 00:21:08 +02:00
Julian Descottes
e9b39a5c61 add unit test for PiskelDatabase 2017-08-03 00:21:08 +02:00
Julian Descottes
d0a32b18c5 add unit test for backup database 2017-08-03 00:21:08 +02:00
Julian Descottes
372ad1f513 add unit test for BackupService 2017-08-03 00:21:08 +02:00
Julian Descottes
c6e106fe2d add a limit to the number of sessions backed up 2017-08-03 00:21:08 +02:00
Julian Descottes
f9570ea3c5 Issue #640 - extract database code to dedicated package 2017-08-03 00:21:08 +02:00
Julian Descottes
f9cb631acb Issue #640 - migrate backup service to indexeddb 2017-08-03 00:21:08 +02:00
Julian Descottes
ed749a747f Issue #640 - migrate local browser save to indexeddb 2017-08-03 00:21:08 +02:00
Julian Descottes
30ecd41452 Issue #640 - remove duplicated entries in piskel-script-list 2017-08-03 00:21:08 +02:00
Julian Descottes
af65344c23 Issue #640 - rename PaletteService pointer to localStorage to localStorageGlobal
PaletteService exposes window.localStorage as this.localStorageService. This is confusing since we also have the LocalStorageService class used to save piskels in local storage.
2017-08-03 00:21:08 +02:00
juliandescottes
183133496e Fix #718 - when dropping image, only use import wizard for big images 2017-08-01 01:06:09 +02:00
Julian Descottes
8a2c0191f9 release: bump version to 0.12.1 2017-07-18 08:06:54 +02:00
Julian Descottes
a096dcabfd Fix #717: filter invalid colors 2017-07-18 08:05:48 +02:00
Julian Descottes
96d326ef12 release: bump version to 0.13.0-SNAPSHOT 2017-06-23 21:01:47 +02:00
Julian Descottes
7c37372b13 release: bump version to v0.12.0 2017-06-23 21:01:47 +02:00
Julian Descottes
b21ea30fa8 Issue #658 - Support shift+UP/RIGHT/DOWN/LEFT to move the viewport 2017-06-10 23:12:11 +02:00
Julian Descottes
c2dbddcf9f Issue #636 - rename all application-settings things to preferences-settings
The name is not ideal, but it's better to have a MiscPreferencesController than a MainApplicationController for this kind of very simple panels.
2017-06-10 11:20:23 +02:00
Julian Descottes
09ce6ff88f Issue #636 - remove unused code 2017-06-10 11:20:23 +02:00
Julian Descottes
2c4a8efb44 Issue #636 - add integration test for main settings panel 2017-06-10 11:20:23 +02:00
Julian Descottes
02a25d3f84 Fix eslint violations 2017-06-10 11:20:23 +02:00
Julian Descottes
d159de2e65 Update gitignore for vscode 2017-06-10 11:20:23 +02:00
Julian Descottes
726a8f74c1 Switch from jscs+jshint to eslint 2017-06-10 11:20:23 +02:00
Julian Descottes
89a65ab032 add test-export-gif-scale test to integration test suite 2017-06-10 11:20:23 +02:00
Julian Descottes
d8ec58b42c Remove reference to seamless in tooltip 2017-06-10 11:20:23 +02:00
Julian Descottes
1168870ee0 Issue #636 - Allow users to change the grid color 2017-06-10 11:20:23 +02:00
Julian Descottes
d3a37c74e9 Issue #636 - rename seamless* to tile* 2017-06-10 11:20:23 +02:00
Julian Descottes
5d2ca7e70c Issue #636 - create sizepicker widget and use it in grid settings 2017-06-10 11:20:23 +02:00
Julian Descottes
2976fd09ea Issue #636 - create Tabs widget and use it application settings panel 2017-06-10 11:20:23 +02:00
Julian Descottes
317fda83c3 add integration test for tiny-palettes 2017-06-04 22:29:54 +02:00
Julian Descottes
94160d8fc4 Transform palette color title to uppercase 2017-06-04 22:29:54 +02:00
Julian Descottes
b977a146e9 Issue #663 - display 10 colors per row in palette for palettes with > 10 colors 2017-06-04 22:29:54 +02:00
Julian Descottes
aea4e4d6a6 Fix #704 - increase height of offline apps window to 700px 2017-06-03 10:23:40 +02:00
Julian Descottes
5456ea973a Fix #690 - remove references to github/juliandescottes in README 2017-06-03 09:38:23 +02:00
Julian Descottes
a299d9aed0 Fix #697 - update confirmation message when closing Piskel with unsaved changes 2017-06-03 00:49:52 +02:00
Julian Descottes
cc2fc48107 Fix #271: add new piskel button for desktop application 2017-06-03 00:15:08 +02:00
Julian Descottes
799c9fbf5a Feature #541 crop based on the current selection 2017-06-01 19:46:34 +02:00
Julian Descottes
a9e22535d6 feature #541: add crop transform tool 2017-06-01 19:46:34 +02:00
Julian Descottes
4b4cbe47c8 support expanding the transform toolbox 2017-06-01 19:46:34 +02:00
Julian Descottes
e7d07c5353 Fix #699 - add SPACE to keycode translator 2017-05-27 09:05:05 +02:00
Julian Descottes
cf3383722a check meta key when recording drawing test (OSX) 2017-05-20 20:03:42 +02:00
Julian Descottes
6566ca07a5 add new layer just before the current layer 2017-05-20 20:03:42 +02:00
Julian Descottes
9fafa8b7a7 use SHIFT meta when clicking up down layer to move to top/bottom 2017-05-20 20:03:42 +02:00
Julian Descottes
4a9f7cc74b add grunt task to run drawing tests 2017-05-20 20:03:42 +02:00
Julian Descottes
319060beb6 add drawing test for move layer top/bottom 2017-05-20 20:03:42 +02:00
ItsPugle
729c9f4732 Updating README.md to resolve license dating
Changed 2016 to 2017 to resolve any license dating issues.
2017-05-20 19:53:55 +02:00
Smie
cd560012e1 Adds comments to Stroke tool for drawing lines. 2017-05-17 23:57:30 +02:00
Smie
e819503cc5 Adjusts lineTool ends to square shape. 2017-05-17 23:57:30 +02:00
Smie
6512c3dcc0 Improves performance of line tool for large pen sizes. 2017-05-17 23:57:30 +02:00
juliandescottes
3535dfb25e replace references to github.com/juliandescottes for github.com/piskelapp 2017-05-14 19:18:19 +02:00
juliandescottes
a69554f6c9 release: bump version to 0.12.0-SNAPSHOT 2017-05-14 19:16:58 +02:00
juliandescottes
1040cb4d8c release: bump version to 0.11.1 2017-05-14 19:04:33 +02:00
juliandescottes
d18b85df16 Fix template bug for IE11 2017-05-14 18:55:51 +02:00
juliandescottes
76563bfc41 release: bump version to v0.12.0-SNAPSHOT 2017-05-14 17:43:35 +02:00
juliandescottes
2ba95667b2 release: bump version to v0.11.0 2017-05-14 17:39:33 +02:00
juliandescottes
3949051ba7 release: add release script to run grunt+copy to piskel-website 2017-05-14 17:39:33 +02:00
juliandescottes
df6780a3e7 store version in window.pskl and display it in settings 2017-05-14 17:39:33 +02:00
juliandescottes
b768a22b1c Fix #689 - add unit test for v1 deserializer 2017-05-14 17:39:33 +02:00
juliandescottes
8f4f9d9b0a Fix #689 - add unit test for v0 deserializer 2017-05-14 17:39:33 +02:00
juliandescottes
14e969a3bb Fix typos and errors in existing DeserializationTest 2017-05-14 17:39:33 +02:00
juliandescottes
0ef69bae58 Fix #689 - Constants.DEFAULTS->DEFAULT in deserializers v0/v1 2017-05-14 17:39:33 +02:00
juliandescottes
b40c1c4744 reduce button size 2017-05-13 01:36:04 +02:00
juliandescottes
261259b38f remove unused styles from dialogs-import.css 2017-05-13 01:36:04 +02:00
juliandescottes
799bf76a86 update integration tests after selectMode step changes 2017-05-13 01:36:04 +02:00
juliandescottes
42f329980c remove cancel button from import steps, add big select mode buttons 2017-05-13 01:36:04 +02:00
juliandescottes
80a1edf027 add unit test for piskel MergeUtils 2017-05-13 01:36:04 +02:00
juliandescottes
92934502e8 fix merge of smaller piskel into bigger piskel 2017-05-13 01:36:04 +02:00
juliandescottes
4d07a4eb90 select the first imported layer after a merge 2017-05-13 01:36:04 +02:00
juliandescottes
41ef0cd460 increase casper load timeout 2017-05-13 01:36:04 +02:00
juliandescottes
d77889d265 add integration test chaining two import flows 2017-05-13 01:36:04 +02:00
juliandescottes
4f15b14b58 IE11 fixes 2017-05-13 01:36:04 +02:00
juliandescottes
00d4a1614b protect frame-picker destroy if frame picker init() was not called 2017-05-13 01:36:04 +02:00
juliandescottes
a72b0c69e5 initialize insert-location frame-picker on show() 2017-05-13 01:36:04 +02:00
juliandescottes
c6733cdad4 add integration test for import merge wizard 2017-05-13 01:36:04 +02:00
juliandescottes
30274ad1f8 replace Promise by Q.defer in ImageImport step 2017-05-13 01:36:04 +02:00
juliandescottes
b7fe8c1a5e use image name as piskel name for image import 2017-05-13 01:36:04 +02:00
juliandescottes
a68dccfce0 persist preview UI during import wizard 2017-05-13 01:36:04 +02:00
juliandescottes
78bbc71e6c Implement Import and Merge wizard dialog 2017-05-13 01:36:04 +02:00
juliandescottes
b5a8eb9f96 Feature #683 - add drawing test for duplicate layer 2017-05-13 01:11:45 +02:00
juliandescottes
af3d0fa48b Feature #683: duplicate layer when SHIFT+CLICK on create layer button 2017-05-13 01:11:45 +02:00
juliandescottes
e6a65c0db4 Fix #687 - use normal flavor for nwjs apps 2017-05-13 01:03:14 +02:00
juliandescottes
f2b733c91e Fix #684 - import GIF as spritesheet failed 2017-05-11 01:47:15 +02:00
Julian Descottes
4506fdbdf2 add new grunt target to build desktop apps for older osx 2017-05-09 09:45:08 +02:00
juliandescottes
5d6f354443 Fix #652 - fix worker ObjectURL creation 2017-05-08 01:17:29 +02:00
juliandescottes
a6d3aff9f1 releae: update version to 0.11.0-SNAPSHOT 2017-05-08 00:17:00 +02:00
juliandescottes
a707170fa2 release: update version to v0.10.1 2017-05-08 00:06:14 +02:00
juliandescottes
8c815f320d copy version file to piskel website 2017-05-08 00:06:14 +02:00
juliandescottes
f74b081fad avoid sanitization for cheatsheet keys 2017-05-08 00:06:14 +02:00
juliandescottes
b8fed60fa6 Fix #651 - stop drawing the zoomedout background if unnecessary 2017-05-06 18:47:01 +02:00
Julian Descottes
d841ad10f6 Merge pull request #677 from juliandescottes/dependencies
Dependencies
2017-05-06 18:42:55 +02:00
juliandescottes
f6e16e7b4b chore: update grunt-spritesmith to 6.4.0 2017-05-06 18:31:49 +02:00
juliandescottes
6fb8a6859c chore: update karma-phantomjs-launcher to 1.0.4 2017-05-06 18:30:08 +02:00
juliandescottes
866553b2ca chore: update grunt-contrib-clean & grunt-contrib-uglify 2017-05-06 17:45:42 +02:00
juliandescottes
5aad87471e chore: update jasmine-chore to 2.6.1 2017-05-06 17:42:19 +02:00
juliandescottes
942aacbb94 chore: update fs-extra to 3.0.1 2017-05-06 17:35:40 +02:00
juliandescottes
88da91bde3 chore: remove karma-chrome-launcher (unused) 2017-05-06 17:32:07 +02:00
juliandescottes
ce94dbeeeb chore: update karma to 1.7.0 2017-05-06 16:54:11 +02:00
juliandescottes
a8c85b8a29 Issue #654 : stop using jquery to create the FramesList markup 2017-04-01 12:48:11 +02:00
Julian Descottes
89199f2d6a Merge pull request #644 from juliandescottes/alt-to-pick-color
select color using alt+click (fixes #623)
2017-03-02 01:52:04 +01:00
juliandescottes
98768b2e5b select color using alt+click (fixes #623) 2017-03-02 01:39:28 +01:00
Julian Descottes
62b1b8baf0 Merge pull request #642 from juliandescottes/sanitize-strings
sanitize strings coming from user inputs
2017-02-23 21:01:05 +01:00
Julian Descottes
11a063de12 sanitize strings coming from user inputs 2017-02-23 19:37:29 +01:00
Julian Descottes
6f4413f353 Merge pull request #638 from juliandescottes/nw-warning
add confirmation message when closing desktop app with unsaved changes
2017-02-19 15:14:33 +01:00
Julian Descottes
974450837e add confirmation message when closing desktop app with unsaved changes 2017-02-19 13:19:09 +01:00
juliandescottes
c6c64af2fd Use Q deferred instead of native promise (IE11) 2017-02-11 16:57:56 +01:00
juliandescottes
c68b82339c remove classList toggle with 2nd argument for IE11 2017-02-11 16:51:27 +01:00
Julian Descottes
099ff80155 Merge pull request #634 from zoeesilcock/628-fix-arrows-in-cheatsheet
Use standard HTML entities for the arrows displayed on the keyboard shortcut list
2017-02-05 12:41:30 +01:00
Zoee Silcock
f30e16386d Use standard HTML entities for the arrows displayed on the keyboard shortcut list 2017-02-05 11:47:45 +01:00
juliandescottes
08b97cb6f0 select previous layer after deleting layer 2017-02-04 14:32:23 +01:00
juliandescottes
b6fa769ba1 temporary fix for layerlist scroll 2017-02-04 14:09:27 +01:00
juliandescottes
47b09b10c5 Merge branch 'master' of https://github.com/juliandescottes/piskel 2017-02-04 13:49:20 +01:00
juliandescottes
f039a89572 disable layerlist smoothscrolling 2017-02-04 13:43:49 +01:00
Julian Descottes
e74329f04e Merge pull request #629 from GMartigny/master
Add CodeClimate
2017-02-02 19:30:40 +01:00
Guillaume Martigny
8959b201e9 Excludes lib from linting 2017-02-01 16:17:38 +01:00
Guillaume Martigny
f5491dc557 Irregular whitespace 2017-02-01 16:15:02 +01:00
Guillaume Martigny
9ce3d44cc6 Add config file for CodeClimate 2017-02-01 15:51:13 +01:00
juliandescottes
8928f3e626 Release version 0.10.0 2017-01-29 14:25:44 +01:00
juliandescottes
e04fde7084 log errors when Deserialize fails 2017-01-29 14:18:59 +01:00
juliandescottes
a25648f8e2 bump version to 0.10.0-RC2 2017-01-29 14:05:11 +01:00
juliandescottes
1918227c81 add integration tests for PNG export & scaled export 2017-01-29 13:56:06 +01:00
juliandescottes
8b1b21368c add gif export integration test 2017-01-29 02:42:42 +01:00
juliandescottes
d781df3290 add drawing test for center tool 2017-01-29 00:11:58 +01:00
Smie
35bfcb5f00 Refines Circle tool for PenSize = 1 2017-01-28 02:27:50 +01:00
Smie
cce4cde98b Corrects Circle tool for even dimensions. 2017-01-28 02:27:50 +01:00
Smie
4706587abb Rewrites Circle drawing tool to behave better with large pen sizes. 2017-01-28 02:27:50 +01:00
Julian Descottes
c0182952c9 Merge pull request #622 from juliandescottes/fix-current-colors
Fix current colors
2017-01-25 15:08:30 +01:00
juliandescottes
ba779a97a6 fix #621 : allow color worker to detect up to 256 colors 2017-01-25 15:07:55 +01:00
juliandescottes
dc149f88d6 remove extra caching from CurrentColorsService 2017-01-25 14:59:09 +01:00
Julian Descottes
ac08ff8b82 Merge pull request #620 from zoeesilcock/285-import-multiple-frames
Allow adding multiple frames with drag and drop
2017-01-24 00:11:39 +01:00
Zoee Silcock
9be332fad3 Allow adding multiple frames with drag and drop
This is a partial solution issue number #285. When dropping multiple images it creates a new frame for each one. It works great when all images are the same size and within the size of the piskel document. When the images aren't the size of the document they are positioned in the same way as single image import.
2017-01-22 11:16:18 +01:00
juliandescottes
11db5ca45c remove getBoundRectanglePixels from PixelUtils 2017-01-21 18:24:48 +01:00
Julian Descottes
37445202f3 Merge pull request #618 from smiegrin/rectanlgeRetool
Improves Rectangle tool performance.
2017-01-21 18:19:56 +01:00
Smie
f8b77403cd Improves Rectangle tool performance. 2017-01-16 11:52:22 -07:00
juliandescottes
74d8aa8c9c migrate copy script to node 2017-01-15 14:13:05 +01:00
juliandescottes
acad4df49e fix typos in perf warning popup 2017-01-15 13:33:57 +01:00
juliandescottes
af92ee6bd7 increase height of performance info popup 2017-01-15 13:26:48 +01:00
juliandescottes
a740699775 increase appengine storage limit to avoid false positive 2017-01-15 13:08:41 +01:00
juliandescottes
6ce2c00acf force color black on brush size label 2017-01-15 13:00:15 +01:00
juliandescottes
93db679dd7 release: bump version to 0.10.0-RC1 2017-01-15 12:51:10 +01:00
juliandescottes
5bde3c471d remove unused paletteController member from DrawingController 2017-01-15 12:35:38 +01:00
juliandescottes
94b1a1df4a History service gets core piskelController from public piskelController 2017-01-14 21:58:37 +01:00
Julian Descottes
8806c41892 Merge pull request #615 from juliandescottes/load-error-msg
display error message on file load error
2017-01-14 21:53:52 +01:00
juliandescottes
8cad3bb607 display error message on file load error 2017-01-14 21:37:52 +01:00
juliandescottes
552d4fa710 nits on test/js/utils/PixelUtilsTest_visit_connected.js 2017-01-14 15:44:47 +01:00
juliandescottes
b11f7a430d add unit test for getSimilarConnectedPixelsFromFrame 2017-01-14 00:56:24 +01:00
juliandescottes
a4952d0db2 fix #603 shape select fails when clicking outside drawing area 2017-01-13 15:07:05 +01:00
juliandescottes
42f4812b46 move drop image logic to FrameUtils, add unit test 2017-01-13 13:58:57 +01:00
juliandescottes
bf91c4ef62 Fix image dropper when image has to be moved 2017-01-13 13:22:21 +01:00
juliandescottes
03f37d46ac add unit tests for colorToInt 2017-01-13 03:31:02 +01:00
juliandescottes
0abd779348 fix #602 : shape selection fails with some colors 2017-01-13 02:59:59 +01:00
juliandescottes
33259e5522 nits on previewSize widget 2017-01-11 23:43:57 +01:00
juliandescottes
e8207aba57 update labels for preview size widget 2017-01-11 21:59:37 +01:00
Julian Descottes
b03b4a7c60 Merge pull request #567 from GMartigny/362-MultiSizePreview
Add a dropdown for preview size options [1x, best, full]
2017-01-11 21:56:23 +01:00
Guillaume Martigny
2f47bc433c lint fix 2017-01-11 12:32:29 +01:00
Guillaume Martigny
9cd3fa03a0 Merge branch 'master' into 362-MultiSizePreview 2017-01-11 12:28:20 +01:00
Guillaume Martigny
d4b4192d45 Final : Specific tooltip while preview size selection disabled 2017-01-11 12:23:49 +01:00
juliandescottes
d5199d38aa remove css variables from built css (edge :( ) 2017-01-11 01:13:56 +01:00
juliandescottes
ab082b9f4a set nwjs downloadURL to https 2017-01-09 09:27:49 +01:00
juliandescottes
2ec6c4b848 upgrade nwjs to 0.19.4 2017-01-09 09:19:12 +01:00
juliandescottes
2cdc999875 Fix bug when opening save panel for sprite with performance problem 2017-01-09 09:10:20 +01:00
Julian Descottes
4c6d2c1e48 Merge pull request #607 from juliandescottes/controller-tests
Add first integration tests
2017-01-09 00:43:46 +01:00
juliandescottes
95256071e1 add missing EOF new lines 2017-01-08 20:43:15 +01:00
juliandescottes
b86ec72a4e use evalLine in integration/settings/test-resize 2017-01-08 20:42:00 +01:00
juliandescottes
70085bc056 Add integration tests for resize content and resize from other origin 2017-01-08 20:38:12 +01:00
Julian Descottes
a328e4d20e add resize test checking frame content
Moved shared methods to a head.js file
2017-01-08 19:56:53 +01:00
Julian Descottes
569b508fd5 mutualize casperjsOptions in gruntfile 2017-01-08 16:39:55 +01:00
Julian Descottes
d30f6a05d1 add integration tests 2017-01-08 16:09:03 +01:00
Julian Descottes
76ae797a9e nits: typos and case 2017-01-08 11:55:09 +01:00
Julian Descottes
61c76f980a Merge pull request #605 from Sal0hcine/fix-reset-default-colours
Pressing "d" for default colors doesn't fully work. #601
2017-01-05 11:44:49 +01:00
Nick Garland
5bd113b38f Removed reset from SelectedColorsService and implemented the reset in PaletteController 2017-01-04 18:28:58 +00:00
Julian Descottes
aa5d4d4090 Merge branch 'master' of https://github.com/juliandescottes/piskel 2017-01-02 23:35:07 +01:00
Julian Descottes
398d93557a remove unused argument in FileDropperService constructor 2017-01-02 23:34:54 +01:00
Julian Descottes
0733a5a142 Merge pull request #600 from zoeesilcock/363-firefox-dnd-bug
Workaround for incorrect frame selection after re-ordering on Firefox
2017-01-02 23:27:33 +01:00
Julian Descottes
835cee37aa Merge pull request #599 from zoeesilcock/563-color-format-preference
Add a setting for changing the color format shown in the color picker
2017-01-02 23:09:19 +01:00
Zoee Silcock
2dea7faea0 Workaround for incorrect frame selection after re-ordering on Firefox
This commit is related to the following issue: #363

When a frame is dropped both `mouseup` and `click` events are triggered on Firefox. This is somwhat expected behaviour but other browsers do not trigger the `click` event.

One would expect jquery-ui to work the same across all browsers but when they got a bug report they decided to not change anything:
https://bugzilla.mozilla.org/show_bug.cgi?id=787944

The most comon workaround appears to be to use the `clone` helper in jquery-ui sortable. Unfortunately this doesn't work because the cloned frame doesn't keep the contents of the canvas. This seemed like the cleanest workaround, here are a few others:
http://stackoverflow.com/questions/947195/jquery-ui-sortable-how-can-i-cancel-the-click-event-on-an-item-thats-dragged
2016-12-29 10:09:05 +01:00
Zoee Silcock
809737908c Add a setting for changing the color format shown in the color picker 2016-12-29 08:08:13 +01:00
Julian Descottes
e43cee3c94 Merge pull request #598 from juliandescottes/disable-gallery
Disable gallery
2016-12-27 01:04:25 +01:00
Julian Descottes
b869d63211 remove useless comment 2016-12-27 00:56:18 +01:00
Julian Descottes
c0f7e7be52 jshint cleanup, move HTML to a template, add css classes 2016-12-27 00:56:18 +01:00
Julian Descottes
98527c6ded update notification style to use piskel theme colors 2016-12-27 00:56:17 +01:00
Julian Descottes
9518d570e6 display save to gallery warning if performance issue detected 2016-12-27 00:52:32 +01:00
Julian Descottes
01b9898181 improve serialization error detection for firefox 2016-12-27 00:52:32 +01:00
juliandescottes
184b2e48aa disable gallery save when if spritesheet size too big (WIP) 2016-12-27 00:52:32 +01:00
juliandescottes
e97a641e95 add constant for the max datastore accepted size 2016-12-27 00:52:32 +01:00
Julian Descottes
7eea5d672a fix hover image for minimap popup preview 2016-12-25 10:20:57 +01:00
Julian Descottes
537234b1d1 update minimap crop style 2016-12-24 11:09:12 +01:00
Julian Descottes
57936d90b1 fix jshint issue 2016-12-24 10:26:40 +01:00
Julian Descottes
ef8060c07d remove unused resizeNearestNeighbor util 2016-12-24 10:24:23 +01:00
Julian Descottes
8551a8546a fix #369 improve perf of grid rendering 2016-12-23 23:41:41 +01:00
Julian Descottes
eb84e87a13 add gold border on textfield:focus 2016-12-23 21:09:05 +01:00
Julian Descottes
ca3b789747 add user setting for seamless mode opacity 2016-12-22 23:27:00 +01:00
Julian Descottes
22dd474799 add border radius to settings export tabs 2016-12-22 22:33:04 +01:00
Julian Descottes
16151e8e95 remove text-shadow from settings panels 2016-12-22 22:21:32 +01:00
Julian Descottes
2f62be4927 simplify buttons styling 2016-12-22 14:21:21 +01:00
Julian Descottes
fbaccb03f2 introduce css variables 2016-12-22 13:06:01 +01:00
juliandescottes
dd9b1e0189 add test to check deserialized piskel contains valid frames 2016-12-21 17:20:54 +01:00
juliandescottes
dda566a218 fix broken serializer 2016-12-21 17:20:54 +01:00
Julian Descottes
2bcd354342 Merge pull request #595 from juliandescottes/unsupported-browser-popup
add a warning popup when detecting an unsupported browser
2016-12-21 15:52:45 +01:00
Julian Descottes
6cc41ee07b add a warning popup when detecting an unsupported browser 2016-12-21 15:44:04 +01:00
juliandescottes
eca9191f29 increase drawing test timeout to 30 seconds 2016-12-21 15:38:31 +01:00
Julian Descottes
83c7e950f0 Merge pull request #593 from juliandescottes/save-split
Save split
2016-12-21 12:25:54 +01:00
juliandescottes
32070efcc1 save split: add comments and cleanup 2016-12-21 12:22:50 +01:00
juliandescottes
c743334a31 Switch back to line layout 2016-12-21 11:45:34 +01:00
juliandescottes
84419a1550 split saved piskel in chunks when serialization fails 2016-12-21 02:28:11 +01:00
juliandescottes
66c941dd25 support chunked layerData in regular deserializer 2016-12-18 11:36:11 +01:00
juliandescottes
dba62d2b0d add pskl.utils.Array.chunk 2016-12-18 09:16:52 +01:00
Julian Descottes
156161f7c8 Merge pull request #574 from juliandescottes/warning-notifications
Warning notifications
2016-12-18 07:15:03 +01:00
juliandescottes
58bfe16b27 performance warning: text cleanup 2016-12-18 06:52:44 +01:00
juliandescottes
57b37971f6 add svg warning icon 2016-12-17 10:19:17 +01:00
juliandescottes
8dab74ceea add text to warning notifications popup 2016-12-16 10:04:36 +01:00
juliandescottes
d0cca52f47 issue #555: add performance warning icon, show dialog 2016-12-16 07:49:15 +01:00
juliandescottes
58cf9f8390 issue #555 detect performance issues based on sprite specs 2016-12-16 07:49:15 +01:00
juliandescottes
49109e51c9 fix js error when resizing piskel (missing fps arg) 2016-12-16 07:02:31 +01:00
Julian Descottes
27b26fe4f3 Merge pull request #589 from juliandescottes/move-fps-to-model
move fps info from preview controller to piskel model
2016-12-13 00:11:47 -10:00
Julian Descottes
b21fc0490d remove unused previewController member in ImportService 2016-12-13 11:04:03 +01:00
Julian Descottes
25ede9ffff cleanup unused arguments in PiskelFileUtils 2016-12-13 11:00:58 +01:00
Julian Descottes
37d2861352 move fps info from preview controller to piskel model 2016-12-13 09:17:34 +01:00
Julian Descottes
2fe0b842a5 update pixijs export metadata app url 2016-12-13 07:28:55 +01:00
Julian Descottes
dd7ab574b9 Merge pull request #581 from PSeitz/savejson
add pixi export
2016-12-12 20:23:45 -10:00
Julian Descottes
c2fdb65e37 simplify error template 2016-12-12 10:08:37 +01:00
Julian Descottes
aef88c8713 simplify error template 2016-12-12 09:58:56 +01:00
Julian Descottes
b3c13f1630 Merge pull request #587 from juliandescottes/create-issue-template
add issue template
2016-12-11 22:42:46 -10:00
Julian Descottes
6b0eda2998 add issue template 2016-12-12 09:35:02 +01:00
Julian Descottes
16cfffa898 Merge pull request #579 from PSeitz/piskelcopy
Copy between piskels
2016-12-09 07:18:45 -10:00
Julian Descottes
732c3c2d76 Merge pull request #577 from GMartigny/559-TooLongLayerName
Add ellipsis to overflowing layer item name #559
2016-12-06 03:19:48 +01:00
Pascal Seitz
21c7425cbc add pixi export 2016-12-05 19:11:01 +01:00
Guillaume Martigny
9ac9583455 Address comment and nit 2016-12-05 09:43:15 +01:00
Pascal Seitz
9608995d9c Fix spaces 2016-12-04 11:59:07 +01:00
Pascal Seitz
5faa985dea Copy between piskels
#272
2016-12-04 11:40:18 +01:00
Guillaume Martigny
5544f734cf 🥷 2016-12-02 17:30:38 +01:00
Guillaume Martigny
9d0d38e081 Proposal : tooltip only when layer name overflow 2016-12-02 17:21:10 +01:00
Guillaume Martigny
ad5c8182e4 Add ellipsis to overflowing layer item name #559 2016-12-01 11:43:23 +01:00
Julian Descottes
9dd403a54e Merge pull request #560 from smiegrin/master
Allows square brush size of up to 32 pixels using keyboard...
2016-11-30 23:05:03 +01:00
Guillaume Martigny
f2424ed16e Resolve options collision
Disable preview widget with tooltip
Fix animation with shortcuts
2016-11-30 11:25:47 +01:00
Smie
da0e8dec84 Stylistic changes to pixel and pen size code. 2016-11-28 08:21:30 -07:00
Julian Descottes
a5fc491e92 Merge pull request #573 from juliandescottes/update-deps
Update deps
2016-11-27 23:43:23 +01:00
Julian Descottes
e53ee0604c chore: update dateformat to 2.0.0 2016-11-27 12:08:51 +01:00
Julian Descottes
e1671202af chore: update grunt-contrib-jshint to 1.1.0 2016-11-27 12:08:18 +01:00
Julian Descottes
5e3bb9d79c chore: update nwjs to 0.18.8 2016-11-27 12:07:25 +01:00
Julian Descottes
c5c336e12c chore: update grunt-nw-builder to 3.1.0 2016-11-27 11:57:13 +01:00
Julian Descottes
85b141df52 chore: udpate karma to 1.3.0 2016-11-27 11:54:27 +01:00
Smie
a65eeee2e0 Merge branch 'master' of https://github.com/juliandescottes/piskel 2016-11-26 13:32:23 -07:00
Smie
39dba2b70f Displays pen size in selector for sizes above 4 pixels wide. 2016-11-26 13:09:07 -07:00
juliandescottes
0cb4a7831b fix drawing tests when running in browser 2016-11-24 14:18:52 +01:00
Guillaume Martigny
696d18748a Move tooltips
Change "best" option on resize
Update available options on resize and configuration change
2016-11-23 18:32:17 +01:00
Guillaume Martigny
e328b4c7b8 Add a dropdown for preview size options [1x, best, full]
https://github.com/juliandescottes/piskel/issues/362
2016-11-22 17:12:15 +01:00
Julian Descottes
5996216ae7 Merge pull request #566 from juliandescottes/memory-improvements
Memory improvements
2016-11-22 00:27:33 +01:00
Smie
8cb7a4aaf6 Permits brush size of only 1-32 pixels. 2016-11-21 12:53:14 -07:00
juliandescottes
136506da40 issue #374 throttle calls to currentColorsService update function 2016-11-20 12:08:31 +01:00
juliandescottes
d08c101b11 issue #374 cap cached frames for cachedframeprocessor to 100 2016-11-20 01:10:05 +01:00
juliandescottes
4b50dfdb5b issue #374 limit undo/redo to the last 500 states 2016-11-20 00:24:48 +01:00
Julian Descottes
e3b363d757 Fix regression when loading piskel files 2016-11-12 18:33:00 +01:00
Julian Descottes
440c28d0fd Fix regression when loading piskel files 2016-11-12 18:32:21 +01:00
Smie
a560872df7 Stylistic changes to src/js/utils/PixelUtils.js 2016-10-28 18:39:00 -06:00
Smie
aca6c28b4b Allows square brush size of up to 1,000,000 pixels using keyboard shortcuts. 2016-10-28 17:56:22 -06:00
Julian Descottes
4a01f5625c release: set version to v0.9.0-RC2 2016-10-16 21:32:00 +02:00
Julian Descottes
8f493a8147 add comment in arraybuffer serialization helpers 2016-10-16 18:33:10 +02:00
Julian Descottes
73986c4e61 move arraybuffer serializer to dedicated subfolder 2016-10-16 18:28:12 +02:00
Julian Descottes
2a7957bce2 rollback to modelv2 for all serializations except history service 2016-10-16 00:22:06 +02:00
Julian Descottes
0586756b92 release: set version to 0.9.0-RC1 2016-10-15 19:30:53 +02:00
Julian Descottes
2b78456314 fix #554: zooming in/out breaks drawing area on Safari 2016-10-10 18:14:06 +02:00
juliandescottes
4b378d48a2 trigger piskel_saved event after loading page sprite 2016-10-10 03:03:59 +02:00
juliandescottes
5faf4af7c9 fix page title update when loading existing piskel 2016-10-10 02:44:51 +02:00
juliandescottes
d947fe1c05 add blob type 2016-10-10 02:17:19 +02:00
juliandescottes
85336f9b9a fix loading of v2 models 2016-10-10 01:47:26 +02:00
juliandescottes
91f637d2fd fix color picker regression with intToColor missing 2016-10-09 23:59:16 +02:00
juliandescottes
eb69c91d43 add other color picker test 2016-10-09 23:59:16 +02:00
juliandescottes
7ae40d8794 fix pick color with middle mouse no longer workin 2016-10-09 23:59:16 +02:00
juliandescottes
5a39d6850e fix backward compatibility issue on piskelapp.com 2016-10-09 23:59:16 +02:00
Julian Descottes
f342b72e1b Merge pull request #553 from juliandescottes/fix-transparency-glitch
Fix transparency issues after deserialization
2016-10-09 13:25:49 +02:00
Julian Descottes
1624792f61 Fix transparency issues after deserialization 2016-10-09 13:09:28 +02:00
juliandescottes
dd58af30b9 close dialogs when clicking outside of the dialog container 2016-10-02 00:56:13 +02:00
juliandescottes
4e515f4820 use monospace instead of Courier 2016-10-02 00:49:49 +02:00
juliandescottes
71ec809aea fix #502: add smoothscroll polyfill 2016-10-02 00:23:26 +02:00
Dávid Szabó
9538e03928 Fix BackupService change JSON to new serialization 2016-10-01 14:34:01 +02:00
Dávid Szabó
e647826095 Move string to buffer converting code to utils 2016-10-01 14:34:01 +02:00
Dávid Szabó
5fe9081df1 Remove unneccessary frame version incrementing 2016-10-01 14:34:01 +02:00
Dávid Szabó
d4f038f97b Move buffer to string converting to utils 2016-10-01 14:34:01 +02:00
Dávid Szabó
23a0768f8d Fix wrong calculation of requried bytes 2016-10-01 14:34:01 +02:00
Dávid Szabó
4cc434edd6 Remove atob and btoa, it's already in base64 2016-10-01 14:34:01 +02:00
Dávid Szabó
26b3cf3a23 Remove unnecessary caching 2016-10-01 14:34:01 +02:00
Dávid Szabó
7e9c632efd Remove unused sub variable 2016-10-01 14:34:01 +02:00
Dávid Szabó
6c50816830 Refactor downloadAsFile to accept blob 2016-10-01 14:34:01 +02:00
Dávid Szabó
38cbfe4fce Fix FileDropperService to work with the new cb 2016-10-01 14:34:01 +02:00
Dávid Szabó
d775609183 Remove unneccessary frame version incrementation 2016-10-01 14:34:01 +02:00
Dávid Szabó
74f36daa7c Break oneliner to multiple lines 2016-10-01 14:34:01 +02:00
Dávid Szabó
ffca6aa44c Move intToHex to utils and change for to map 2016-10-01 14:34:01 +02:00
Dávid Szabó
6ea9c248d8 Remove unneccessary else if 2016-10-01 14:34:01 +02:00
Dávid Szabó
9c96c7eaf2 Fix missing variable and remove unnecessesary if 2016-10-01 14:34:01 +02:00
Dávid Szabó
c97ce34e6e Fix consistency 2016-10-01 14:34:01 +02:00
Dávid Szabó
43f989919c Remove unneccessary type check 2016-10-01 14:34:01 +02:00
Dávid Szabó
0ec8036670 Move Uint32Array.fill polyfill to utils 2016-10-01 14:34:01 +02:00
Dávid Szabó
3a2d837f5a Decrease animated preview throttle to 300ms 2016-10-01 14:34:01 +02:00
Dávid Szabó
0f404d2b25 Refactor dom initialize flag 2016-10-01 14:34:01 +02:00
Dávid Szabó
5577c3ab5a Fix GalleryStorageService
GalleryStorageService is sending JSON so it couldn't serialize the
ArrayBuffer which came from serializing the Piskel. In this commit it
sends the ArrayBuffer as an Array to the server so it can store it easily.
2016-10-01 14:34:01 +02:00
Dávid Szabó
baf8049ea6 Fix jshint errors 2016-10-01 14:34:01 +02:00
Dávid Szabó
74b7f93ddb Fix code style errors 2016-10-01 14:34:01 +02:00
Dávid Szabó
fb97533cc9 Rework frameslist for better perfomance 2016-10-01 14:34:01 +02:00
Dávid Szabó
ebab5ecb3f Change frameslist throttle from 1sec to 500ms 2016-10-01 14:34:01 +02:00
Dávid Szabó
37443ecdc2 Fix code style errors 2016-10-01 14:34:01 +02:00
Dávid Szabó
91f0d98d63 Fix wrong colors being in current colors 2016-10-01 14:34:01 +02:00
Dávid Szabó
fa716d7a6c Fix ColorSwap and Bucket tool 2016-10-01 14:34:01 +02:00
Dávid Szabó
ac3e43bf61 Add caching to CurrentColorsService 2016-10-01 14:34:01 +02:00
Dávid Szabó
502eb1aac4 Fix missing name and description from v2 2016-10-01 14:34:01 +02:00
Dávid Szabó
218c0b511b Fix callbacks to work with the new serializer 2016-10-01 14:34:01 +02:00
Dávid Szabó
a3fd2f0d89 Remove unnecessary argument 2016-10-01 14:34:01 +02:00
Dávid Szabó
c522d48c8f Fix test to work with new serializer format 2016-10-01 14:34:01 +02:00
Dávid Szabó
c2b283be67 Fix services to use new serializer format 2016-10-01 14:34:01 +02:00
Dávid Szabó
dbbd57ae28 Fix old deserializers to match new callback func 2016-10-01 14:34:01 +02:00
Dávid Szabó
fefc635e25 Add function for reading file as array buffer 2016-10-01 14:34:01 +02:00
Dávid Szabó
8910bf0dbd Add model version 2 backward compatiblity 2016-10-01 14:34:01 +02:00
Dávid Szabó
f607c65789 Add model version 3 deserializer 2016-10-01 14:34:01 +02:00
Dávid Szabó
2962a838d3 Add model version 3 serializer 2016-10-01 14:34:01 +02:00
Dávid Szabó
7eab386122 Make sure opacity is a float and rounded 2016-10-01 14:34:01 +02:00
Dávid Szabó
0c0aa5f2c9 Add caching to CurrentColorsService 2016-10-01 14:34:01 +02:00
Dávid Szabó
bb7d5c862f Remove unnecessary rendering 2016-10-01 14:34:01 +02:00
Dávid Szabó
f0f79754f1 Remove loop and use the pixels directly 2016-10-01 14:34:01 +02:00
Dávid Szabó
a097d0b897 Fix frame processor caching 2016-10-01 14:34:01 +02:00
Dávid Szabó
a1ab693fb5 Remove nested loop 2016-10-01 14:34:01 +02:00
Dávid Szabó
7707aca03e Change nested loop and directly change pixels 2016-10-01 14:34:01 +02:00
Dávid Szabó
f829d589d5 Improve frame colors worker perfomance by caching 2016-10-01 14:34:01 +02:00
Dávid Szabó
712262b82a Format some code and remove unnecessary logging 2016-10-01 14:34:01 +02:00
Dávid Szabó
0bbb4ff2d5 Remove 2nd level cache 2016-10-01 14:34:01 +02:00
Dávid Szabó
6ee23e22df Throttle frameslist and preview rendering 2016-10-01 14:34:01 +02:00
Dávid Szabó
f5c98cf0b3 Rework pixel storage, manipulation, rendering 2016-10-01 14:34:01 +02:00
Dávid Szabó
06abdca62e Change model version to 3
The new serializing will use typed arrays / blob.
2016-10-01 14:34:01 +02:00
juliandescottes
2ca97b48e7 Add another performance tests for layers and undo 2016-10-01 13:56:53 +02:00
juliandescottes
132487704b Add simple performance test 2016-10-01 13:48:58 +02:00
juliandescottes
f6be33d5bf Add performance figures to drawing tests 2016-10-01 13:09:19 +02:00
Julian Descottes
8a031d771a Merge pull request #550 from david-szabo97/feature_export-selected-frame
Add misc export: download selected frame as png
2016-09-28 14:42:46 +02:00
Dávid Szabó
3be2b3d3bc Add misc export: download selected frame as png 2016-09-23 16:35:22 +02:00
Julian Descottes
7b512f6412 Merge pull request #539 from juliandescottes/fix-drawing-tests
Fix drawing tests
2016-09-01 15:51:05 +02:00
juliandescottes
b1058c452e Issue #533: Add grunt task aliases for backward compat 2016-09-01 15:37:28 +02:00
juliandescottes
7bc5d20b2e Issue #533: Merge test suites. use delay as timeout 2016-09-01 01:42:06 +02:00
juliandescottes
e9ef6eb5b3 Issue #533: drawing tests, fix keyboard event replay on osx 2016-09-01 00:14:13 +02:00
juliandescottes
a2d5e6ff04 Issue #533: Fix drawing tests cross-browser/OS issues 2016-09-01 00:12:07 +02:00
Julian Descottes
4d12908363 Merge pull request #536 from david-szabo97/update_phantomjs_casperjs
Update PhantomJS and CasperJS
2016-09-01 00:11:01 +02:00
Julian Descottes
682ef9cf91 Merge pull request #538 from david-szabo97/hotfix-retina_icons_gitignore
Remove icons@2x.png from the repo
2016-08-31 23:08:37 +02:00
Dávid Szabó
cbacd68414 Remove icons@2x.png from the repo 2016-08-31 22:40:22 +02:00
Dávid Szabó
3b65b90de1 Fix package.json 2016-08-31 17:25:20 +02:00
Dávid Szabó
e7ed2f9b24 Update phantomjs to 2.1.7
PhantomJS 1.9.19 doesn't support typed arrays so the tests would fail.
2016-08-31 16:27:37 +02:00
Dávid Szabó
0238dffe71 Update CasperJS and refactor tests 2016-08-31 16:20:01 +02:00
Julian Descottes
52eaa8b170 Merge pull request #529 from david-szabo97/hotfix-multiple_piskel_ready_callback
Change onPiskelReady to support multiple callback
2016-08-30 00:18:53 +02:00
Dávid Szabó
53d728cf3a Make code more consistent 2016-08-26 01:11:03 +02:00
Dávid Szabó
d01f4ef83e Change onPiskelReady to support multiple callback 2016-08-24 22:43:16 +02:00
juliandescottes
9c6871effc Fix layout issue when starting with small viewport height 2016-08-16 10:33:19 +02:00
juliandescottes
2fe1fe67e5 Fix: flexbox issue on IE11 2016-08-16 10:06:42 +02:00
juliandescottes
8867324468 Fix zoom centering when zooming with keyboard shortcuts 2016-08-16 09:53:14 +02:00
juliandescottes
1bf326fbd8 release: set version to 0.9.0-SNAPSHOT 2016-08-16 01:43:26 +02:00
juliandescottes
eef85c57b7 release: version 0.8.2 2016-08-16 01:11:07 +02:00
Julian Descottes
d4e9b1e896 Merge pull request #516 from juliandescottes/feature-drag-selection
Feature drag selection
2016-08-16 01:10:18 +02:00
juliandescottes
8e3ac50f81 Issue #290: cleanup unused code in SelectionManager 2016-08-16 01:04:55 +02:00
Julian Descottes
f4cbabe2ce Issue #290: selection tools: clear hasSelection flag when calling commitSelection 2016-08-16 00:40:01 +02:00
Julian Descottes
69393127fa Issue #290: rename dismissSelection to commitSelection 2016-08-16 00:40:01 +02:00
Julian Descottes
fc7fc6d9b0 Issue #290: Fix typo in comment 2016-08-16 00:40:01 +02:00
Julian Descottes
01aa4629cc Issue #290: Commit selection on ENTER 2016-08-16 00:40:01 +02:00
Julian Descottes
22797e5dc5 Issue #290: add missing parameter to dismissSelection in BaseSelect 2016-08-16 00:40:01 +02:00
Julian Descottes
0d5dc21a41 Issue #290: change boolean flag name to isMovingContent in BaseSelect 2016-08-16 00:40:01 +02:00
Julian Descottes
0d1210e71f Issue #290: fix wand cursor hotspot 2016-08-16 00:40:01 +02:00
Julian Descottes
34f2a9df0b Issue #163: show highlighter pixel for selection tools when no selection 2016-08-16 00:40:01 +02:00
Julian Descottes
a383e59280 Issue #290: allow to drag selection when using SHIFT while selection 2016-08-16 00:40:01 +02:00
Julian Descottes
230f1b23fc Merge pull request #518 from epicabsol/icontweaks
Cursor tweaks
2016-08-06 18:45:40 +02:00
epicabsol
77ccd60e77 Renamed lighten cursor
lighting.png -> lighten.png
2016-08-06 09:23:05 -07:00
Julian Descottes
5014937392 Merge pull request #517 from epicabsol/master
Correct desktop window icon
2016-08-06 13:08:26 +02:00
epicabsol
17e6cf9b38 Dither & stroke cursors
Added dither and stroke cursors. The line on the stroke cursor is quite
hard to see, but I think that's pretty unaviodable. I would suggest
moving to a larger cursor size.
2016-08-05 22:32:24 -07:00
epicabsol
d795c297f5 Lighting cursor, more tweaks
Added an icon for the lighting tool, although it's somewhat difficult to
see what it is without looking closely. I'd love to hear other ideas for
a cursor. (See juliandescottes/piskel#351)
I also reworked the hit point of the existing cursors by a few pixels.
2016-08-05 21:34:46 -07:00
epicabsol
f4bf053564 Reworked circle drawing cursor
Reworked circle drawing cursor to match the style of the rectangle
cursor.
2016-08-05 20:33:18 -07:00
epicabsol
d10c284436 Correct desktop window icon filename
I found the logo at dest/prod/logo.png, while there was no
dest/logo.png. Fixes juliandescottes/piskel#515
2016-08-05 19:06:49 -07:00
Julian Descottes
fdd4fb5b4e only update zoom for a valid modifier, fix zoom centering bug when using keyboard shortcuts 2016-07-30 00:01:32 +02:00
Julian Descottes
3e7999cfc5 Merge pull request #385 from smiegrin/master
Introduces zooming towards/away from mouse
2016-07-28 09:39:18 +02:00
Smie
f4c860ddfa Consolidates zooming into single function. 2016-07-26 09:28:18 -06:00
Julian Descottes
2dee5fcad1 Merge pull request #512 from juliandescottes/fix-move-viewport
Fix viewport shaking on touchmove event on mobile/tablet
2016-07-26 12:20:06 +02:00
Julian Descottes
4895017ebb Fix viewport shaking on touchmove event on mobile/tablet 2016-07-26 12:13:49 +02:00
Smie
81b1bca7f5 Merge branch 'master' of https://github.com/juliandescottes/piskel 2016-07-25 14:40:58 -06:00
juliandescottes
0b1ec655ae retina: update lasso & shape select icons 2016-07-25 09:32:50 +02:00
juliandescottes
144cf4b7de release: set version to 0.9.0-SNAPSHOT 2016-07-24 19:42:46 +02:00
Smie Grin
be79eb2f6f Merge branch 'master' of https://github.com/juliandescottes/piskel 2016-05-04 16:31:53 -06:00
Smie Grin
3b6c5aa7a4 Sync upstream Jan 31 2016 2016-01-31 16:41:34 -07:00
Smie Grin
e8f6bcee63 Merge remote-tracking branch 'upstream/master' 2016-01-18 07:39:31 -07:00
smiegrin
412067ad90 Introduces zooming towards/away from mouse 2016-01-17 16:30:21 -07:00
318 changed files with 15491 additions and 2947 deletions

25
.codeclimate.yml Normal file
View File

@@ -0,0 +1,25 @@
engines:
csslint:
enabled: true
duplication:
enabled: true
config:
languages:
- javascript
eslint:
enabled: true
checks:
wrap-iife:
enabled: false
fixme:
enabled: true
ratings:
paths:
- "**.css"
- "**.js"
exclude_paths:
- .github/
- bin/
- misc/
- src/js/lib/
- test/

2
.eslintignore Normal file
View File

@@ -0,0 +1,2 @@
# Exclude libs.
**/lib/**/*.js

19
.github/ISSUE_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,19 @@
Bug description
(this template is intended for bug reports, erase it when requesting features/enhancements)
### Steps to reproduce the bug
1. go to piskelapp.com
2. select a tool
3. ...
### Environment details
* operating system:
* browser (or offline application version):
### Sprite details
* number of frames:
* sprite resolution:
* session duration:
Feel free to include a screenshot of the bug, a .piskel file of the sprite or anything else that can help us investigate.

7
.gitignore vendored
View File

@@ -1,4 +1,4 @@
# mac artefacts
# mac artifacts
*.DS_Store
# nodejs local installs
@@ -15,10 +15,12 @@ cache
# netbeans project folder
nbproject
# vscode workspace folder
.vscode
# git stackdumps
*.stackdump
# diffs
diff.txt
@@ -28,6 +30,7 @@ build/closure/closure_compiled_binary.js
# spriting artifacts
src/img/icons.png
src/img/icons@2x.png
src/css/icons.css
# plato report directory

75
.jscsrc
View File

@@ -1,75 +0,0 @@
{
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"maximumLineLength": {
"value": 80,
"allExcept": ["comments", "regex"]
},
"validateIndentation": 2,
"validateQuoteMarks": "'",
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowMultipleVarDecl": true,
"disallowKeywordsOnNewLine": ["else"],
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpacesInForStatement": true,
"requireLineFeedAtFileEnd": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": false
},
"disallowSpacesInsideObjectBrackets": "all",
"disallowSpacesInsideArrayBrackets": "all",
"disallowSpacesInsideParentheses": true,
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true,
"disallowKeywords": ["with"],
"disallowSpacesInFunctionExpression": null,
"disallowSpacesInFunctionDeclaration": null,
"disallowSpacesInCallExpression": true,
"disallowSpaceAfterObjectKeys": false,
"requireSpaceBeforeObjectValues": true,
"requireCapitalizedConstructors": true,
"requireDotNotation": true,
"requireSemicolons": true,
"validateParameterSeparator": ", ",
"jsDoc": null
}

View File

@@ -1,14 +1,9 @@
language: node_js
node_js:
- "4.1"
- "7.4.0"
before_install:
- npm update -g npm
- npm install -g grunt-cli
- git clone git://github.com/n1k0/casperjs.git ~/casperjs
- cd ~/casperjs
- git checkout tags/1.0.2
- export PATH=$PATH:`pwd`/bin
- cd -
before_script:
- phantomjs --version
- casperjs --version

View File

@@ -9,11 +9,10 @@ module.exports = function(grunt) {
TEST : 9991
};
var DEV_MODE = '?debug';
// create a version based on the build timestamp
var dateFormat = require('dateformat');
var version = '-' + dateFormat(new Date(), "yyyy-mm-dd-hh-MM");
var releaseVersion = require('./package.json').version;
/**
* Helper to prefix all strings in provided array with the provided path
@@ -34,37 +33,27 @@ module.exports = function(grunt) {
var stylePaths = require('./src/piskel-style-list.js').styles;
var piskelStyles = prefixPaths(stylePaths, "src/");
var getCasperConfig = function (suiteName, delay, host) {
var testPaths = require('./test/casperjs/' + suiteName).tests;
var tests = prefixPaths(testPaths, "test/casperjs/");
// Casper JS tests
var casperjsOptions = [
'--baseUrl=http://' + hostname + ':' + PORT.TEST,
'--mode=?debug',
'--verbose=false',
'--includes=test/casperjs/integration/include.js',
'--log-level=info',
'--print-command=false',
'--print-file-paths=true',
];
return {
filesSrc : tests,
options : {
args : {
baseUrl : 'http://' + host + ':' + PORT.TEST,
mode : DEV_MODE,
delay : delay
},
async : false,
direct : false,
logLevel : 'info',
printCommand : false,
printFilePaths : true
}
};
};
var getConnectConfig = function (base, port, host) {
if (typeof base === 'string') {
base = [base];
}
var integrationTestPaths = require('./test/casperjs/integration/IntegrationSuite.js').tests;
var integrationTests = prefixPaths(integrationTestPaths, "test/casperjs/integration/");
var getConnectConfig = function (base, port, host, open) {
return {
options: {
port: port,
hostname : host,
base: base
base: base,
open: open
}
};
};
@@ -91,33 +80,17 @@ module.exports = function(grunt) {
css : ['src/css/**/*.css']
},
jscs : {
options : {
"config": ".jscsrc",
"maximumLineLength": 120,
"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
"validateQuoteMarks": { "mark": "'", "escape": true },
"disallowMultipleVarDecl": "exceptUndefined",
"disallowSpacesInAnonymousFunctionExpression": null
},
js : [ 'src/js/**/*.js' , '!src/js/**/lib/**/*.js' ]
},
jshint: {
options: {
undef : true,
latedef : true,
browser : true,
trailing : true,
curly : true,
globals : {'$':true, 'jQuery' : true, 'pskl':true, 'Events':true, 'Constants':true, 'console' : true, 'module':true, 'require':true, 'Q':true}
},
eslint: {
files: [
'Gruntfile.js',
'package.json',
// Includes
'src/js/**/*.js',
'!src/js/**/lib/**/*.js' // Exclude lib folder (note the leading !)
]
// Exludes
// TODO: remove this (for now we still get warnings from the lib folder)
'!src/js/**/lib/**/*.js'
],
options: {
fix: grunt.option('fix') // this will get params from the flags
}
},
/**
@@ -125,18 +98,9 @@ module.exports = function(grunt) {
*/
connect: {
prod: getConnectConfig('dest/prod', PORT.PROD, hostname),
test: getConnectConfig(['dest/dev', 'test'], PORT.TEST, hostname),
dev: getConnectConfig(['dest/dev', 'test'], PORT.DEV, hostname)
},
open : {
prod : {
path : 'http://' + hostname + ':' + PORT.PROD + '/'
},
dev : {
path : 'http://' + hostname + ':' + PORT.DEV + '/' + DEV_MODE
}
prod: getConnectConfig('dest/prod', PORT.PROD, hostname, true),
test: getConnectConfig(['dest/dev', 'test'], PORT.TEST, hostname, false),
dev: getConnectConfig(['dest/dev', 'test'], PORT.DEV, hostname, 'http://' + hostname + ':' + PORT.DEV + '/?debug')
},
watch: {
@@ -180,7 +144,7 @@ module.exports = function(grunt) {
},
css : {
src : piskelStyles,
dest : 'dest/prod/css/piskel-style-packaged' + version + '.css'
dest : 'dest/tmp/css/piskel-style-packaged' + version + '.css'
}
},
@@ -201,7 +165,8 @@ module.exports = function(grunt) {
dest: 'dest/tmp/index.html',
options : {
globals : {
'version' : version
'version' : version,
'releaseVersion' : releaseVersion
}
}
}
@@ -231,19 +196,18 @@ module.exports = function(grunt) {
{src: ['dest/tmp/index.html'], dest: 'dest/prod/piskelapp-partials/main-partial.html'}
]
},
// remove the fake header from the desktop build
desktop: {
css: {
options: {
patterns: [{
match: /<!--standalone-start-->(?:.|[\r\n])*<!--standalone-end-->/,
replacement: "",
description : "Remove everything between standalone-start & standalone-end"
}
]
match: /var\(--highlight-color\)/g,
replacement: "gold",
}]
},
files: [
{src: ['dest/prod/index.html'], dest: 'dest/prod/index.html'}
]
files: [{
src: ['dest/tmp/css/piskel-style-packaged' + version + '.css'],
dest: 'dest/prod/css/piskel-style-packaged' + version + '.css'
}]
}
},
@@ -282,9 +246,23 @@ module.exports = function(grunt) {
}
},
ghost : {
'travis' : getCasperConfig('TravisTestSuite.js', 10000, hostname),
'local' : getCasperConfig('LocalTestSuite.js', 50, hostname)
casperjs : {
drawing : {
files : {
src: ['test/casperjs/DrawingTest.js']
},
options : {
casperjsOptions: casperjsOptions
}
},
integration : {
files : {
src: integrationTests
},
options : {
casperjsOptions: casperjsOptions
}
}
},
/**
@@ -294,57 +272,78 @@ module.exports = function(grunt) {
nwjs: {
windows : {
options: {
version : "0.15.4",
downloadUrl: 'https://dl.nwjs.io/',
version : "0.19.4",
build_dir: './dest/desktop/', // destination folder of releases.
win: true,
linux32: true,
linux64: true
linux64: true,
flavor: "normal",
},
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
},
macos : {
options: {
downloadUrl: 'https://dl.nwjs.io/',
osx64: true,
version : "0.15.4",
build_dir: './dest/desktop/'
version : "0.19.4",
build_dir: './dest/desktop/',
flavor: "normal",
},
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
},
macos_old : {
options: {
downloadUrl: 'https://dl.nwjs.io/',
osx64: true,
version : "0.12.3",
build_dir: './dest/desktop/old',
flavor: "normal",
},
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
}
}
});
// Validate
grunt.registerTask('lint', ['jscs:js', 'leadingIndent:css', 'jshint']);
// karma/unit-tests task
// TEST TASKS
// Run linting
grunt.registerTask('lint', ['eslint', 'leadingIndent:css']);
// Run unit-tests
grunt.registerTask('unit-test', ['karma']);
// Run integration tests
grunt.registerTask('integration-test', ['build-dev', 'connect:test', 'casperjs:integration']);
// Run drawing tests
grunt.registerTask('drawing-test', ['build-dev', 'connect:test', 'casperjs:drawing']);
// Run linting, unit tests, drawing tests and integration tests
grunt.registerTask('test', ['lint', 'unit-test', 'build-dev', 'connect:test', 'casperjs:drawing', 'casperjs:integration']);
// Validate & Test
grunt.registerTask('test-travis', ['lint', 'unit-test', 'build-dev', 'connect:test', 'ghost:travis']);
// Validate & Test (faster version) will NOT work on travis !!
grunt.registerTask('test-local', ['lint', 'unit-test', 'build-dev', 'connect:test', 'ghost:local']);
grunt.registerTask('test-local-nolint', ['unit-test', 'build-dev', 'connect:test', 'ghost:local']);
// Run the tests, even if the linting fails
grunt.registerTask('test-nolint', ['unit-test', 'build-dev', 'connect:test', 'casperjs:drawing', 'casperjs:integration']);
grunt.registerTask('test', ['test-travis']);
grunt.registerTask('precommit', ['test-local']);
// Used by optional precommit hook
grunt.registerTask('precommit', ['test']);
// BUILD TASKS
grunt.registerTask('build-index.html', ['includereplace']);
grunt.registerTask('merge-statics', ['concat:js', 'concat:css', 'uglify']);
grunt.registerTask('build', ['clean:prod', 'sprite', 'merge-statics', 'build-index.html', 'replace:mainPartial', 'copy:prod']);
grunt.registerTask('build', ['clean:prod', 'sprite', 'merge-statics', 'build-index.html', 'replace:mainPartial', 'replace:css', 'copy:prod']);
grunt.registerTask('build-dev', ['clean:dev', 'sprite', 'build-index.html', 'copy:dev']);
grunt.registerTask('desktop', ['clean:desktop', 'default', 'nwjs:windows']);
grunt.registerTask('desktop-mac', ['clean:desktop', 'default', 'nwjs:macos']);
grunt.registerTask('desktop-mac-old', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:macos_old']);
// Validate & Build
grunt.registerTask('default', ['lint', 'build']);
// Build stand alone app with nodewebkit
grunt.registerTask('desktop', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:windows']);
grunt.registerTask('desktop-mac', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:macos']);
// SERVER TASKS
// Start webserver and watch for changes
grunt.registerTask('serve', ['build', 'connect:prod', 'open:prod', 'watch:prod']);
grunt.registerTask('serve', ['build', 'connect:prod', 'watch:prod']);
// Start webserver on src folder, in debug mode
grunt.registerTask('serve-dev', ['build-dev', 'connect:dev', 'open:dev', 'watch:dev']);
grunt.registerTask('play', ['build-dev', 'connect:dev', 'watch:dev']);
grunt.registerTask('serve-debug', ['serve-dev']);
grunt.registerTask('play', ['serve-dev']);
// ALIASES, kept for backward compatibility
grunt.registerTask('serve-debug', ['play']);
grunt.registerTask('serve-dev', ['play']);
grunt.registerTask('test-travis', ['test']);
grunt.registerTask('test-local', ['test']);
// Default task
grunt.registerTask('default', ['lint', 'build']);
};

View File

@@ -1,75 +1,61 @@
Piskel
======
[![Travis Status](https://api.travis-ci.org/juliandescottes/piskel.png?branch=master)](https://travis-ci.org/juliandescottes/piskel) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)
[![Travis Status](https://api.travis-ci.org/piskelapp/piskel.png?branch=master)](https://travis-ci.org/piskelapp/piskel) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](https://gruntjs.com/)
A simple web-based tool for Spriting and Pixel art.
Piskel is an easy-to-use sprite editor. It can be used to create game sprites, animations, pixel-art...
It is the editor used in **[piskelapp.com](https://www.piskelapp.com)**.
![Piskel editor screenshot](https://screenletstore.appspot.com/img/8f03e768-ac59-11e3-b2a1-7f5a1b97c420.jpeg "Piskel editor screenshot")
<img
src="https://screenletstore.appspot.com/img/95aaa0f0-37a4-11e7-a652-7b8128ce3e3b.png"
title="Piskel editor screenshot"
width="500">
You can try the standalone editor at **http://juliandescottes.github.io/piskel** or see it integrated in **http://piskelapp.com**.
## About Piskel
Piskel is mainly developped by :
### Built with
* **[@juliandescottes](https://github.com/juliandescottes)**
* **[@grosbouddha](https://github.com/grosbouddha)**
## What's the point ?
You can use Piskel to do two things :
* **spriting** : create retro-style sprites for games
![Megaman spritesheet](http://piskel-imgstore-a.appspot.com/img/c8081287-ac58-11e3-bd8c-b3c4036c0eee.png "Megaman spritesheet")
* **pixelart** : create crazy/pretty pixelart animations for fun !
![Rabbit jumping](http://piskel-imgstore-a.appspot.com/img/947f2dab-ac58-11e3-949a-b3c4036c0eee.gif "Rabit jumping")
Integrated in **[piskelapp.com](http://piskelapp.com)**, you can share everything you work on with others as easily as you share a link.
## Requirements
Piskel supports the following browsers :
* **Chrome** (latest)
* **Firefox** (latest)
* **Internet Explorer** 11+
... and a fairly recent computer.
We don't plan/want/could be forced into supporting older IEs. For Opera and Safari, we've never tested them but the gap shouldn't be huge.
## Offline version
Offline builds are available. More details in the [dedicated wiki page](https://github.com/juliandescottes/piskel/wiki/Desktop-applications).
## Built with
The Piskel editor is purely built in **JavaScript, HTML and CSS**. It uses Canvas extensively for displaying all them pretty sprites.
The Piskel editor is purely built in **JavaScript, HTML and CSS**.
We also use the following **libraries** :
* [spectrum](https://github.com/bgrins/spectrum) : awesome standalone colorpicker
* [gifjs](http://jnordberg.github.io/gif.js/) : generate animated GIFs in javascript, using webworkers
* [gifjs](https://jnordberg.github.io/gif.js/) : generate animated GIFs in javascript, using webworkers
* [supergif](https://github.com/buzzfeed/libgif-js) : modified version of SuperGif to parse and import GIFs
* [jszip](https://github.com/Stuk/jszip) : create, read and edit .zip files with Javascript
* [canvas-toBlob](https://github.com/eligrey/canvas-toBlob.js/) : shim for canvas toBlob
* [jquery](http://jquery.com/) : used sporadically in the application
* [bootstrap-tooltip](http://getbootstrap.com/javascript/#tooltips) : nice tooltips
* [jquery](https://jquery.com/) : used sporadically in the application
* [bootstrap-tooltip](https://getbootstrap.com/javascript/#tooltips) : nice tooltips
As well as some **icons** from the [Noun Project](http://thenounproject.com/) :
As well as some **icons** from the [Noun Project](https://thenounproject.com/) :
* Folder by Simple Icons from The Noun Project
* (and probably one or two others)
### Browser Support
Piskel supports the following browsers:
* **Chrome** (latest)
* **Firefox** (latest)
* **Edge** (latest)
* **Internet Explorer** 11
### Mobile/Tablets
There is no support for mobile.
### Offline builds
Offline builds are available. More details in the [dedicated wiki page](https://github.com/piskelapp/piskel/wiki/Desktop-applications).
## Contributing ?
Help is always welcome !
* **Issues** : Found a problem when using the application, want to request a feature, [open an issue](https://github.com/juliandescottes/piskel/issues).
* **Participate** : Have a look at the [wiki](https://github.com/juliandescottes/piskel/wiki) to set up the development environment
* **Issues** : Found a problem when using the application, want to request a feature, [open an issue](https://github.com/piskelapp/piskel/issues).
* **Development** : Have a look at the [wiki](https://github.com/piskelapp/piskel/wiki) to set up the development environment
## License
Copyright 2016 Julian Descottes
Copyright 2017 Julian Descottes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -83,7 +69,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Mobile/Tablets
There is no support for mobile for now.

32
RELEASE.md Normal file
View File

@@ -0,0 +1,32 @@
# Release instructions
- retrieve source code and dependencies
- clone piskel `git clone https://github.com/piskelapp/piskel`
- clone piskel website `git clone https://github.com/piskelapp/piskel-website`
- download the appengine SDK for python at [this url](https://cloud.google.com/appengine/docs/standard/python/download). It seems recent versions don't work for me on Windows. [GoogleAppEngine-1.9.67.msi](https://storage.cloud.google.com/appengine-sdks/featured/GoogleAppEngine-1.9.67.msi?_ga=2.6838962.-1257793585.1543157659) looks ok...
- prepare the release
- in `piskel-website` clone, checkout the `master` branch, not the `release`. The release branch is similar to the master branch, except it doesn't ignore the statics files coming from the `piskel` project. The idea is that we can easily checkout the release branch to do a new release, without having to rebuild piskel, in case nothing changed in piskel itself. We will switch to the release branch when we perform the final release.
- in `piskel` clone, create a new branch for the release `git checkout -b vX.Y`
- build and copy piskel to piskel-website (assumes the clones are in the same folder) `grunt && node bin/copy-to-piskel-website.js`
- local test
- start piskel-website in the Google app engine launcher, test manually the update
- if any issue is detected create a commit to fix it (on the `vX.Y` branch) and push it.
- beta test
- check the version in app.yaml is set to 'beta'. For historical reasons, alpha is the "production" version, while beta is the ... beta version. Don't ask.
- in the google app engine launcher, deploy this version.
- go to https://beta-dot-piskel-app.appspot.com and test (while this is not production frontend, it shares the same database, so be careful with what you create and delete)
- if any issue is detected create a commit to fix it (on `master`) and push it.
- check caches...
- If any icon was modified or any script of piskel-website was modified, there's no nice way to clean the cache on each release... so we just put a time stamp in the requests. eg `background-image: url(../img/icons@2x.png?20181125);` or `<script type="text/javascript" src="/static/js/piskel-animated-preview.js?20181124"></script>`. Erk.
- finalize the release
- in `piskel` update version in package.json. Remove the "-SNAPSHOT" at the end and commit the change, with a commit message such as `release: bump version to vX.Y`.
- in `piskel-website` checkout the `release` branch. Rebase it on master (that's pretty bad, we should probably cherry pick all the changes between the two branches...)
- once again build and copy piskel to piskel-website
- in `piskel-website` run `git status` to check that there are a bunch of changes to commit. (test locally again if you are paranoid)
- in `piskel-website` commit the current changes with a commit message such as `update statics for release vX.Y`
- Check that the version in app.yaml is now set to alpha. Deploy. Pray.
- post release
- in piskel-website push the release branch to github
- in piskel add a last commit to update the version in package.json to update the version to `vX+1.0-SNAPSHOT`
- create a tag on github

View File

@@ -0,0 +1,84 @@
const rmdir = require('rmdir');
const path = require('path');
const fs = require('fs');
const fse = require('fs-extra');
const PISKEL_PATH = path.resolve(__dirname, '..');
const PISKELAPP_PATH = path.resolve(__dirname, '../../piskel-website');
var pjson = require('../package.json');
// Callbacks sorted by call sequence.
function onCopy(err) {
if (err) {
console.error('Failed to copy static files...');
return console.error(err);
}
console.log('Copied static files to piskel-website...');
let previousPartialPath = path.resolve(PISKELAPP_PATH, 'templates/editor/main-partial.html');
fs.access(previousPartialPath, fs.constants.F_OK, function (err) {
if (err) {
// File does not exit, call next step directly.
console.error('Previous main partial doesn\'t exist yet.');
onDeletePreviousPartial();
} else {
// File exists, try to delete it before moving on.
fs.unlink(previousPartialPath, onDeletePreviousPartial);
}
})
}
function onDeletePreviousPartial(err) {
if (err) {
console.error('Failed to delete previous main partial...');
return console.error(err);
}
console.log('Previous main partial deleted...');
fse.copy(
path.resolve(PISKELAPP_PATH, "static/editor/piskelapp-partials/main-partial.html"),
path.resolve(PISKELAPP_PATH, "templates/editor/main-partial.html"),
onCopyNewPartial
);
}
function onCopyNewPartial(err) {
if (err) {
console.error('Failed to delete previous main partial...');
return console.error(err);
}
console.log('Main partial copied...');
rmdir(
path.resolve(PISKELAPP_PATH, "static/editor/piskelapp-partials/"),
onDeleteTempPartial
);
}
function onDeleteTempPartial(err) {
if (err) {
console.error('Failed to delete temporary main partial...');
return console.error(err);
}
console.log('Temporary main partial deleted...');
fs.writeFile(path.resolve(PISKELAPP_PATH, "static/editor/VERSION"), pjson.version, onVersionFileCreated);
}
function onVersionFileCreated(err) {
if (err) {
console.error('Failed to create temporary main partial...');
return console.error(err);
}
console.log('Version file created...');
console.log('Finished!');
}
fse.copy(
path.resolve(PISKEL_PATH, "dest/prod"),
path.resolve(PISKELAPP_PATH, "static/editor"),
onCopy
);

64
cli/README.md Normal file
View File

@@ -0,0 +1,64 @@
# Piskel CLI
Wraps the Piskel pixel editing application to enable similar export options via the command line.
## Installation
Option 1: Globally install Piskel
```
npm install -g https://github.com/piskelapp/piskel/tarball/master
```
Option 2: Clone and install Piskel normally and then run npm link inside the installation root
## Usage
**Export provided .piskel file as a png sprite sheet using app defaults**
```
piskel-cli snow-monster.piskel
```
**Export scaled sprite sheet**
```
piskel-cli snow-monster.piskel --scale 5
```
**Export scaled to specific (single frame) width value**
```
piskel-cli snow-monster.piskel --scaledWidth 435
```
**Export scaled to specific (single frame) height value**
```
piskel-cli snow-monster.piskel --scaledHeight 435
```
**Export sprite sheet as a single column**
```
piskel-cli snow-monster.piskel --columns 1
```
**Export sprite sheet as a single row**
```
piskel-cli snow-monster.piskel --rows 1
```
**Export a single frame (0 is first frame)**
```
piskel-cli snow-monster.piskel --frame 3
```
**Export a second file containing the data-uri for the exported png**
```
piskel-cli snow-monster.piskel --dataUri
```
**Export cropped**
```
piskel-cli snow-monster.piskel --crop
```
**Custom output path and/or filename**
```
piskel-cli snow-monster.piskel --dest ./output-folder/snah-monstah.png
```

130
cli/export-png.js Normal file
View File

@@ -0,0 +1,130 @@
const fs = require('fs');
function onPageEvaluate(window, options, piskel) {
console.log("\nPiskel name: " + piskel.descriptor.name);
// Setup piskelController
var piskelController = new pskl.controller.piskel.PiskelController(piskel);
pskl.app.piskelController = piskelController;
piskelController.init();
// Apply crop if enabled
if (options.crop) {
// Mock selection manager to avoid errors during crop
pskl.app.selectionManager = {};
// Setup crop tool
var crop = new pskl.tools.transform.Crop();
// Perform crop
crop.applyTransformation();
// Get cropped piskel
piskel = piskelController.getPiskel();
}
// Mock exportController to provide zoom value based on cli args
// and to avoid errors and/or unnecessary bootstrapping
var exportController = {
getExportZoom: function () {
var zoom = options.zoom;
if (options.scaledWidth) {
zoom = options.scaledWidth / piskel.getWidth();
} else if (options.scaledHeight) {
zoom = options.scaledHeight / piskel.getHeight();
}
return zoom;
}
};
// Setup pngExportController
var pngExportController = new pskl.controller.settings.exportimage.PngExportController(piskelController, exportController);
// Mock getColumns and getRows to use values from cli arguments
pngExportController.getColumns_ = function () {
if (options.columns) return options.columns;
if (options.rows) {
return Math.ceil(piskelController.getFrameCount() / pngExportController.getRows_());
} else {
return pngExportController.getBestFit_();
}
};
pngExportController.getRows_ = function () {
if (options.columns && !options.rows) {
return Math.ceil(piskelController.getFrameCount() / pngExportController.getColumns_());
}
return options.rows;
};
// Render to output canvas
var canvas;
if (options.frame > -1) {
// Render a single frame
canvas = piskelController.renderFrameAt(options.frame, true);
var zoom = exportController.getExportZoom();
if (zoom != 1) {
// Scale rendered frame
canvas = pskl.utils.ImageResizer.resize(canvas, canvas.width * zoom, canvas.height * zoom, false);
}
} else {
// Render the sprite sheet
canvas = pngExportController.createPngSpritesheet_();
}
// Add output canvas to DOM
window.document.body.appendChild(canvas);
// Prepare return data
const returnData = {
width: canvas.width,
height: canvas.height
};
// Wait a tick for things to wrap up
setTimeout(function () {
// Exit and pass data to parent process
window.callPhantom(returnData);
}, 0);
}
function onPageExit(page, options, data) {
// Set clip for output image
if (data.width && data.height) {
page.clipRect = { top: 0, left: 0, width: data.width, height: data.height };
}
console.log("\n" + 'Generated file(s):');
const dest = options.dest.replace('.png', '') + '.png';
// Render page to the output image
page.render(dest);
console.log(" " + dest);
if (options.dataUri) {
const dataUriPath = options.dest + '.datauri';
const dataUri = 'data:image/png;base64,' + page.renderBase64('PNG');
// Write data-uri to file
fs.write(dataUriPath, dataUri, 'w');
console.log(" " + dataUriPath);
}
}
module.exports = {
onPageEvaluate: onPageEvaluate,
onPageExit: onPageExit
};

93
cli/index.js Normal file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const minimist = require('minimist');
const childProcess = require('child_process');
const phantomjs = require('phantomjs');
const binPath = phantomjs.path;
// Parse command args
let args = minimist(process.argv.slice(2), {
default: {
crop: false,
dataUri: false,
debug: false,
scale: 1
},
});
if (args.debug) console.log(args);
// Ensure a path for the src file was passed
if (!args._ || (args._ && !args._.length)) {
console.error('Path to a .piskel file is required');
return;
}
const src = args._[0];
// Ensure the src file exists
if (!fs.existsSync(src)) {
console.error('No such file: ' + src);
return;
}
// Read src piskel file
const piskelFile = fs.readFileSync(src, 'utf-8');
const dest = args.dest || path.basename(src, '.piskel');
console.log('Piskel CLI is exporting...');
// Get path to Piskel's app js bundle
let piskelAppJsDir = path.resolve(__dirname +'/../dest/prod/js/');
let minJsFiles = fs.readdirSync(piskelAppJsDir).filter(filename => filename.indexOf('min') > -1);
let piskelAppJsFileName = minJsFiles[0];
let piskelAppJsPath = (piskelAppJsFileName) ? path.join(piskelAppJsDir, piskelAppJsFileName) : '';
if (!fs.existsSync(piskelAppJsPath)) {
console.error(`Piskel's application JS file not found in: ${piskelAppJsDir}. Run prod build and try again.`);
return;
}
// Prepare args to pass to phantom script
const options = {
dest: dest,
zoom: args.scale,
crop: !!args.crop,
rows: args.rows,
columns: args.columns,
frame: args.frame,
dataUri: !!args.dataUri,
debug: args.debug,
piskelAppJsPath: piskelAppJsPath,
scaledWidth: args.scaledWidth,
scaledHeight: args.scaledHeight
};
const childArgs = [
path.join(__dirname, 'piskel-export.js'),
piskelFile,
JSON.stringify(options)
];
if (args.debug) {
childArgs.unshift(
'--remote-debugger-port=9035',
'--remote-debugger-autorun=yes'
);
}
// Run phantom script
childProcess.execFile(binPath, childArgs, function (err, stdout, stderr) {
// Print any output the from child process
if (err) console.log(err);
if (stderr) console.log(stderr);
if (stdout) console.log(stdout);
console.log('Export complete');
});

45
cli/piskel-export.js Normal file
View File

@@ -0,0 +1,45 @@
// PhantomJS system
const system = require('system');
// Exporter
const exporter = require('./export-png');
// Get passed args
const args = system.args;
// Parse input piskel file and options
const piskelFile = JSON.parse(args[1]);
const options = JSON.parse(args[2]);
// Create page w/ canvas
const page = require('webpage').create();
page.content = '<html><body></body></html>';
// Inject Piskel JS
page.injectJs(options.piskelAppJsPath);
// Listen for page console logs
page.onConsoleMessage = function (msg) {
console.log(msg);
};
// Run page logic
page.evaluate(function (piskelFile, options, onPageEvaluate) {
// Zero out default body margin
document.body.style.margin = 0;
// Deserialize piskel file and run exporter's page evaluate task
pskl.utils.serialization.Deserializer.deserialize(piskelFile, function (piskel) {
onPageEvaluate(window, options, piskel);
});
}, piskelFile, options, exporter.onPageEvaluate);
// Wait for page to trigger exit
page.onCallback = function (data) {
// Run exporter page exit task
exporter.onPageExit(page, options, data);
// Exit
phantom.exit(0);
};

View File

@@ -8,7 +8,10 @@ module.exports = function(config) {
var piskelScripts = require('./src/piskel-script-list.js').scripts.map(mapToSrcFolder);
piskelScripts.push('test/js/testutils/**/*.js');
piskelScripts.push('test/js/**/*.js');
// Polyfill for Object.assign (missing in PhantomJS)
piskelScripts.push('./node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js');
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
@@ -21,7 +24,9 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: piskelScripts,
files: piskelScripts.concat([
'./node_modules/promise-polyfill/promise.js'
]),
// list of files to exclude

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="90"
height="90"
viewBox="0 0 89.999997 90"
enable-background="new 0 0 89.231 100"
xml:space="preserve"
inkscape:version="0.92.1 r15371"
sodipodi:docname="common-backup.svg"
inkscape:export-filename="C:\Development\git\piskel\misc\icons\source\tool-rotate.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"><metadata
id="metadata15"><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><defs
id="defs13" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1148"
id="namedview11"
showgrid="false"
inkscape:zoom="7.75"
inkscape:cx="13.031976"
inkscape:cy="43.272537"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" /><g
id="g3760"
transform="matrix(0,-0.97677741,0.97203982,0,-2.1261998,91.355253)"
style="fill:#ff00ff;fill-opacity:1"><path
style="fill:#ff00ff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path3"
d="m 29.229405,55.37008 c -0.387431,-1.333059 -0.642506,-2.72161 -0.738881,-4.152895 h -8.675106 c 0.115651,2.460738 0.552554,4.838559 1.260594,7.099021 z" /><path
style="fill:#ff00ff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path5"
d="m 29.023802,70.783821 5.579515,-6.601516 c -1.862622,-1.780814 -3.387929,-3.907969 -4.44999,-6.287065 l -8.152106,2.946124 c 1.604978,3.800815 4.017584,7.185766 7.022581,9.942457 z" /><path
style="fill:#ff00ff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path7"
d="m 47.110967,69.703978 c -3.887799,-0.260871 -7.469766,-1.6322 -10.437498,-3.790608 l -5.577588,6.598963 c 4.487901,3.403448 10.011517,5.524225 16.015086,5.803594 z" /><path
style="fill:#ff00ff;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0"
id="path9"
d="M 48.464084,21.400659 V 14.532532 L 28.981398,25.698341 48.464084,36.86415 v -6.867489 c 11.042093,0 20.024317,8.91683 20.024317,19.877897 0,10.509484 -8.258763,19.134189 -18.671845,19.828145 v 8.611948 c 15.190751,-0.703524 27.330245,-13.189635 27.330245,-28.440093 0,-15.700763 -12.86681,-28.473899 -28.682717,-28.473899 z" /></g><g
id="g4513"
transform="translate(0,-2)"><rect
y="32.516129"
x="42"
height="15.612903"
width="7.9999986"
id="rect4494"
style="fill:#ff00f7;fill-opacity:1;stroke:#ffffed;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6.04534006;stroke-opacity:1" /><rect
transform="rotate(120)"
y="-76.050484"
x="12.680965"
height="15.612903"
width="7.9999986"
id="rect4494-7"
style="fill:#ff00f7;fill-opacity:1;stroke:#ffffed;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:6.04534006;stroke-opacity:1" /></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="42"
height="42"
viewBox="0 0 41.999999 41.999999"
enable-background="new 0 0 99.997 69.373"
xml:space="preserve"
inkscape:version="0.48.4 r9939"
sodipodi:docname="common-warning-red.svg"
inkscape:export-filename="C:\Development\git\piskel\misc\icons\source\tool-move.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"><metadata
id="metadata9"><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><defs
id="defs7" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1148"
id="namedview5"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="85.612634"
inkscape:cy="3.0742543"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 21,4.2499995 c -0.868171,0 -1.517453,0.2705716 -2,1.03125 L 3.9999999,34.999999 c -0.6703157,1.211185 0.6156981,2.999959 2,3 l 29.9999991,0 c 1.377219,0.0098 2.645421,-1.78334 2,-3 l -15,-29.6874995 C 22.632848,4.6114627 21.868171,4.2499995 21,4.2499995 z m 0,6.2187495 11.999999,23.53125 -23.9999992,0 z"
id="rect3765"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zcccccczcccc" /><path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 20.572432,16.003047 c -0.858253,0.109012 -1.577503,1.040604 -1.572402,2.036618 L 20,25.963381 c 9.2e-5,1.066342 -0.158856,2.036512 0.765534,2.036618 l 0.468961,0 c 0.92439,-1.06e-4 0.765412,-0.970276 0.765504,-2.036618 l 1,-7.923716 c -9.2e-5,-1.066342 -0.841114,-2.036512 -1.765504,-2.036618 l -0.468961,0 c -0.0643,-0.0041 -0.128799,-0.0041 -0.193102,0 z"
id="rect3772"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" /><path
style="fill:#ff0000;fill-opacity:1;stroke:#00ffff;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:1.60000000000000010"
d="m 20.999298,29.000086 c 0.620953,-0.006 0.971639,0.298697 0.999273,1.499911 0.02763,1.201212 -0.347092,1.493936 -0.999273,1.499909 -0.65218,0.006 -1.002864,-0.275261 -0.999271,-1.499909 0.0036,-1.22465 0.378318,-1.493938 0.999271,-1.499911 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzzzz" /></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -20,9 +20,9 @@
xml:space="preserve"
inkscape:version="0.48.4 r9939"
sodipodi:docname="tool-lasso-select.svg"
inkscape:export-filename="C:\Development\git\piskel\misc\icons\source\tool-lasso-select@2x.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><metadata
inkscape:export-filename="C:\Development\git\piskel\misc\icons\source\tool-lasso-select.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"><metadata
id="metadata9"><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><defs
@@ -39,22 +39,17 @@
inkscape:window-height="1148"
id="namedview5"
showgrid="false"
inkscape:zoom="11.313709"
inkscape:cx="28.848556"
inkscape:cy="56.05112"
inkscape:zoom="5.6568543"
inkscape:cx="53.41565"
inkscape:cy="19.716081"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:5.99999987, 5.99999987;stroke-dashoffset:9.59999979"
d="m 27.137305,45.116922 c 4.348192,3.354775 13.757306,5.64287 20.485225,5.05984 6.727919,-0.583031 15.989555,-2.799751 19.954403,-8.454605 3.964848,-5.654854 2.6921,-13.891707 -3.122398,-15.860913 -6.608117,-2.237981 -9.882928,4.099594 -19.471426,4.899951 -7.474124,0.623869 -14.014171,-4.834533 -18.728321,-1.630028 -7.360138,5.003149 -3.465675,12.63098 0.882517,15.985755 z"
style="fill:none;stroke:#ffffff;stroke-width:3.99999976000000010;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:7.99999982000000020, 3.99999991000000010;stroke-dashoffset:1.59999997000000000"
d="M 63.459007,62.898551 C 51.21203,69.659898 34.408658,68.826355 23.032272,56.955855 11.655886,45.085355 16.081011,27.22439 25.257464,25.049087 c 9.176453,-2.175302 10.165996,14.382407 20.36105,14.647508 10.195054,0.265101 11.555041,-13.986139 23.446941,-11.490831 11.8919,2.495308 6.640529,27.93144 -5.606448,34.692787 z"
id="path4945"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zszsssz" /><path
style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 26.563739,67.114661 C 33.855127,59.408496 44.134234,57.708412 44.506573,51.469924"
id="path4947"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /></svg>
sodipodi:nodetypes="zzzzzz" /></svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -25,7 +25,7 @@
inkscape:export-ydpi="90"><metadata
id="metadata9"><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><defs
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs7" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
@@ -40,7 +40,7 @@
id="namedview5"
showgrid="false"
inkscape:zoom="8.9380977"
inkscape:cx="27.470446"
inkscape:cx="8.8982615"
inkscape:cy="50.702772"
inkscape:window-x="-8"
inkscape:window-y="-8"
@@ -49,7 +49,7 @@
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="M 54.920882,32.150851 23.207014,63.864718 c 0,0 -1.426625,3.647594 -0.07284,5.00138 1.353787,1.353786 5.00138,-0.07284 5.00138,-0.07284 L 59.849422,37.07939 c 0,0 1.426626,-3.647593 0.07284,-5.001379 -1.353786,-1.353786 -5.00138,0.07284 -5.00138,0.07284 z m -2.537109,5.074219 c 0,0 1.701964,-0.835146 2.46427,-0.07284 0.762306,0.762306 -0.07284,2.464269 -0.07284,2.464269 l -26.639649,26.63965 c 0,0 -1.701963,0.835146 -2.464269,0.07284 -0.762306,-0.762305 0.07284,-2.464269 0.07284,-2.464269 z"
d="M 54.920882,32.150851 23.207015,63.864718 c 0,0 -1.426626,3.647594 -0.07284,5.001381 1.353787,1.353785 5.001381,-0.07284 5.001381,-0.07284 L 59.849423,37.07939 c 0,0 1.426625,-3.647592 0.07284,-5.001379 -1.353786,-1.353785 -5.00138,0.07284 -5.00138,0.07284 z m -4.969979,8.298204 c 0,0 1.306407,-1.230703 2.068713,-0.468398 0.762306,0.762307 -0.468398,2.068712 -0.468398,2.068712 L 27.739997,65.860591 c 0,0 -1.306406,1.230704 -2.068712,0.468398 -0.762306,-0.762305 0.468398,-2.068712 0.468398,-2.068712 z"
id="rect4410"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cczcczcczcczcc" /><path

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,21 +0,0 @@
@ECHO off
SETLOCAL
SET PISKEL_PATH="C:\Development\git\piskel"
SET PISKELAPP_PATH="C:\Development\git\piskel-website"
ECHO "Copying files to piskelapp"
XCOPY "%PISKEL_PATH%\dest\prod" "%PISKELAPP_PATH%\static\editor" /e /i /h /y
ECHO "Delete previous partial"
DEL "%PISKELAPP_PATH%\templates\editor\main-partial.html"
ECHO "Copy new partial"
MOVE "%PISKELAPP_PATH%\static\editor\piskelapp-partials\main-partial.html" "%PISKELAPP_PATH%\templates\editor"
ECHO "Delete temp partial"
RMDIR "%PISKELAPP_PATH%\static\editor\piskelapp-partials\" /S /Q
PAUSE
explorer "%PISKELAPP_PATH%\"
ENDLOCAL

View File

@@ -1,63 +1,77 @@
{
"name": "piskel",
"version": "0.8.1",
"version": "0.15.2-SNAPSHOT",
"description": "Pixel art editor",
"author": "Julian Descottes <julian.descottes@gmail.com>",
"contributors": [
"Vincent Renaudin"
],
"homepage": "http://github.com/juliandescottes/piskel",
"homepage": "http://github.com/piskelapp/piskel",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "http://github.com/juliandescottes/piskel.git"
"url": "http://github.com/piskelapp/piskel.git"
},
"files": [
"dest/prod",
"misc/scripts/piskel-root"
],
"bin": {
"piskel-root": "./misc/scripts/piskel-root"
"piskel-root": "./misc/scripts/piskel-root",
"piskel-cli": "./cli/index.js"
},
"main": "./dest/prod/index.html",
"scripts": {
"test": "grunt test",
"start": "nodewebkit",
"preversion": "grunt test-local build",
"postversion": "git push && git push --tags && npm publish"
"dev": "grunt play",
"start": "grunt build && nw",
"preversion": "grunt test build",
"postversion": "git push && git push --tags && npm publish",
"release": "grunt && node ./bin/copy-to-piskel-website",
"build": "grunt desktop",
"build:mac": "grunt desktop-mac",
"format": "grunt eslint --fix"
},
"devDependencies": {
"dateformat": "1.0.11",
"grunt": "^0.4.5",
"grunt-contrib-clean": "1.0.0",
"dateformat": "4.5.1",
"fs-extra": "10.0.0",
"grunt": "1.4.1",
"grunt-casperjs": "^2.2.1",
"grunt-cli": "^1.4.3",
"grunt-contrib-clean": "2.0.0",
"grunt-contrib-concat": "1.0.1",
"grunt-contrib-connect": "1.0.2",
"grunt-contrib-connect": "3.0.0",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-uglify": "1.0.1",
"grunt-contrib-watch": "1.0.0",
"grunt-ghost": "1.1.0",
"grunt-include-replace": "4.0.1",
"grunt-jscs": "2.8.0",
"grunt-karma": "1.0.0",
"grunt-contrib-jshint": "3.0.0",
"grunt-contrib-uglify": "5.0.1",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "23.0.0",
"grunt-include-replace": "5.0.0",
"grunt-jscs": "3.0.1",
"grunt-karma": "4.0.2",
"grunt-leading-indent": "0.2.0",
"grunt-nw-builder": "2.0.3",
"grunt-open": "0.2.3",
"grunt-replace": "1.0.1",
"grunt-spritesmith": "6.3.0",
"jasmine-core": "2.1.0",
"karma": "0.13.21",
"karma-chrome-launcher": "1.0.1",
"karma-jasmine": "1.0.2",
"karma-phantomjs-launcher": "0.2.3",
"load-grunt-tasks": "3.5.0",
"phantomjs": "1.9.19"
"grunt-nw-builder": "3.1.0",
"grunt-replace": "2.0.2",
"grunt-spritesmith": "^6.9.0",
"jasmine-core": "3.8.0",
"karma": "6.3.4",
"karma-jasmine": "4.0.1",
"karma-phantomjs-launcher": "1.0.4",
"load-grunt-tasks": "5.1.0",
"nw": "0.54.0",
"phantomjs": "2.1.7",
"phantomjs-polyfill-object-assign": "0.0.2",
"promise-polyfill": "8.2.0",
"rmdir": "1.2.0"
},
"window": {
"title": "Piskel",
"icon": "dest/logo.png",
"icon": "dest/prod/logo.png",
"toolbar": false,
"width": 1000,
"height": 500
"height": 700
},
"dependencies": {
"minimist": "^1.2.5"
}
}

View File

@@ -1,3 +1,9 @@
@keyframes fade {
50% { opacity: 0.5; }
}
@keyframes glow {
0% { opacity: 0.66; }
50% { opacity: 1; }
100% { opacity: 0.66; }
}

View File

@@ -0,0 +1,152 @@
#dialog-container.browse-backups {
width: 700px;
height: 500px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -350px;
}
.backups-step-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.backups-step-content {
width: 100%;
height: 10px;
flex-grow: 1;
background: #444;
padding: 20px;
overflow: auto;
box-sizing: border-box;
}
.backups-step-actions {
flex-grow: 0;
flex-shrink: 1;
height: 60px;
display: flex;
align-items: center;
padding: 0 20px;
}
.show #dialog-container.browse-backups {
margin-top: -250px;
}
.browse-backups .browse-backups-disclaimer {
display: flex;
margin-bottom: 20px;
align-items: center;
}
.browse-backups .browse-backups-disclaimer-content {
padding: 0 20px;
font-size: 13px;
}
.browse-backups .browse-backups-disclaimer .backups-icon {
border: 1px solid gold;
flex-shrink: 0;
width: 90px;
height: 90px;
}
.browse-backups .centered-message {
position: absolute;
left: 50%;
width: 200px;
margin-top: 100px;
margin-left: -130px;
padding: 30px;
font-size: 16px;
text-align: center;
border: 1px solid;
}
.browse-backups .session-list-empty,
.browse-backups .snapshot-list-empty {
color: #bbb;
}
.browse-backups .session-list-error,
.browse-backups .snapshot-list-error {
color: white;
}
.browse-backups .session-item {
/* Transition duration should be kept in sync with SelectSession.DELETE_TRANSITION_DURATION */
transition: all 500ms;
}
/* Hide and slide up next sessions when deleting an item */
.browse-backups .session-item.deleting {
opacity: 0;
margin-bottom: -60px;
}
.browse-backups .session-item,
.browse-backups .snapshot-item {
display: flex;
align-items: center;
width: 100%;
height: 80px;
margin-bottom: 10px;
padding: 0 20px;
border: 1px solid #666;
box-sizing: border-box;
}
.browse-backups .snapshot-preview {
flex-grow: 0;
flex-shrink: 1;
/* Keep synced with SessionDetails.PREVIEW_SIZE */
height: 60px;
width: 60px;
margin-right: 20px;
}
.browse-backups .session-details,
.browse-backups .snapshot-details {
flex-grow: 1;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.browse-backups .session-details-title,
.browse-backups .snapshot-details-title {
font-size: 13px;
}
.browse-backups .session-details-info,
.browse-backups .snapshot-details-info {
font-size: 11px;
color: #bbb;
line-height: 1.5em;
}
.browse-backups .session-actions,
.browse-backups .snapshot-actions {
flex-grow: 0;
flex-shrink: 1;
display: flex;
}
.browse-backups .session-actions button,
.browse-backups .snapshot-actions button {
margin-left: 10px;
}
.browse-backups .session-item:last-child,
.browse-backups .snapshot-item:last-child {
margin-bottom: 0;
}

View File

@@ -3,6 +3,19 @@
/* Browse local piskels panel */
/************************************************************************************************/
#dialog-container.browse-local {
width: 700px;
height: 500px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -350px;
}
.show #dialog-container.browse-local {
margin-top: -250px;
}
.local-piskel-list {
width: 100%;
}
@@ -29,7 +42,7 @@
.local-piskel-list-head {
font-weight: bold;
color: gold;
color: var(--highlight-color);
}
.local-piskel-load-button,

View File

@@ -3,7 +3,7 @@
bottom: 10px;
left: 10px;
color : gold;
color : var(--highlight-color);
font-weight: bold;
font-size : 1.25em;
line-height: 20px;
@@ -97,7 +97,7 @@
border-radius: 2px;
text-align: center;
font-family:Courier;
font-family: monospace;
font-weight: bold;
font-size : 18px;
color: white;
@@ -113,8 +113,8 @@
}
.cheatsheet-shortcut-editable .cheatsheet-key {
border-color: gold;
color: gold;
border-color: var(--highlight-color);
color: var(--highlight-color);
}
.cheatsheet-shortcut-editing .cheatsheet-key {
@@ -140,7 +140,7 @@
padding : 10px;
overflow: hidden;
background-color : gold;
background-color : var(--highlight-color);
}
.cheatsheet-helptext {

View File

@@ -103,7 +103,7 @@
transition : border-color 0.2s;
}
.create-palette-color:hover {
border:1px solid gold;
border:1px solid var(--highlight-color);
}
.colors-list-drop-proxy {
@@ -111,17 +111,17 @@
}
.create-palette-new-color {
border:2px dotted gold;
border:2px dotted var(--highlight-color);
border-radius: 2px;
line-height: 40px;
text-align: center;
font-size: 20px;
color: gold;
color: var(--highlight-color);
}
.create-palette-color.selected {
border:2px solid gold;
border:2px solid var(--highlight-color);
}
.create-palette-remove-color {

View File

@@ -1,101 +0,0 @@
/************************************************************************************************/
/* Import dialog */
/************************************************************************************************/
#dialog-container.import-image {
width: 550px;
height: 360px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -250px;
}
.show #dialog-container.import-image {
margin-top: -150px;
}
.import-subsection {
margin-left: 25px;
}
.import-section:not(.import-subsection) > .dialog-section-title {
width: 50px;
}
.import-section-preview-title {
position: absolute;
margin-left: 50%;
margin-top: -28px;
}
.import-section-preview {
position: absolute;
display: inline-block;
border: 1px dashed #999;
border-radius: 3px;
margin-left: 50%;
}
.import-section-preview img {
max-width: 220px;
max-height: 220px;
display: block;
}
.import-section-preview.no-border {
border-color: transparent;
}
.import-section-preview canvas {
position: absolute;
left: 0;
top: 0;
}
.dialog-section-title {
display : inline-block;
width: 80px;
}
.dialog-section-radio {
margin-top: 15px;
vertical-align: sub;
}
.import-size-field:nth-of-type(2) {
margin-left: 5px;
}
.import-image-file-name {
display: inline-block;
overflow: hidden;
width: 200px;
vertical-align: middle;
word-break : break-all;
white-space: nowrap;
text-overflow: ellipsis;
font-style: italic;
font-weight: normal;
text-shadow: none;
color: gold;
}
[name=smooth-resize-checkbox] {
margin : 0 8px;
}
.dialog-import-body {
padding: 10px 20px;
font-size:1.3em
}
.import-button {
font-size: 1em;
height: 28px;
padding: 0px 10px;
margin-top: 15px;
}

288
src/css/dialogs-import.css vendored Normal file
View File

@@ -0,0 +1,288 @@
#dialog-container.import {
width: 500px;
height: 350px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -250px;
margin-top: -175px;
}
.import .dialog-content {
font-size: 1.3em;
}
.import-step-container {
display: flex;
width: 100%;
height: 100%;
box-sizing: border-box;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5);
background: #444;
}
.import-step-content {
padding: 10px;
}
.import-step-buttons {
position: absolute;
bottom: 10px;
right: 10px;
text-align: right;
}
.import-first-step .import-back-button {
display: none;
}
/**
* IMAGE IMPORT STEP
*/
.import-image-container {
padding: 10px;
}
.import-image-loading {
opacity: 0.3;
pointer-events: none;
}
.import-image-loading::after {
content: 'loading image';
position: absolute;
width: 100%;
top: 0;
left: 0;
margin-top: 110px;
text-align: center;
font-size: 3em;
color: white;
text-shadow: 0 0 60px black;
}
.import-subsection {
margin-left: 25px;
}
.import-section:not(.import-subsection) > .dialog-section-title {
width: 50px;
}
.import-section-preview-title {
position: absolute;
margin-left: 50%;
margin-top: -28px;
}
.import-section-preview {
position: absolute;
display: inline-block;
border: 1px dashed #999;
border-radius: 3px;
margin-left: 50%;
top: 10px;
width: 220px;
height: 220px;
display: flex;
align-items: center;
justify-content: center;
}
.import-section-preview img {
max-width: 100%;
max-height: 100%;
display: block;
}
.import-section-preview canvas {
position: absolute;
}
.dialog-section-title {
display : inline-block;
width: 80px;
}
.dialog-section-radio {
margin-top: 15px;
vertical-align: sub;
}
.import-size-field:nth-of-type(2) {
margin-left: 5px;
}
.import-image-file-name {
display: inline-block;
overflow: hidden;
width: 200px;
vertical-align: middle;
word-break : break-all;
white-space: nowrap;
text-overflow: ellipsis;
font-style: italic;
font-weight: normal;
text-shadow: none;
color: var(--highlight-color);
}
[name=smooth-resize-checkbox] {
margin : 0 8px;
}
.dialog-import-body {
padding: 10px 20px;
font-size:1.3em
}
/**
* SELECT MODE
*/
.import-info {
display: flex;
flex-direction: column;
height: 100%;
max-width: 178px;
box-sizing: border-box;
padding: 10px;
border-right: 3px solid gold;
}
.import-preview canvas {
max-width: 100%;
max-height: 100%;
}
.import-meta {
margin-top: 10px;
box-sizing: border-box;
/*center meta information horizontally*/
display: flex;
flex-direction: column;
justify-content: center;
}
.import-meta > div {
height: 22px;
display: flex;
margin-bottom: 5px;
}
.import-meta-value,
.import-meta-label {
padding: 2px 4px;
}
.import-meta-label {
border-radius: 2px 0 0 2px;
color: var(--highlight-color);
}
.import-meta-value {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.import-missing {
text-align: center;
line-height: 70px;
font-style: italic;
color: #aaa;
}
.import-mode-title {
margin-bottom: 10px
}
.import-mode-section {
display: flex;
border: 3px solid #666;
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
align-items: center;
}
.import-mode-section .button {
width: 75px;
height: 30px;
font-size: 14px;
margin-left: 10px;
flex-grow: 0;
flex-shrink: 0;
}
.import-mode-section-description {
flex-grow: 1;
}
.import-resize-option,
.insert-mode-option {
display: flex;
align-items: center;
margin: 5px 0;
}
.import-resize-option :checked + span,
.insert-mode-option :checked + span {
color: var(--highlight-color);
}
.import-resize-option input,
.insert-mode-option input {
margin: 5px;
}
/**
* ADJUST SIZE
*/
.import-resize-anchor-info {
margin-bottom: 10px;
}
.import-resize-section {
margin-bottom: 10px;
}
.import-resize-anchor {
margin-top: 20px;
}
.import-resize-option :checked + span {
color: var(--highlight-color);
}
.import-resize-warning {
color: var(--highlight-color);
}
/**
* INSERT LOCATION
*/
.insert-mode-container {
margin-top: 20px;
margin-bottom: 10px;
}
.insert-frame-preview {
margin: 10px 0;
}
.insert-frame-preview .frame-picker-wrapper {
height: 120px;
}

View File

@@ -0,0 +1,68 @@
.performance-link {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 11000;
cursor: pointer;
opacity: 0;
transition : opacity 0.3s;
}
.performance-link.visible {
display: block;
opacity: 0.66;
animation: glow 2s infinite;
}
.performance-link.visible:hover {
opacity: 1;
animation: none;
}
#dialog-container.performance-info {
width: 500px;
height: 525px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -250px;
margin-top: -260px;
}
.dialog-performance-info-body {
font-size: 13px;
letter-spacing: 1px;
padding: 10px 20px;
}
.dialog-performance-info-body ul {
border: 1px solid #666;
padding: 5px;
border-radius: 3px;
}
.dialog-performance-info-body li {
list-style-type: initial;
margin: 0 20px;
}
.dialog-performance-info-body sup {
color: var(--highlight-color);
cursor: pointer;
}
.show #dialog-container.performance-info {
margin-top: -300px;
}
.dialog-performance-info-body .warning-icon {
float: left;
margin-top: 10px;
}
.dialog-performance-info-body .warning-icon-info {
overflow: hidden;
margin-left: 30px;
}

View File

@@ -0,0 +1,32 @@
/************************************************************************************************/
/* Unsupported browser dialog */
/************************************************************************************************/
#dialog-container.unsupported-browser {
width: 600px;
height: 260px;
top : 50%;
left : 50%;
position : absolute;
margin-top: -130px;
margin-left: -300px;
}
.unsupported-browser .dialog-content {
font-size:1.2em;
letter-spacing: 1px;
padding:10px 20px;
overflow: auto;
}
.unsupported-browser .supported-browser-list {
padding: 5px 20px;
}
.unsupported-browser .supported-browser-list li {
list-style-type: square;
}
#current-user-agent {
color: var(--highlight-color);
}

View File

@@ -39,7 +39,7 @@
-moz-box-sizing : border-box;
border-radius: 3px;
border : 3px solid gold;
border : 3px solid var(--highlight-color);
background: #444;
overflow: auto;
}
@@ -48,19 +48,6 @@
margin-top: 0;
}
#dialog-container.browse-local {
width: 700px;
height: 500px;
top : 50%;
left : 50%;
position : absolute;
margin-left: -350px;
}
.show #dialog-container.browse-local {
margin-top: -250px;
}
.dialog-wrapper {
height: 100%;
position : relative;
@@ -76,7 +63,7 @@
.dialog-head {
width: 100%;
background: gold;
background: var(--highlight-color);
margin: 0;
padding: 10px;
color: black;

View File

@@ -22,6 +22,11 @@
background : #3a3a3a;
}
.textfield:focus {
border-color: var(--highlight-color);
outline: none;
}
.textfield-small {
width : 50px;
}
@@ -29,17 +34,13 @@
.button {
box-sizing: border-box;
height: 24px;
background-color: #3f3f3f;
border: 1px solid #333;
border-top-color: #666;
border-bottom-color: #222;
background-color: #666;
border-style: none;
border-radius: 2px;
cursor: pointer;
text-decoration: none;
color: white;
text-shadow: 0 -1px 0 black;
font-weight: bold;
font-size: 1rem;
text-align: center;
@@ -48,25 +49,17 @@
}
.button:hover {
text-decoration: none;
background-color: #484848;
color: gold;
color: var(--highlight-color);
}
.button-primary {
background-color: rgb(255,215,0); /* gold */
border-color: rgb(179, 164, 0);
border-top-color: white;
border-bottom-color: rgb(151, 133, 0);
background-color: var(--highlight-color);
color: black;
text-shadow: 0 1px 0 #fff;
}
.button-primary:hover {
background-color: rgb(255,235,20);
color: #333;
background-color: white;
color: black;
}
.button[disabled],
@@ -74,10 +67,6 @@
cursor:default;
background-color: #aaa;
color: #777;
text-shadow: 0 1px 0 #bbb;
border-color: #666;
border-top-color: #999;
border-bottom-color: #555;
}
.import-size-field,

View File

@@ -54,6 +54,9 @@
}
.add-frame-action {
display: flex;
align-items: center;
margin-top: 8px;
padding: 6px 0;
overflow: hidden;
@@ -71,6 +74,7 @@
.add-frame-action-icon {
margin: 3px;
float: left;
flex-shrink: 0;
}
.add-frame-action .label {
@@ -79,7 +83,7 @@
}
.add-frame-action:hover {
border-color: gold;
border-color: var(--highlight-color);
}
.preview-tile {
@@ -131,6 +135,11 @@
cursor: default;
}
.preview-tile .tile-overlay.tile-count.toggled {
background-color: gold;
color: black;
}
.preview-tile .tile-overlay.delete-frame-action {
top: 0;
right: 0;
@@ -153,7 +162,7 @@
}
.preview-tile.selected {
border-color: gold;
border-color: var(--highlight-color);
}
.preview-tile.selected:after {
@@ -162,7 +171,7 @@
top: 38px;
right: -9px;
border: transparent 4px solid;
border-left-color: gold;
border-left-color: var(--highlight-color);
border-width: 6px 0 6px 6px;
border-style: solid;
}
@@ -173,6 +182,6 @@
*/
.preview-tile-drop-proxy {
border: 3px dashed gold;
border: 3px dashed var(--highlight-color);
background-color: rgba(255, 215,0, 0.2);
}

View File

@@ -3,7 +3,7 @@
*/
.main-wrapper {
position: absolute;
position: fixed;
top: 5px;
right: 0;
bottom: 5px;
@@ -25,7 +25,8 @@
.left-column {
vertical-align: top;
height: 100%;
margin-right: 7px;
padding-right: 7px;
flex-shrink: 0;
}
.main-column {
@@ -37,12 +38,14 @@
box-sizing: border-box;
vertical-align: top;
height: 100%;
flex-shrink: 0;
display: flex;
flex-direction: column;
position: relative;
margin-left: 10px;
/* Keep in sync with Constants.RIGHT_COLUMN_PADDING_LEFT */
padding-left: 10px;
/* Add some padding for the absolutely positioned .cursor-coordinates */
padding-bottom: 20px;
}
@@ -78,10 +81,21 @@
}
.cursor-coordinates {
color:#888;
font-size:12px;
font-weight:bold;
font-family:Courier;
color: var(--highlight-color);
font-size: 12px;
font-weight: bold;
font-family: monospace;
}
.cursor-coordinates .drawing-zoom {
position: absolute;
top: -20px;
left: 1px;
}
.cursor-coordinates .frame-info {
line-height: 1.5;
text-align: left;
}
/**
@@ -155,4 +169,4 @@
.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;}
.canvas.layers-above-canvas {z-index: 11;}

View File

@@ -1,8 +1,8 @@
.minimap-crop-frame {
position:absolute;
border:1px solid rgba(255,255,255,0.5);
z-index:100;
box-sizing : border-box;
-moz-box-sizing : border-box;
cursor : pointer;
position: absolute;
border: 2px solid gold;
z-index: 100;
box-sizing: border-box;
-moz-box-sizing: border-box;
cursor: pointer;
}

View File

@@ -6,12 +6,12 @@
max-width: 300px;
border-top-left-radius: 7px;
border: #F0C36D 1px solid;
border: #e1a325 2px solid;
border-right: 0;
border-bottom: 0;
color: #222;
background-color: #F9EDBE;
background-color: var(--highlight-color);
font-weight: bold;
font-size: 13px;
@@ -24,8 +24,6 @@
top: 6px;
right: 17px;
color: gray;
font-size: 18px;
font-weight: bold;
@@ -43,7 +41,7 @@
padding: 10px;
width: 360px;
border-top-right-radius: 2px;
border: gold 2px solid;
border: var(--highlight-color) 2px solid;
border-left: 0;
border-bottom: 0;
background-color: #444;
@@ -69,6 +67,6 @@
margin-top: 8px;
height : 4px;
width : 300px;
background : linear-gradient(to left, gold, gold) no-repeat -300px 0;
background : linear-gradient(to left, var(--highlight-color), var(--highlight-color)) no-repeat -300px 0;
background-color : black;
}

View File

@@ -1,49 +0,0 @@
.pen-size-container {
overflow: hidden;
padding: 5px 5px;
}
.pen-size-option {
float: left;
box-sizing: border-box;
width: 20px;
height: 20px;
margin-right: 2px;
border-style: solid;
border-width: 2px;
border-color: #444;
cursor: pointer;
}
.pen-size-option[data-size='1'] {
padding: 6px;
}
.pen-size-option[data-size='2'] {
padding: 5px;
}
.pen-size-option[data-size='3'] {
padding: 4px;
}
.pen-size-option[data-size='4'] {
padding: 3px;
}
.pen-size-option:before {
content: '';
width: 100%;
height: 100%;
background-color: white;
display: block;
}
.pen-size-option:hover {
border-color: #888;
}
.pen-size-option.selected:before {
background-color: gold;
}
.pen-size-option.selected {
border-color: gold;
}

View File

@@ -5,6 +5,7 @@ html, body {
cursor : default;
font-family: Arial;
font-size: 11px;
line-height: 1.1;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
@@ -47,5 +48,5 @@ input[type="range"] {
}
a, a:visited {
color:gold;
color: var(--highlight-color);
}

View File

@@ -1,6 +1,14 @@
/*******************************/
/* Application Setting panel */
/*******************************/
/********************************/
/* Preferences Settings panel */
/********************************/
.settings-section-preferences {
height: 100%;
position: relative;
overflow: hidden;
margin: 0 20px;
height: 100%;
}
.background-picker-wrapper {
display: inline-block;
@@ -27,16 +35,20 @@
}
.background-picker.selected {
border-color: gold;
border-color: var(--highlight-color);
}
.layer-opacity-input {
.settings-opacity-input {
margin: 5px;
vertical-align: middle;
}
.layer-opacity-input,
.tile-mask-opacity-input {
width: 100px;
}
.layer-opacity-text {
.settings-opacity-text {
height: 31px;
display: inline-block;
line-height: 30px;
@@ -47,11 +59,102 @@
text-align: center;
}
.grid-width-select {
.settings-item-grid-size,
.settings-item-grid-spacing,
.settings-item-grid-color {
display: flex;
align-items: center;
}
.settings-item-grid-size > label,
.settings-item-grid-spacing > label,
.settings-item-grid-color > label {
width: 65px;
flex-shrink: 0;
}
.grid-spacing-container .size-picker-option[data-size='1'] {
padding: 7px;
}
.grid-spacing-container .size-picker-option[data-size='2'] {
padding: 6px;
}
.grid-spacing-container .size-picker-option[data-size='4'] {
padding: 5px;
}
.grid-spacing-container .size-picker-option[data-size='8'] {
padding: 4px;
}
.grid-spacing-container .size-picker-option[data-size='16'] {
padding: 3px;
}
.grid-spacing-container .size-picker-option[data-size='32'] {
padding: 2px;
}
.grid-spacing-container .size-picker-option[data-size='64'] {
padding: 1px;
}
.settings-item-grid-size .size-picker-option,
.settings-item-grid-spacing .size-picker-option {
border-color: #888;
}
.settings-item-grid-size .size-picker-option:not(.selected):hover,
.settings-item-grid-spacing .size-picker-option:not(.selected):hover {
border-color: white;
}
.grid-width-select,
.color-format-select {
margin: 5px 5px 0 5px;
}
.settings-section-application > .settings-title {
.grid-colors-list {
overflow: hidden;
padding: 0 5px;
}
.grid-colors-item {
float: left;
width: 20px;
height: 20px;
cursor: pointer;
border: 2px solid #888;
margin-right: 2px;
margin-bottom: 2px;
box-sizing: border-box;
}
.grid-colors-item:hover {
border-color: white;
}
.grid-colors-item.selected {
border-color: gold;
}
.settings-section-preferences > .settings-title {
/* Override the default 10px margin bottom for this panel */
margin-bottom: 15px;
}
.settings-section-preferences .button-primary {
margin-top: 10px;
}
.settings-version-info {
position: absolute;
bottom: 10px;
right: 10px;
color: #888;
}
/* Override default link styles for the release notes link
It doesn't need to popout too much */
.settings-version,
.settings-version:hover {
color: white !important;
text-decoration: none !important;
}

View File

@@ -43,8 +43,29 @@
float : left;
}
.gif-export-warning {
display: none;
}
.gif-export-warning.visible {
display: flex;
align-items: center;
border: 1px solid red;
padding: 5px;
margin: 5px 0;
}
.gif-export-warning-icon {
flex-shrink: 0;
margin-right: 5px;
}
.gif-export-warning-message {
font-weight: normal;
}
.preview-upload-ongoing:before{
content: "Upload ongoing ...";
content: "Upload in progress...";
position: absolute;
display: block;
height: 100%;
@@ -100,43 +121,6 @@
line-height: 23px;
}
.export-tabs {
overflow: hidden;
position: relative;
}
.export-tabs:after {
content: "";
display: block;
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
z-index: 0;
background-color: gold;
}
.export-tab {
float: left;
cursor: pointer;
padding: 5px;
border: 1px solid transparent;
/* Make sure the tab and its border are positioned above the :after element; */
position: relative;
z-index: 1;
}
.export-tab.selected,
.export-tab:hover {
color: gold;
}
.export-tab.selected {
border-color: gold gold #444 gold;
border-style: solid;
border-width: 1px;
}
.export-panel-header {
padding: 10px 5px 0px;
}
@@ -160,7 +144,8 @@
overflow: hidden;
}
.export-panel-gif .button {
.export-panel-gif .button,
.export-panel-png .button {
margin-right: 5px;
width: 75px;
flex-shrink: 0;
@@ -170,11 +155,6 @@
width: 50px;
}
.png-export-dimension-info,
.png-export-datauri-info {
margin-left: 5px;
}
#png-export-columns,
#png-export-rows {
/* Override default textfield padding-right to keep the number spinners

View File

@@ -5,103 +5,8 @@
width: 25%;
}
/*****************/
/* ANCHOR WIDGET */
/*****************/
.resize-origin-container {
overflow: hidden;
.resize-anchor-container {
position: relative;
width: 70px;
margin-top: 5px;
display: inline-block;
}
.transition .resize-origin-option,
.transition .resize-origin-option:before {
transition: background-color 0.2s, border-color 0.2s;
}
.resize-origin-option {
float: left;
position: relative;
box-sizing: border-box;
margin: 0 1px 1px 0;
width: 20px;
height: 20px;
background : #888;
font-size: 8px;
text-align: center;
cursor: pointer;
}
.disabled .resize-origin-option {
cursor: default;
background : #555;
border-color: #555 !important;
}
.resize-origin-option:hover {
border : 3px solid white;
}
.resize-origin-option.selected {
border : 3px solid gold;
}
.resize-origin-option:before {
content: '';
position: absolute;
display: block;
top: 50%;
left: 50%;
margin: -2px;
}
.resize-origin-option.selected:before {
content: '';
width: 4px;
height: 4px;
background: gold;
}
.disabled .resize-origin-option.selected:before {
background: #555;
}
.disabled .resize-origin-option[data-neighbor]:before {
border-color: #555 !important;
}
.resize-origin-option[data-neighbor]:before {
width: 0;
height: 0;
border-width: 4px;
border-style: solid;
border-color: transparent;
}
.resize-origin-option[data-neighbor="bottom"]:before {
border-top-color: gold;
margin-left: -4px;
}
.resize-origin-option[data-neighbor="left"]:before {
border-right-color: gold;
margin-top: -4px;
margin-left: -6px;
}
.resize-origin-option[data-neighbor="top"]:before {
border-bottom-color: gold;
margin-top: -6px;
margin-left: -4px;
}
.resize-origin-option[data-neighbor="right"]:before {
border-left-color: gold;
margin-top: -4px;
}

View File

@@ -24,3 +24,13 @@
color: white;
font-style: normal;
}
.save-status-warning-icon {
float: left;
margin-top: 5px;
}
.save-status-warning-icon {
overflow: hidden;
padding-left: 10px;
}

View File

@@ -52,7 +52,7 @@
background-color: #444;
margin-right: 0;
padding-right: 2px;
border-left : 3px solid gold;
border-left : 3px solid var(--highlight-color);
}
/************************************************************************************************/
@@ -64,7 +64,6 @@
font-size: 12px;
font-weight: bold;
color: #ccc;
text-shadow: 1px 1px #000;
}
.settings-section .button {
@@ -77,7 +76,7 @@
text-transform: uppercase;
border-bottom: 1px #aaa solid;
padding-bottom: 5px;
color: gold;
color: var(--highlight-color);
}
.settings-description {

View File

@@ -100,8 +100,8 @@
}
.sp-palette .sp-thumb-el.sp-thumb-active {
border-color: gold;
box-shadow: 0 0 0px 1px gold;
border-color: var(--highlight-color);
box-shadow: 0 0 0px 1px var(--highlight-color);
}
.sp-input {
@@ -110,7 +110,7 @@
background: #111;
border-radius: 2px;
color: #D3D3D3;
font-family: Courier!important;
font-family: monospace!important;
}
.sp-input.sp-validation-error {

View File

@@ -1,113 +0,0 @@
/*
Icon classes can be used entirely standalone. They are named after their original file names.
```html
<!-- `display: block` sprite -->
<div class="icon-home"></div>
<!-- `display: inline-block` sprite -->
<img class="icon-home" />
```
*/
.icon-cloud_export {
background-image: url(../img/spritesheet.png);
background-position: -512px -276px;
width: 50px;
height: 47px;
}
.icon-dragndrop {
background-image: url(../img/spritesheet.png);
background-position: -564px -173px;
width: 48px;
height: 48px;
}
.icon-duplicate {
background-image: url(../img/spritesheet.png);
background-position: -512px -369px;
width: 16px;
height: 16px;
}
.icon-export {
background-image: url(../img/spritesheet.png);
background-position: -564px -225px;
width: 43px;
height: 42px;
}
.icon-favicon {
background-image: url(../img/spritesheet.png);
background-position: -582px -151px;
width: 16px;
height: 16px;
}
.icon-gallery {
background-image: url(../img/spritesheet.png);
background-position: -512px -225px;
width: 52px;
height: 51px;
}
.icon-garbage {
background-image: url(../img/spritesheet.png);
background-position: 0px 0px;
width: 512px;
height: 512px;
}
.icon-gear {
background-image: url(../img/spritesheet.png);
background-position: -563px -323px;
width: 38px;
height: 37px;
}
.icon-import-icon {
background-image: url(../img/spritesheet.png);
background-position: -576px -69px;
width: 28px;
height: 36px;
}
.icon-keyboard {
background-image: url(../img/spritesheet.png);
background-position: -512px -133px;
width: 70px;
height: 40px;
}
.icon-local-storage-icon {
background-image: url(../img/spritesheet.png);
background-position: -512px 0px;
width: 100px;
height: 69px;
}
.icon-merge-icon {
background-image: url(../img/spritesheet.png);
background-position: -512px -69px;
width: 64px;
height: 64px;
}
.icon-plus {
background-image: url(../img/spritesheet.png);
background-position: -512px -323px;
width: 51px;
height: 46px;
}
.icon-popup-preview-arrow-gold {
background-image: url(../img/spritesheet.png);
background-position: -576px -105px;
width: 24px;
height: 18px;
}
.icon-popup-preview-arrow-white {
background-image: url(../img/spritesheet.png);
background-position: -582px -133px;
width: 24px;
height: 18px;
}
.icon-resize-icon {
background-image: url(../img/spritesheet.png);
background-position: -512px -173px;
width: 52px;
height: 52px;
}
.icon-save {
background-image: url(../img/spritesheet.png);
background-position: -562px -276px;
width: 43px;
height: 42px;
}

View File

@@ -17,11 +17,11 @@ body {
}
.no-overflow {
overflow : hidden;
overflow: hidden;
}
.image-link {
color : gold;
.highlight {
color: var(--highlight-color);
}
.pull-top,
@@ -52,14 +52,23 @@ body {
}
.checkbox-fix {
margin-left: 0;
margin: 3px 3px 3px 0;
}
.checkbox-container {
display: flex;
align-items: center;
}
.hidden {
display: none;
}
/**
* TOOLTIPS
*/
.tooltip-shortcut {
color:gold;
color: var(--highlight-color);
}
.tooltip-container {

View File

@@ -79,7 +79,7 @@
.preview-toggle-onion-skin-enabled,
.preview-toggle-onion-skin-enabled:hover {
color : gold;
color : var(--highlight-color);
}
.preview-contextual-actions {
@@ -98,7 +98,9 @@
opacity: 1;
}
.original-size-button {
.preview-contextual-action {
float: left;
width : 18px;
height: 18px;
line-height: 18px;
@@ -113,28 +115,95 @@
font-family: Tahoma;
}
.original-size-button-enabled {
color: gold;
border-color: gold;
.preview-contextual-action-hidden {
display: none;
}
.preview-contextual-action {
float: left;
.preview-contextual-action:hover {
color: var(--highlight-color);
border-color: var(--highlight-color);
}
/**
* If the icon represents an enabled state, the border should always be gold.
*/
.preview-contextual-action-enabled {
color: var(--highlight-color);
border-color: var(--highlight-color);
}
/**
* Drop-down in preview size selection
*/
.preview-drop-down {
float: left;
position: relative;
width : 22px;
min-height: 22px;
margin: 0 5px;
}
.preview-drop-down.preview-drop-down-disabled {
opacity: 0.5;
}
.preview-disable-overlay{
position: absolute;
width: 100%;
height: 100%;
display: none;
}
.preview-drop-down.preview-drop-down-disabled .preview-disable-overlay {
display: block;
z-index: 10;
}
.preview-drop-down .preview-contextual-action {
position: relative;
margin: 0 0 -100% 0;
opacity: 0;
transition: opacity linear .2s,
margin linear .2s;
transition-delay: 0s, .2s;
z-index: 1;
}
.preview-drop-down:hover .preview-contextual-action {
margin: 0 0 5px 0;
opacity: 1;
transition-delay: 0s, 0s;
}
.preview-drop-down .size-button-selected {
opacity: 1;
color: gold;
border-color: gold;
z-index: 5;
}
.open-popup-preview-button {
border : 2px solid white;
background-color : rgba(0,0,0,0.3);
}
.open-popup-preview-button:hover {
border-color: gold;
border-color: var(--highlight-color);
}
/**
* The regular image is provided bby the sprite icons.png+icons.css
* The regular image is provided by the sprite icons.png+icons.css
*/
.icon-minimap-popup-preview-arrow-white:hover {
background-image: url(../img/icons/minimap/minimap-popup-preview-arrow-gold.png);
background-position: 0 0;
background-size: 18px 18px;
}
@media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.icon-minimap-popup-preview-arrow-white:hover {
background-image: url(../img/icons/minimap/minimap-popup-preview-arrow-gold@2x.png);
}
}

View File

@@ -35,7 +35,7 @@
.layers-toggle-preview-enabled,
.layers-toggle-preview-enabled:hover {
color : gold;
color : var(--highlight-color);
}
/**
@@ -59,24 +59,40 @@
.layer-item {
position: relative;
display: flex;
height:24px;
line-height: 24px;
padding: 0 0 0 10px;
border-top: 1px solid #444;
cursor: pointer;
}
.layer-item .layer-name,
.layer-item .layer-name-input {
padding: 0 0 0 10px;
flex: 1 auto;
white-space: nowrap;
}
.layer-item .layer-name-input {
width: 80%;
}
.layer-item .layer-name.overflowing-name {
overflow: hidden;
text-overflow: ellipsis;
}
.layer-item:hover {
background : #222;
}
.layer-item-opacity {
position: absolute;
right: 8px;
padding: 0 8px 0 8px;
flex: 0 auto;
}
.current-layer-item,
.current-layer-item:hover {
background : #333;
color: gold;
color: var(--highlight-color);
}

View File

@@ -76,6 +76,11 @@
position: relative;
}
.palettes-list-colors.tiny > .palettes-list-color {
width: calc((100% - 35px) / 10);
height: 16px;
}
.palettes-list-color div {
height: 100%;
}
@@ -89,7 +94,7 @@
line-height: 35px;
width: 100%;
color: gray;
font-size: 0.7em;
font-size: 0.8em;
font-style: italic;
text-align: center
}
@@ -121,13 +126,14 @@
* Color index for the 9 first colors
*/
.palettes-list-color:nth-child(-n+10):after {
:not(.tiny) > .palettes-list-color:nth-child(-n+10):after {
content: attr(data-color-index);
position: absolute;
top: 0;
right: 0;
background-color: black;
color: gold;
color: var(--highlight-color);
font-family: Tahoma;
font-size: 0.5em;
@@ -136,39 +142,3 @@
padding: 2px 3px 2px 3px;
border-radius: 0 0 0 2px;
}
.palettes-list-color:nth-child(1):after {
content: "1";
}
.palettes-list-color:nth-child(2):after {
content: "2";
}
.palettes-list-color:nth-child(3):after {
content: "3";
}
.palettes-list-color:nth-child(4):after {
content: "4";
}
.palettes-list-color:nth-child(5):after {
content: "5";
}
.palettes-list-color:nth-child(6):after {
content: "6";
}
.palettes-list-color:nth-child(7):after {
content: "7";
}
.palettes-list-color:nth-child(8):after {
content: "8";
}
.palettes-list-color:nth-child(9):after {
content: "9";
}

View File

@@ -26,7 +26,17 @@
.toolbox-buttons .button {
/* Override border propery on .button elements from form.css */
border-style: solid;
border-color: #333;
border-width: 0 1px 0 0;
border-radius: 0;
background-color: #3f3f3f;
}
.toolbox-buttons .button[disabled],
.toolbox-buttons .button[disabled]:hover {
background-color: #aaa;
}
.toolbox-buttons button:last-child {

View File

@@ -17,7 +17,7 @@
position : absolute;
height : 100%;
width : 100%;
border: 3px solid gold;
border: 3px solid var(--highlight-color);
box-sizing: border-box;
}
@@ -31,33 +31,39 @@
.tool-paint-bucket .drawing-canvas-container:hover,
.tool-colorswap .drawing-canvas-container:hover {
cursor: url(../img/cursors/paint-bucket.png) 12 12, pointer;
cursor: url(../img/cursors/paint-bucket.png) 14 14, pointer;
}
.tool-vertical-mirror-pen .drawing-canvas-container:hover {
cursor: url(../img/cursors/vertical-mirror-pen.png) 5 15, pointer;
}
.tool-pen .drawing-canvas-container:hover,
.tool-lighten .drawing-canvas-container:hover,
.tool-pen .drawing-canvas-container:hover {
cursor: url(../img/cursors/pen.png) 1 14, pointer;
}
.tool-dithering .drawing-canvas-container:hover {
cursor: url(../img/cursors/pen.png) 0 15, pointer;
cursor: url(../img/cursors/dither.png) 1 14, pointer;
}
.tool-lighten .drawing-canvas-container:hover {
cursor: url(../img/cursors/lighten.png) 1 15, pointer;
}
.tool-eraser .drawing-canvas-container:hover {
cursor: url(../img/cursors/eraser.png) 0 15, pointer;
cursor: url(../img/cursors/eraser.png) 3 14, pointer;
}
.tool-stroke .drawing-canvas-container:hover {
cursor: url(../img/cursors/pen.png) 0 15, pointer;
cursor: url(../img/cursors/stroke.png) 1 14, pointer;
}
.tool-rectangle .drawing-canvas-container:hover {
cursor: url(../img/cursors/rectangle.png) 0 15, pointer;
cursor: url(../img/cursors/rectangle.png) 5 15, pointer;
}
.tool-circle .drawing-canvas-container:hover {
cursor: url(../img/cursors/circle.png) 2 15, pointer;
cursor: url(../img/cursors/circle.png) 5 15, pointer;
}
.tool-move .drawing-canvas-container:hover {
@@ -70,11 +76,11 @@
}
.tool-shape-select .drawing-canvas-container:hover {
cursor: url(../img/cursors/wand.png) 15 15, pointer;
cursor: url(../img/cursors/wand.png) 10 5, pointer;
}
.tool-colorpicker .drawing-canvas-container:hover {
cursor: url(../img/cursors/dropper.png) 0 15, pointer;
cursor: url(../img/cursors/dropper.png) 2 15, pointer;
}
.swap-colors-button {

View File

@@ -3,5 +3,38 @@
}
.transformations-container .tool-icon {
float:left;
margin: 0 0 5px 0;
}
.transformations-container .tools-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
height: 46px;
/* Override the float:left set on tools-wrapper in layout.css; */
float: initial;
}
.transformations-container.show-more .tools-wrapper {
height: auto;
/* Compensate the 5px bottom-margin coming from the tool-icon */
margin-bottom: -5px;
}
.transformations-show-more-link {
position: absolute;
color: #999;
right: 10px;
font-weight: normal;
cursor: pointer;
transition: 0.2s linear;
}
.transformations-show-more-link:hover {
color: white;
}
.show-more .transformations-show-more-link {
color: gold;
}

3
src/css/variables.css Normal file
View File

@@ -0,0 +1,3 @@
html, body {
--highlight-color: gold;
}

View File

@@ -0,0 +1,98 @@
/*****************/
/* ANCHOR WIDGET */
/*****************/
.anchor-wrapper {
overflow: hidden;
width: 70px;
}
/* When transitioning between enabled and disabled states */
.transition .anchor-option,
.transition .anchor-option:before {
transition: background-color 0.2s, border-color 0.2s;
}
.anchor-option {
float: left;
position: relative;
box-sizing: border-box;
margin: 0 1px 1px 0;
width: 20px;
height: 20px;
background : #888;
font-size: 8px;
text-align: center;
cursor: pointer;
}
.disabled .anchor-option {
cursor: default;
background : #555;
border-color: #555 !important;
}
.anchor-option:hover {
border : 3px solid white;
}
.anchor-option.selected {
border : 3px solid var(--highlight-color);
}
.anchor-option:before {
content: '';
position: absolute;
display: block;
top: 50%;
left: 50%;
margin: -2px;
}
.anchor-option.selected:before {
content: '';
width: 4px;
height: 4px;
background: var(--highlight-color);
}
.disabled .anchor-option.selected:before {
background: #555;
}
.disabled .anchor-option[data-neighbor]:before {
border-color: #555 !important;
}
.anchor-option[data-neighbor]:before {
width: 0;
height: 0;
border-width: 4px;
border-style: solid;
border-color: transparent;
}
.anchor-option[data-neighbor="bottom"]:before {
border-top-color: var(--highlight-color);
margin-left: -4px;
}
.anchor-option[data-neighbor="left"]:before {
border-right-color: var(--highlight-color);
margin-top: -4px;
margin-left: -6px;
}
.anchor-option[data-neighbor="top"]:before {
border-bottom-color: var(--highlight-color);
margin-top: -6px;
margin-left: -4px;
}
.anchor-option[data-neighbor="right"]:before {
border-left-color: var(--highlight-color);
margin-top: -4px;
}

View File

@@ -0,0 +1,55 @@
/***********************/
/* FRAME PICKER WIDGET */
/***********************/
.frame-picker-wrapper {
width: 150px;
height: 150px;
border: 3px solid #666;
border-radius: 3px;
}
.frame-viewer {
width: 100%;
height: calc(100% - 25px);
display: flex;
align-items: center;
justify-content: center;
}
.frame-viewer > canvas,
.frame-viewer > img {
max-width: 100%;
max-height: 100%;
}
.frame-nav {
display: flex;
width: 100%;
height: 24px;
border-top: 1px solid #666;
}
.frame-nav .button {
flex-shrink: 0;
border-radius: 0;
height: 24px;
background-color: #3f3f3f;
}
.frame-nav .button[disabled],
.frame-nav .button[disabled]:hover {
background-color: #aaa;
}
.frame-nav .button + .button {
border-left: 1px solid #333;
}
.frame-nav-input {
min-width: 1px;
border-style: none;
height: 24px;
text-align: center;
}

View File

@@ -0,0 +1,61 @@
/***********************/
/* SIZE PICKER WIDGET */
/***********************/
.size-picker-container {
overflow: hidden;
padding: 5px 5px;
}
.size-picker-option {
float: left;
box-sizing: border-box;
width: 20px;
height: 20px;
margin-right: 2px;
border-style: solid;
border-width: 2px;
border-color: #444;
cursor: pointer;
}
.size-picker-option[data-size='1'] {
padding: 5px;
}
.size-picker-option[data-size='2'] {
padding: 4px;
}
.size-picker-option[data-size='3'] {
padding: 3px;
}
.size-picker-option[data-size='4'] {
padding: 2px;
}
.size-picker-option:before {
content: '';
width: 100%;
height: 100%;
background-color: white;
display: block;
text-align: center;
line-height: 12px;
font-size: 90%;
}
.size-picker-option:hover {
border-color: #888;
}
.size-picker-option.selected:before {
background-color: var(--highlight-color);
}
.size-picker-option.selected {
border-color: var(--highlight-color);
}
.size-picker-option.labeled:before {
content: attr(real-size);
color: black;
}

42
src/css/widgets-tabs.css Normal file
View File

@@ -0,0 +1,42 @@
/*****************/
/* TABS WIDGET */
/*****************/
.tab-list {
overflow: hidden;
position: relative;
}
.tab-list:after {
content: "";
display: block;
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
z-index: 0;
background-color: var(--highlight-color);
}
.tab-item {
float: left;
cursor: pointer;
padding: 5px;
border: 1px solid transparent;
border-radius: 2px 2px 0 0;
/* Make sure the tab and its border are positioned above the :after element; */
position: relative;
z-index: 1;
}
.tab-item.selected,
.tab-item:hover {
color: var(--highlight-color);
}
.tab-item.selected {
border-color: var(--highlight-color);
border-bottom-color: #444;
border-style: solid;
border-width: 1px;
}

View File

@@ -0,0 +1,32 @@
.wizard-wrapper {
z-index: 1;
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.wizard-step {
z-index: -1;
margin-left: calc(100% + 5px);
position: absolute;
}
.current-step {
z-index: 1;
margin-left: 0;
}
.current-step-in,
.current-step-out {
z-index: 10;
transition: margin-left 200ms;
}
.current-step-in {
margin-left: 0;
}
.current-step-out {
margin-left: 100%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 766 B

BIN
src/img/cursors/dither.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

BIN
src/img/cursors/lighten.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 827 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -22,9 +22,7 @@
color:white;">
<span style="top:45%">Loading Piskel ...</span>
</div>
<!--standalone-start-->
@@include('templates/debug-header.html', {})
<!--standalone-end-->
<!-- the comment below indicates the beginning of markup reused by the editor integrated in piskelapp.com -->
<!-- do not delete, do not move :) -->
@@ -69,18 +67,28 @@
</div>
@@include('templates/misc-templates.html', {})
@@include('templates/data-uri-export.html', {})
@@include('templates/popup-preview.html', {})
<span class="cheatsheet-link icon-common-keyboard-gold" rel="tooltip" data-placement="right" title="Keyboard shortcuts">&nbsp;</span>
<span class="cheatsheet-link icon-common-keyboard-gold"
rel="tooltip" data-placement="right" title="Keyboard shortcuts">&nbsp;</span>
<div class="performance-link icon-common-warning-red"
rel="tooltip" data-placement="left" title="Performance problem detected, learn more.">&nbsp;</div>
<!-- dialogs partials -->
@@include('templates/dialogs/create-palette.html', {})
@@include('templates/dialogs/import-image.html', {})
@@include('templates/dialogs/browse-backups.html', {})
@@include('templates/dialogs/browse-local.html', {})
@@include('templates/dialogs/cheatsheet.html', {})
@@include('templates/dialogs/create-palette.html', {})
@@include('templates/dialogs/import.html', {})
@@include('templates/dialogs/performance-info.html', {})
@@include('templates/dialogs/unsupported-browser.html', {})
<!-- settings-panel partials -->
@@include('templates/settings/application.html', {})
@@include('templates/settings/preferences.html', {})
@@include('templates/settings/preferences/grid.html', {})
@@include('templates/settings/preferences/misc.html', {})
@@include('templates/settings/preferences/tile.html', {})
@@include('templates/settings/resize.html', {})
@@include('templates/settings/save.html', {})
@@include('templates/settings/import.html', {})

99
src/js/.eslintrc Normal file
View File

@@ -0,0 +1,99 @@
{
"env": {
"es6": true,
"browser": true
},
"globals": {
"$": true,
"jQuery": true,
"pskl": true,
"Events": true,
"Constants": true,
"console": true,
"module": true,
"require": true,
"Q": true,
"Promise": true
},
"rules": {
"no-undef": 2,
"no-use-before-define": [
2,
{
"functions": false
}
],
"curly": [
2,
"all"
],
"operator-linebreak": [
2,
"after"
],
"camelcase": [
2,
{
"properties": "never"
}
],
"max-len": [
2,
120
],
"indent": [
2,
2,
{
"SwitchCase": 1
}
],
"quotes": [
2,
"single"
],
"no-multi-str": 2,
"no-mixed-spaces-and-tabs": 2,
"no-trailing-spaces": 2,
"space-unary-ops": [
2,
{
"nonwords": false,
"overrides": {}
}
],
"one-var": [
2,
"never"
],
"brace-style": [
2,
"1tbs",
{
"allowSingleLine": true
}
],
"keyword-spacing": [
2,
{}
],
"space-infix-ops": 2,
"space-before-blocks": [
2,
"always"
],
"eol-last": 2,
"space-in-parens": [
2,
"never"
],
"no-multiple-empty-lines": 2,
"no-with": 2,
"no-spaced-func": 2,
"dot-notation": 2,
"semi": [
2,
"always"
]
}
}

View File

@@ -12,14 +12,19 @@ var Constants = {
MAX_HEIGHT : 1024,
MAX_WIDTH : 1024,
MAX_PALETTE_COLORS : 100,
MAX_PALETTE_COLORS : 256,
// allow current colors service to get up to 256 colors.
// GIF generation is different if the color count goes over 256.
MAX_WORKER_COLORS : 256,
PREVIEW_FILM_SIZE : 96,
ANIMATED_PREVIEW_WIDTH : 200,
// Keep in sync with padding-left: 10px in layout.css
RIGHT_COLUMN_PADDING_LEFT : 10,
DEFAULT_PEN_COLOR : '#000000',
TRANSPARENT_COLOR : 'rgba(0, 0, 0, 0)',
SEAMLESS_MODE_OVERLAY_COLOR : 'rgba(255, 255, 255, 0.5)',
SEAMLESS_MODE_OVERLAY_COLOR : 'rgba(255, 255, 255, 0)',
CURRENT_COLORS_PALETTE_ID : '__current-colors',
@@ -49,8 +54,17 @@ var Constants = {
// TESTS
DRAWING_TEST_FOLDER : 'drawing',
// Maximum size of a sprite that can be saved on piskelapp datastore.
// This size will be compared to the length of the stringified serialization of the sprite.
// This is an approximation at best but gives correct results in most cases.
// The datastore limit is 1 MiB, which we roughly approximate to 1 million characters.
APPENGINE_SAVE_LIMIT : 1 * 1024 * 1024,
// Message displayed when an action will lead to erase the current animation.
CONFIRM_OVERWRITE: 'This will replace your current animation, are you sure you want to continue?',
// SERVICE URLS
APPENGINE_SAVE_URL : 'save',
IMAGE_SERVICE_UPLOAD_URL : 'http://piskel-imgstore-b.appspot.com/__/upload',
IMAGE_SERVICE_GET_URL : 'http://piskel-imgstore-b.appspot.com/img/'
IMAGE_SERVICE_UPLOAD_URL : '{{protocol}}://piskel-imgstore-b.appspot.com/__/upload',
IMAGE_SERVICE_GET_URL : '{{protocol}}://piskel-imgstore-b.appspot.com/img/'
};

View File

@@ -15,7 +15,7 @@ var Events = {
DRAG_START : 'DRAG_START',
DRAG_END : 'DRAG_END',
DIALOG_DISPLAY : 'DIALOG_DISPLAY',
DIALOG_SHOW : 'DIALOG_SHOW',
DIALOG_HIDE : 'DIALOG_HIDE',
PALETTE_LIST_UPDATED : 'PALETTE_LIST_UPDATED',
@@ -59,11 +59,16 @@ var Events = {
AFTER_SAVING_PISKEL: 'AFTER_SAVING_PISKEL',
FRAME_SIZE_CHANGED : 'FRAME_SIZE_CHANGED',
FPS_CHANGED : 'FPS_CHANGED',
SELECTION_CREATED: 'SELECTION_CREATED',
SELECTION_MOVE_REQUEST: 'SELECTION_MOVE_REQUEST',
SELECTION_DISMISSED: 'SELECTION_DISMISSED',
CLIPBOARD_COPY: 'CLIPBOARD_COPY',
CLIPBOARD_CUT: 'CLIPBOARD_CUT',
CLIPBOARD_PASTE: 'CLIPBOARD_PASTE',
SHOW_NOTIFICATION: 'SHOW_NOTIFICATION',
HIDE_NOTIFICATION: 'HIDE_NOTIFICATION',
@@ -76,6 +81,10 @@ var Events = {
CURRENT_COLORS_UPDATED : 'CURRENT_COLORS_UPDATED',
PERFORMANCE_REPORT_CHANGED : 'PERFORMANCE_REPORT_CHANGED',
PISKEL_FILE_IMPORT_FAILED : 'PISKEL_FILE_IMPORT_FAILED',
// Tests
MOUSE_EVENT : 'MOUSE_EVENT',
KEYBOARD_EVENT : 'KEYBOARD_EVENT',

View File

@@ -15,12 +15,16 @@
*/
this.isAppEngineVersion = !!pskl.appEngineToken_;
// This id is used to keep track of sessions in the BackupService.
this.sessionId = pskl.utils.Uuid.generate();
this.shortcutService = new pskl.service.keyboard.ShortcutService();
this.shortcutService.init();
var size = pskl.UserSettings.get(pskl.UserSettings.DEFAULT_SIZE);
var fps = Constants.DEFAULT.FPS;
var descriptor = new pskl.model.piskel.Descriptor('New Piskel', '');
var piskel = new pskl.model.Piskel(size.width, size.height, descriptor);
var piskel = new pskl.model.Piskel(size.width, size.height, fps, descriptor);
var layer = new pskl.model.Layer('Layer 1');
var frame = new pskl.model.Frame(size.width, size.height);
@@ -35,6 +39,8 @@
this.piskelController.init();
this.paletteImportService = new pskl.service.palette.PaletteImportService();
this.paletteImportService.init();
this.paletteService = new pskl.service.palette.PaletteService();
this.paletteService.addDynamicPalette(new pskl.service.palette.CurrentColorsPalette());
@@ -58,25 +64,24 @@
this.drawingController = new pskl.controller.DrawingController(
this.piskelController,
this.paletteController,
$('#drawing-canvas-container'));
document.querySelector('#drawing-canvas-container'));
this.drawingController.init();
this.previewController = new pskl.controller.preview.PreviewController(
this.piskelController,
$('#animated-preview-canvas-container'));
document.querySelector('#animated-preview-canvas-container'));
this.previewController.init();
this.minimapController = new pskl.controller.MinimapController(
this.piskelController,
this.previewController,
this.drawingController,
$('.minimap-container'));
document.querySelector('.minimap-container'));
this.minimapController.init();
this.framesListController = new pskl.controller.FramesListController(
this.piskelController,
$('#preview-list'));
document.querySelector('#preview-list-wrapper'));
this.framesListController.init();
this.layersListController = new pskl.controller.LayersListController(this.piskelController);
@@ -94,7 +99,7 @@
this.selectionManager = new pskl.selection.SelectionManager(this.piskelController);
this.selectionManager.init();
this.historyService = new pskl.service.HistoryService(this.corePiskelController);
this.historyService = new pskl.service.HistoryService(this.piskelController);
this.historyService.init();
this.notificationController = new pskl.controller.NotificationController();
@@ -109,6 +114,9 @@
this.canvasBackgroundController = new pskl.controller.CanvasBackgroundController();
this.canvasBackgroundController.init();
this.indexedDbStorageService = new pskl.service.storage.IndexedDbStorageService(this.piskelController);
this.indexedDbStorageService.init();
this.localStorageService = new pskl.service.storage.LocalStorageService(this.piskelController);
this.localStorageService.init();
@@ -124,12 +132,15 @@
this.storageService = new pskl.service.storage.StorageService(this.piskelController);
this.storageService.init();
this.importService = new pskl.service.ImportService(this.piskelController, this.previewController);
this.importService = new pskl.service.ImportService(this.piskelController);
this.importService.init();
this.imageUploadService = new pskl.service.ImageUploadService();
this.imageUploadService.init();
this.savedStatusService = new pskl.service.SavedStatusService(this.piskelController, this.historyService);
this.savedStatusService = new pskl.service.SavedStatusService(
this.piskelController,
this.historyService);
this.savedStatusService.init();
this.backupService = new pskl.service.BackupService(this.piskelController);
@@ -138,7 +149,9 @@
this.beforeUnloadService = new pskl.service.BeforeUnloadService(this.piskelController);
this.beforeUnloadService.init();
this.headerController = new pskl.controller.HeaderController(this.piskelController, this.savedStatusService);
this.headerController = new pskl.controller.HeaderController(
this.piskelController,
this.savedStatusService);
this.headerController.init();
this.penSizeService = new pskl.service.pensize.PenSizeService();
@@ -147,20 +160,29 @@
this.penSizeController = new pskl.controller.PenSizeController();
this.penSizeController.init();
this.fileDropperService = new pskl.service.FileDropperService(
this.piskelController,
document.querySelector('#drawing-canvas-container'));
this.fileDropperService = new pskl.service.FileDropperService(this.piskelController);
this.fileDropperService.init();
var drawingLoop = new pskl.rendering.DrawingLoop();
drawingLoop.addCallback(this.render, this);
drawingLoop.start();
this.userWarningController = new pskl.controller.UserWarningController(this.piskelController);
this.userWarningController.init();
this.performanceReportService = new pskl.service.performance.PerformanceReportService(
this.piskelController,
this.currentColorsService);
this.performanceReportService.init();
this.clipboardService = new pskl.service.ClipboardService(this.piskelController);
this.clipboardService.init();
this.drawingLoop = new pskl.rendering.DrawingLoop();
this.drawingLoop.addCallback(this.render, this);
this.drawingLoop.start();
this.initTooltips_();
var piskelData = this.getPiskelInitData_();
if (piskelData && piskelData.piskel) {
this.loadPiskel_(piskelData.piskel, piskelData.descriptor, piskelData.fps);
this.loadPiskel_(piskelData);
}
if (pskl.devtools) {
@@ -173,13 +195,28 @@
mb.createMacBuiltin('Piskel');
gui.Window.get().menu = mb;
}
if (!pskl.utils.Environment.isIntegrationTest() && pskl.utils.UserAgent.isUnsupported()) {
$.publish(Events.DIALOG_SHOW, {
dialogId : 'unsupported-browser'
});
}
if (pskl.utils.Environment.isDebug()) {
pskl.app.shortcutService.registerShortcut(pskl.service.keyboard.Shortcuts.DEBUG.RELOAD_STYLES,
window.reloadStyles);
}
},
loadPiskel_ : function (serializedPiskel, descriptor, fps) {
loadPiskel_ : function (piskelData) {
var serializedPiskel = piskelData.piskel;
pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, function (piskel) {
piskel.setDescriptor(descriptor);
pskl.app.piskelController.setPiskel(piskel);
pskl.app.previewController.setFPS(fps);
$.publish(Events.PISKEL_SAVED);
if (piskelData.descriptor) {
// Backward compatibility for v2 or older
piskel.setDescriptor(piskelData.descriptor);
}
});
},

View File

@@ -17,6 +17,8 @@
$.subscribe(Events.DRAG_START, this.onDragStart_.bind(this));
$.subscribe(Events.DRAG_END, this.onDragEnd_.bind(this));
$.subscribe(Events.FRAME_SIZE_CHANGED, this.redraw.bind(this));
$.subscribe(Events.ZOOM_CHANGED, this.redraw.bind(this));
$.subscribe(Events.PISKEL_RESET, this.redraw.bind(this));
this.redraw();
};
@@ -39,7 +41,18 @@
}
}
this.coordinatesContainer.innerHTML = this.getFrameSizeHTML_() + html;
if (pskl.app.drawingController) {
var zoom = pskl.app.drawingController.compositeRenderer.getZoom().toFixed(2);
html += '<div class="drawing-zoom">x' + zoom + '</div>';
}
this.coordinatesContainer.innerHTML = this.getFrameSizeHTML_() + html + this.getCurrentFrameIndexHTML_();
};
ns.CursorCoordinatesController.prototype.getCurrentFrameIndexHTML_ = function () {
var currentFrameIndex = this.piskelController.getCurrentFrameIndex() + 1;
var frameCount = this.piskelController.getFrameCount();
return '<div class="frame-info">' + currentFrameIndex + '/' + frameCount + '</div>';
};
ns.CursorCoordinatesController.prototype.getFrameSizeHTML_ = function () {

View File

@@ -2,14 +2,12 @@
var ns = $.namespace('pskl.controller');
ns.DrawingController = function (piskelController, paletteController, container) {
ns.DrawingController = function (piskelController, container) {
/**
* @public
*/
this.piskelController = piskelController;
this.paletteController = paletteController;
this.dragHandler = new ns.drawing.DragHandler(this);
/**
@@ -24,7 +22,7 @@
var cfg = {
'zoom': this.calculateZoom_(),
'supportGridRendering' : true,
'supportGridRendering' : false,
'height' : this.getContainerHeight_(),
'width' : this.getContainerWidth_(),
'xOffset' : 0,
@@ -32,9 +30,10 @@
};
this.overlayRenderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, cfg, ['canvas-overlay']);
this.renderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, cfg, ['drawing-canvas']);
this.onionSkinRenderer = pskl.rendering.OnionSkinRenderer.createInContainer(this.container, cfg, piskelController);
this.layersRenderer = new pskl.rendering.layer.LayersRenderer(this.container, cfg, piskelController);
cfg.supportGridRendering = true;
this.renderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, cfg, ['drawing-canvas']);
this.compositeRenderer = new pskl.rendering.CompositeRenderer();
this.compositeRenderer
@@ -52,20 +51,24 @@
ns.DrawingController.prototype.init = function () {
this.initMouseBehavior();
$.subscribe(Events.TOOL_SELECTED, $.proxy(function(evt, toolBehavior) {
$.subscribe(Events.TOOL_SELECTED, (function(evt, toolBehavior) {
this.currentToolBehavior = toolBehavior;
this.overlayFrame.clear();
}, this));
}).bind(this));
$(window).resize($.proxy(this.startResizeTimer_, this));
window.addEventListener('resize', this.startResizeTimer_.bind(this));
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
$.subscribe(Events.FRAME_SIZE_CHANGED, this.onFrameSizeChange_.bind(this));
var shortcuts = pskl.service.keyboard.Shortcuts;
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.RESET_ZOOM, this.resetZoom_.bind(this));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.INCREASE_ZOOM, this.increaseZoom_.bind(this, 1));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.DECREASE_ZOOM, this.decreaseZoom_.bind(this, 1));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.INCREASE_ZOOM, this.updateZoom_.bind(this, 1));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.DECREASE_ZOOM, this.updateZoom_.bind(this, -1));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_UP, this.updateOffset_.bind(this, 'up'));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_RIGHT, this.updateOffset_.bind(this, 'right'));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_DOWN, this.updateOffset_.bind(this, 'down'));
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.OFFSET_LEFT, this.updateOffset_.bind(this, 'left'));
window.setTimeout(function () {
this.afterWindowResize_();
@@ -74,38 +77,36 @@
};
ns.DrawingController.prototype.initMouseBehavior = function() {
var body = $('body');
this.container.mousedown($.proxy(this.onMousedown_, this));
this.container.addEventListener('mousedown', this.onMousedown_.bind(this));
if (pskl.utils.UserAgent.isChrome || pskl.utils.UserAgent.isIE11) {
this.container.on('mousewheel', $.proxy(this.onMousewheel_, this));
this.container.addEventListener('mousewheel', this.onMousewheel_.bind(this));
} else {
this.container.on('wheel', $.proxy(this.onMousewheel_, this));
this.container.addEventListener('wheel', this.onMousewheel_.bind(this));
}
window.addEventListener('mouseup', this.onMouseup_.bind(this));
window.addEventListener('mousemove', this.onMousemove_.bind(this));
window.addEventListener('keyup', this.onKeyup_.bind(this));
window.addEventListener('touchstart', this.onMousedown_.bind(this));
window.addEventListener('touchmove' , this.onMousemove_.bind(this));
window.addEventListener('touchend', this.onMouseup_.bind(this));
// Deactivate right click:
body.contextmenu(this.onCanvasContextMenu_);
window.addEventListener('touchstart', this.onTouchstart_.bind(this));
window.addEventListener('touchmove' , this.onTouchmove_.bind(this));
window.addEventListener('touchend', this.onTouchend_.bind(this));
// Deactivate right click:
document.body.addEventListener('contextmenu', this.onCanvasContextMenu_.bind(this));
};
ns.DrawingController.prototype.startResizeTimer_ = function () {
if (this.resizeTimer) {
window.clearInterval(this.resizeTimer);
}
this.resizeTimer = window.setTimeout($.proxy(this.afterWindowResize_, this), 200);
this.resizeTimer = window.setTimeout(this.afterWindowResize_.bind(this), 200);
};
ns.DrawingController.prototype.afterWindowResize_ = function () {
var initialWidth = this.compositeRenderer.getDisplaySize().width;
this.compositeRenderer.setDisplaySize(this.getContainerWidth_(), this.getContainerHeight_());
this.centerColumnWrapperHorizontally_();
var ratio = this.compositeRenderer.getDisplaySize().width / initialWidth;
var newZoom = ratio * this.compositeRenderer.getZoom();
this.compositeRenderer.setZoom(newZoom);
@@ -130,12 +131,24 @@
ns.DrawingController.prototype.onFrameSizeChange_ = function () {
this.compositeRenderer.setDisplaySize(this.getContainerWidth_(), this.getContainerHeight_());
this.centerColumnWrapperHorizontally_();
this.compositeRenderer.setZoom(this.calculateZoom_());
this.compositeRenderer.setOffset(0, 0);
$.publish(Events.ZOOM_CHANGED);
};
ns.DrawingController.prototype.onTouchstart_ = function (event) {
this.onMousedown_(event);
};
ns.DrawingController.prototype.onTouchmove_ = function (event) {
this.onMousemove_(event);
event.preventDefault();
};
ns.DrawingController.prototype.onTouchend_ = function (event) {
this.onMouseup_(event);
};
/**
* @private
*/
@@ -151,6 +164,9 @@
if (event.button === Constants.MIDDLE_BUTTON) {
this.dragHandler.startDrag(event.clientX, event.clientY);
} else if (event.altKey && !this.currentToolBehavior.supportsAlt()) {
this.currentToolBehavior.hideHighlightedPixel(this.overlayFrame);
this.isPickingColor = true;
} else {
this.currentToolBehavior.hideHighlightedPixel(this.overlayFrame);
$.publish(Events.TOOL_PRESSED);
@@ -198,6 +214,8 @@
if (this.isClicked) {
if (pskl.app.mouseStateService.isMiddleButtonPressed()) {
this.dragHandler.updateDrag(x, y);
} else if (this.isPickingColor) {
// Nothing to do on mousemove when picking a color with ALT+click.
} else {
$.publish(Events.MOUSE_EVENT, [event, this]);
this.currentToolBehavior.moveToolAt(
@@ -220,18 +238,19 @@
$.publish(Events.CURSOR_MOVED, [coords.x, coords.y]);
};
ns.DrawingController.prototype.onMousewheel_ = function (jQueryEvent) {
var evt = jQueryEvent.originalEvent;
ns.DrawingController.prototype.onMousewheel_ = function (evt) {
// Ratio between wheelDeltaY (mousewheel event) and deltaY (wheel event) is -40
var delta;
if (pskl.utils.UserAgent.isChrome) {
delta = evt.wheelDeltaY;
} else if (pskl.utils.UserAgent.isIE11) {
if (pskl.utils.UserAgent.isIE11) {
delta = evt.wheelDelta;
} else if (pskl.utils.UserAgent.isFirefox) {
delta = -40 * evt.deltaY;
} else {
delta = evt.wheelDeltaY;
}
var modifier = Math.abs(delta / 120);
delta = delta || 0;
var modifier = (delta / 120);
if (pskl.utils.UserAgent.isMac ? evt.metaKey : evt.ctrlKey) {
modifier = modifier * 5;
@@ -239,59 +258,139 @@
evt.preventDefault();
}
if (delta > 0) {
this.increaseZoom_(modifier);
} else if (delta < 0) {
this.decreaseZoom_(modifier);
var coords = this.getSpriteCoordinates(evt.clientX, evt.clientY);
this.updateZoom_(modifier, coords);
};
/**
* Update the current viewport offset of 1 pixel in the provided direction.
* Direction can be one of 'up', 'right', 'down', 'left'.
* Callback for the OFFSET_${DIR} shortcuts.
*/
ns.DrawingController.prototype.updateOffset_ = function (direction) {
var off = this.getOffset();
if (direction === 'up') {
off.y -= 1;
} else if (direction === 'right') {
off.x += 1;
} else if (direction === 'down') {
off.y += 1;
} else if (direction === 'left') {
off.x -= 1;
}
this.setOffset(
off.x,
off.y
);
};
ns.DrawingController.prototype.increaseZoom_ = function (zoomMultiplier) {
var step = (zoomMultiplier || 1) * this.getZoomStep_();
/**
* Update the current zoom level by a given multiplier.
*
* @param {Number} zoomMultiplier: factor by which the zoom should be modified. Negative
* values will decrease the zoom, positive values will increase it.
* @param {Object} centerCoords, optional:
* - {Number} x: x coordinate of the desired center the zoomed canvas
* - {Number} y: y coordinate of the desired center the zoomed canvas
*/
ns.DrawingController.prototype.updateZoom_ = function (zoomMultiplier, centerCoords) {
if (zoomMultiplier === 0) {
return;
}
var off = this.getOffset();
var oldWidth = this.getContainerWidth_() / this.renderer.getZoom();
var oldHeight = this.getContainerHeight_() / this.renderer.getZoom();
var step = zoomMultiplier * 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);
if (typeof centerCoords === 'object') {
var xRatio = (centerCoords.x - off.x) / oldWidth;
var yRatio = (centerCoords.y - off.y) / oldHeight;
var newWidth = this.getContainerWidth_() / this.renderer.getZoom();
var newHeight = this.getContainerHeight_() / this.renderer.getZoom();
this.setOffset(
off.x - ((newWidth - oldWidth) * xRatio),
off.y - ((newHeight - oldHeight) * yRatio)
);
}
};
/**
* @private
*/
ns.DrawingController.prototype.onMouseup_ = function (event) {
var frame = this.piskelController.getCurrentFrame();
if (!this.isClicked) {
return;
}
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
if (event.changedTouches && event.changedTouches[0]) {
coords = this.getSpriteCoordinates(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
}
if (this.isClicked) {
// A mouse button was clicked on the drawing canvas before this mouseup event,
// the user was probably drawing on the canvas.
// Note: The mousemove movement (and the mouseup) may end up outside
// of the drawing canvas.
this.isClicked = false;
// A mouse button was clicked on the drawing canvas before this mouseup event,
// the user was probably drawing on the canvas.
// Note: The mousemove movement (and the mouseup) may end up outside
// of the drawing canvas.
if (pskl.app.mouseStateService.isMiddleButtonPressed()) {
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.piskelController.getCurrentFrame(),
this.overlayFrame,
event
);
this.isClicked = false;
$.publish(Events.TOOL_RELEASED);
}
$.publish(Events.MOUSE_EVENT, [event, this]);
var isMiddleButton = pskl.app.mouseStateService.isMiddleButtonPressed();
var isMiddleClick = isMiddleButton && !this.dragHandler.isDragging();
var isMiddleDrag = isMiddleButton && this.dragHandler.isDragging();
if (this.isPickingColor || isMiddleClick) {
// Picking color after ALT+click or middle mouse button click.
this.pickColorAt_(coords);
this.isPickingColor = false;
// Flash the cursor to briefly show the colorpicker cursor.
this.flashColorPicker_();
} else if (isMiddleDrag) {
// Stop the drag handler after a middle button drag action.
this.dragHandler.stopDrag();
} else {
// Regular tool click, release the current tool.
this.currentToolBehavior.releaseToolAt(
coords.x,
coords.y,
this.piskelController.getCurrentFrame(),
this.overlayFrame,
event
);
$.publish(Events.TOOL_RELEASED);
}
$.publish(Events.MOUSE_EVENT, [event, this]);
};
/**
* Send a COLOR selection event for the color contained at the provided coordinates.
* No-op if the coordinate is outside of the drawing canvas.
* @param {Object} coords {x: Number, y: Number}
*/
ns.DrawingController.prototype.pickColorAt_ = function (coords) {
var frame = this.piskelController.getCurrentFrame();
if (!frame.containsPixel(coords.x, coords.y)) {
return;
}
var color = pskl.utils.intToColor(frame.getPixel(coords.x, coords.y));
var isRightButton = pskl.app.mouseStateService.isRightButtonPressed();
var evt = isRightButton ? Events.SELECT_SECONDARY_COLOR : Events.SELECT_PRIMARY_COLOR;
$.publish(evt, [color]);
};
ns.DrawingController.prototype.flashColorPicker_ = function () {
document.body.classList.add('tool-colorpicker');
document.body.classList.remove(this.currentToolBehavior.toolId);
window.clearTimeout(this.flashColorPickerTimer);
this.flashColorPickerTimer = window.setTimeout(function () {
document.body.classList.remove('tool-colorpicker');
document.body.classList.add(this.currentToolBehavior.toolId);
}.bind(this), 200);
};
/**
@@ -312,7 +411,8 @@
* @private
*/
ns.DrawingController.prototype.onCanvasContextMenu_ = function (event) {
if ($(event.target).closest('#drawing-canvas-container').length) {
// closest() not really available everywhere yet, just skip if missing.
if (event.target.closest && event.target.closest('#drawing-canvas-container')) {
// Deactivate right click on drawing canvas only.
event.preventDefault();
event.stopPropagation();
@@ -350,17 +450,21 @@
};
ns.DrawingController.prototype.getAvailableHeight_ = function () {
return $('#main-wrapper').height();
return document.querySelector('#main-wrapper').getBoundingClientRect().height;
};
ns.DrawingController.prototype.getSelectorWidth_ = function (selector) {
return document.querySelector(selector).getBoundingClientRect().width;
};
ns.DrawingController.prototype.getAvailableWidth_ = function () {
var leftSectionWidth = $('.left-column').outerWidth(true);
var rightSectionWidth = $('.right-column').outerWidth(true);
var toolsContainerWidth = $('#tool-section').outerWidth(true);
var settingsContainerWidth = $('#application-action-section').outerWidth(true);
var leftSectionWidth = this.getSelectorWidth_('.left-column');
var rightSectionWidth = this.getSelectorWidth_('.right-column');
var toolsContainerWidth = this.getSelectorWidth_('#tool-section');
var settingsContainerWidth = this.getSelectorWidth_('#application-action-section');
var usedWidth = leftSectionWidth + rightSectionWidth + toolsContainerWidth + settingsContainerWidth;
var availableWidth = $('#main-wrapper').width() - usedWidth;
var availableWidth = this.getSelectorWidth_('#main-wrapper') - usedWidth;
var comfortMargin = 10;
return availableWidth - comfortMargin;
@@ -374,17 +478,6 @@
return this.getAvailableWidth_();
};
/**
* @private
*/
ns.DrawingController.prototype.centerColumnWrapperHorizontally_ = function() {
var containerHeight = this.getContainerHeight_();
var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - containerHeight) / 2);
$('#column-wrapper').css({
'top': verticalGapInPixel + 'px'
});
};
ns.DrawingController.prototype.getRenderer = function () {
return this.compositeRenderer;
};

View File

@@ -5,35 +5,46 @@
SELECT : 'select',
CLONE : 'clone',
DELETE : 'delete',
NEW_FRAME : 'newframe'
NEW_FRAME : 'newframe',
TOGGLE: 'toggle'
};
ns.FramesListController = function (piskelController, container) {
this.piskelController = piskelController;
this.container = container;
this.previewList = container.querySelector('#preview-list');
this.refreshZoom_();
this.redrawFlag = true;
this.regenerateDomFlag = true;
this.justDropped = false;
this.cachedFrameProcessor = new pskl.model.frame.CachedFrameProcessor();
this.cachedFrameProcessor.setFrameProcessor(this.frameToPreviewCanvas_.bind(this));
this.cachedFrameProcessor.setOutputCloner(this.clonePreviewCanvas_.bind(this));
this.initDragndropBehavior_();
};
ns.FramesListController.prototype.init = function() {
$.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this));
$.subscribe(Events.PISKEL_RESET, this.flagForRedraw_.bind(this));
$.subscribe(Events.PISKEL_RESET, this.flagForRedraw_.bind(this, true));
$.subscribe(Events.USER_SETTINGS_CHANGED, this.flagForRedraw_.bind(this));
$.subscribe(Events.PISKEL_RESET, this.refreshZoom_.bind(this));
$('#preview-list-scroller').scroll(this.updateScrollerOverflows.bind(this));
this.container.get(0).addEventListener('click', this.onContainerClick_.bind(this));
this.previewListScroller = document.querySelector('#preview-list-scroller');
this.previewListScroller.addEventListener('scroll', this.updateScrollerOverflows.bind(this));
this.container.addEventListener('click', this.onContainerClick_.bind(this));
this.updateScrollerOverflows();
};
ns.FramesListController.prototype.flagForRedraw_ = function () {
ns.FramesListController.prototype.flagForRedraw_ = function (regenerateDom) {
this.redrawFlag = true;
if (regenerateDom) {
this.regenerateDomFlag = true;
}
};
ns.FramesListController.prototype.refreshZoom_ = function () {
@@ -42,17 +53,25 @@
ns.FramesListController.prototype.render = function () {
if (this.redrawFlag) {
this.createPreviews_();
if (this.regenerateDomFlag) {
this.tiles = [];
this.addFrameTile = null;
this.createPreviews_();
this.regenerateDomFlag = false;
}
this.updatePreviews_();
this.redrawFlag = false;
}
};
ns.FramesListController.prototype.updateScrollerOverflows = function () {
var scroller = $('#preview-list-scroller');
var scrollerHeight = scroller.height();
var scrollTop = scroller.scrollTop();
var scrollerContentHeight = $('#preview-list').height();
var treshold = $('.top-overflow').height();
var scroller = this.previewListScroller;
var scrollerHeight = scroller.offsetHeight;
var scrollTop = scroller.scrollTop;
var scrollerContentHeight = this.previewList.offsetHeight;
var treshold = this.container.querySelector('.top-overflow').offsetHeight;
var overflowTop = false;
var overflowBottom = false;
@@ -65,9 +84,8 @@
overflowBottom = true;
}
}
var wrapper = $('#preview-list-wrapper');
wrapper.toggleClass('top-overflow-visible', overflowTop);
wrapper.toggleClass('bottom-overflow-visible', overflowBottom);
this.container.classList.toggle('top-overflow-visible', overflowTop);
this.container.classList.toggle('bottom-overflow-visible', overflowBottom);
};
ns.FramesListController.prototype.onContainerClick_ = function (event) {
@@ -80,27 +98,92 @@
if (action === ACTION.CLONE) {
this.piskelController.duplicateFrameAt(index);
var clonedTile = this.createPreviewTile_(index + 1);
this.previewList.insertBefore(clonedTile, this.tiles[index].nextSibling);
this.tiles.splice(index, 0, clonedTile);
this.updateScrollerOverflows();
} else if (action === ACTION.DELETE) {
this.piskelController.removeFrameAt(index);
this.previewList.removeChild(this.tiles[index]);
this.tiles.splice(index, 1);
this.updateScrollerOverflows();
} else if (action === ACTION.SELECT) {
} else if (action === ACTION.SELECT && !this.justDropped) {
this.piskelController.setCurrentFrameIndex(index);
} else if (action === ACTION.NEW_FRAME) {
this.piskelController.addFrame();
var newtile = this.createPreviewTile_(this.tiles.length);
this.tiles.push(newtile);
this.previewList.insertBefore(newtile, this.addFrameTile);
this.updateScrollerOverflows();
} else if (action == ACTION.TOGGLE) {
this.piskelController.toggleFrameVisibilityAt(index);
}
this.flagForRedraw_();
};
ns.FramesListController.prototype.updatePreviews_ = function () {
var i;
var length;
for (i = 0, length = this.tiles.length; i < length; i++) {
// Remove selected class
this.tiles[i].classList.remove('selected');
// Remove toggle class
this.tiles[i].querySelector('.tile-count').classList.remove('toggled');
// Update tile numbers
this.tiles[i].setAttribute('data-tile-number', i);
this.tiles[i].querySelector('.tile-count').innerHTML = (i + 1);
// Update visibility
if (this.piskelController.hasVisibleFrameAt(i)) {
this.tiles[i].querySelector('.tile-count').classList.add('toggled');
}
// Check if any tile is updated
var hash = this.piskelController.getCurrentLayer().getFrameAt(i).getHash();
if (this.tiles[i].getAttribute('data-tile-hash') !== hash) {
if (this.tiles[i].querySelector('canvas')) {
this.tiles[i].querySelector('.canvas-container').replaceChild(
this.getCanvasForFrame(this.piskelController.getCurrentLayer().getFrameAt(i)),
this.tiles[i].querySelector('canvas')
);
} else {
this.tiles[i].querySelector('.canvas-container').appendChild(
this.getCanvasForFrame(this.piskelController.getCurrentLayer().getFrameAt(i))
);
}
}
}
// Hide/Show buttons if needed
var buttons = this.container.querySelectorAll('.delete-frame-action, .dnd-action');
var display = (this.piskelController.getFrameCount() > 1) ? 'block' : 'none';
for (i = 0, length = buttons.length; i < length; i++) {
buttons[i].style.display = display;
}
// Add selected class
this.tiles[this.piskelController.getCurrentFrameIndex()].classList.add('selected');
};
ns.FramesListController.prototype.createPreviews_ = function () {
this.container.html('');
this.previewList.innerHTML = '';
// Manually remove tooltips since mouseout events were shortcut by the DOM refresh:
$('.tooltip').remove();
var tooltips = document.querySelectorAll('.tooltip');
Array.prototype.forEach.call(tooltips, function (tooltip) {
tooltip.parentNode.removeChild(tooltip);
});
var frameCount = this.piskelController.getFrameCount();
for (var i = 0 ; i < frameCount ; i++) {
this.container.append(this.createPreviewTile_(i));
var tile = this.createPreviewTile_(i);
this.previewList.appendChild(tile);
this.tiles[i] = tile;
}
// Append 'new empty frame' button
var newFrameButton = document.createElement('div');
@@ -109,12 +192,9 @@
newFrameButton.setAttribute('data-tile-action', ACTION.NEW_FRAME);
newFrameButton.innerHTML = '<div class="add-frame-action-icon icon-frame-plus-white">' +
'</div><div class="label">Add new frame</div>';
this.container.append(newFrameButton);
this.previewList.appendChild(newFrameButton);
this.addFrameTile = newFrameButton;
var needDragndropBehavior = (frameCount > 1);
if (needDragndropBehavior) {
this.initDragndropBehavior_();
}
this.updateScrollerOverflows();
};
@@ -122,37 +202,54 @@
* @private
*/
ns.FramesListController.prototype.initDragndropBehavior_ = function () {
$('#preview-list').sortable({
$(this.previewList).sortable({
placeholder: 'preview-tile preview-tile-drop-proxy',
update: $.proxy(this.onUpdate_, this),
update: this.onUpdate_.bind(this),
stop: this.onSortableStop_.bind(this),
items: '.preview-tile',
axis: 'y',
tolerance: 'pointer'
});
$('#preview-list').disableSelection();
$(this.previewList).disableSelection();
};
/**
* @private
*/
ns.FramesListController.prototype.onUpdate_ = function (event, ui) {
var originFrameId = parseInt(ui.item.data('tile-number'), 10);
var targetInsertionId = $('.preview-tile').index(ui.item);
var movedItem = ui.item.get(0);
var originFrameId = parseInt(movedItem.dataset.tileNumber, 10);
var tiles = document.querySelectorAll('.preview-tile');
var targetInsertionId = Array.prototype.indexOf.call(tiles, movedItem);
this.piskelController.moveFrame(originFrameId, targetInsertionId);
this.piskelController.setCurrentFrameIndex(targetInsertionId);
var tile = this.tiles.splice(originFrameId, 1)[0];
this.tiles.splice(targetInsertionId, 0, tile);
this.flagForRedraw_();
};
/**
* @private
*/
ns.FramesListController.prototype.onSortableStop_ = function (event, ui) {
this.justDropped = true;
this.resizeTimer = window.setTimeout((function() {
this.justDropped = false;
}).bind(this), 200);
};
/**
* @private
* TODO(vincz): clean this giant rendering function & remove listeners.
*/
ns.FramesListController.prototype.createPreviewTile_ = function(tileNumber) {
var currentFrame = this.piskelController.getCurrentLayer().getFrameAt(tileNumber);
var previewTileRoot = document.createElement('li');
previewTileRoot.setAttribute('data-tile-number', tileNumber);
previewTileRoot.setAttribute('data-tile-hash', currentFrame.getHash());
previewTileRoot.setAttribute('data-tile-action', ACTION.SELECT);
previewTileRoot.classList.add('preview-tile');
if (this.piskelController.getCurrentFrame() == currentFrame) {
@@ -171,10 +268,14 @@
canvasContainer.style.marginLeft = verticalMargin + 'px';
canvasContainer.style.marginRight = verticalMargin + 'px';
// Add canvas background and canvas
var canvasBackground = document.createElement('div');
canvasBackground.className = 'canvas-background';
canvasContainer.appendChild(canvasBackground);
canvasContainer.appendChild(this.getCanvasForFrame(currentFrame));
previewTileRoot.appendChild(canvasContainer);
// Add clone button
var cloneFrameButton = document.createElement('button');
cloneFrameButton.setAttribute('rel', 'tooltip');
cloneFrameButton.setAttribute('data-placement', 'right');
@@ -184,27 +285,28 @@
cloneFrameButton.className = 'tile-overlay duplicate-frame-action icon-frame-duplicate-white';
previewTileRoot.appendChild(cloneFrameButton);
canvasContainer.appendChild(this.getCanvasForFrame(currentFrame));
previewTileRoot.appendChild(canvasContainer);
// Add delete button
var deleteButton = document.createElement('button');
deleteButton.setAttribute('rel', 'tooltip');
deleteButton.setAttribute('data-placement', 'right');
deleteButton.setAttribute('title', 'Delete this frame');
deleteButton.setAttribute('data-tile-number', tileNumber);
deleteButton.setAttribute('data-tile-action', ACTION.DELETE);
deleteButton.className = 'tile-overlay delete-frame-action icon-frame-recyclebin-white';
previewTileRoot.appendChild(deleteButton);
if (tileNumber > 0 || this.piskelController.getFrameCount() > 1) {
// Add 'remove frame' button.
var deleteButton = document.createElement('button');
deleteButton.setAttribute('rel', 'tooltip');
deleteButton.setAttribute('data-placement', 'right');
deleteButton.setAttribute('title', 'Delete this frame');
deleteButton.setAttribute('data-tile-number', tileNumber);
deleteButton.setAttribute('data-tile-action', ACTION.DELETE);
deleteButton.className = 'tile-overlay delete-frame-action icon-frame-recyclebin-white';
previewTileRoot.appendChild(deleteButton);
// Add 'dragndrop handle'.
var dndHandle = document.createElement('div');
dndHandle.className = 'tile-overlay dnd-action icon-frame-dragndrop-white' ;
previewTileRoot.appendChild(dndHandle);
// Add 'dragndrop handle'.
var dndHandle = document.createElement('div');
dndHandle.className = 'tile-overlay dnd-action icon-frame-dragndrop-white' ;
previewTileRoot.appendChild(dndHandle);
}
var tileCount = document.createElement('div');
tileCount.className = 'tile-overlay tile-count';
// Add tile count
var tileCount = document.createElement('button');
tileCount.setAttribute('rel', 'tooltip');
tileCount.setAttribute('title', 'Toggle for preview');
tileCount.setAttribute('data-tile-number', tileNumber);
tileCount.setAttribute('data-tile-action', ACTION.TOGGLE);
tileCount.className = 'tile-overlay tile-count toggle-frame-action';
tileCount.innerHTML = tileNumber + 1;
previewTileRoot.appendChild(tileCount);

View File

@@ -31,7 +31,7 @@
}
if (this.piskelName_) {
this.piskelName_.innerHTML = name;
this.piskelName_.textContent = name;
}
} catch (e) {
console.warn('Could not update header : ' + e.message);

View File

@@ -1,15 +1,18 @@
(function () {
var ns = $.namespace('pskl.controller');
var TOGGLE_LAYER_SHORTCUT = 'alt+L';
ns.LayersListController = function (piskelController) {
this.piskelController = piskelController;
this.layerPreviewShortcut = pskl.service.keyboard.Shortcuts.MISC.LAYER_PREVIEW ;
this.layerPreviewShortcut = pskl.service.keyboard.Shortcuts.MISC.LAYER_PREVIEW;
this.startRenamingCurrentLayer_ = this.startRenamingCurrentLayer_.bind(this);
this.onRenameInput_ = this.onRenameInput_.bind(this);
};
ns.LayersListController.prototype.init = function () {
this.isRenaming = false;
this.layerItemTemplate_ = pskl.utils.Template.get('layer-item-template');
this.layerNameInputTemplate_ = pskl.utils.Template.get('layer-name-input-template');
this.rootEl = document.querySelector('.layers-list-container');
this.layersListEl = document.querySelector('.layers-list');
this.toggleLayerPreviewEl = document.querySelector('.layers-toggle-preview');
@@ -17,28 +20,55 @@
this.rootEl.addEventListener('click', this.onClick_.bind(this));
this.toggleLayerPreviewEl.addEventListener('click', this.toggleLayerPreview_.bind(this));
this.createButtonTooltips_();
this.initToggleLayerPreview_();
this.renderLayerList_();
this.updateToggleLayerPreview_();
$.subscribe(Events.PISKEL_RESET, this.renderLayerList_.bind(this));
$.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this));
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
};
ns.LayersListController.prototype.renderLayerList_ = function () {
// Backup scroll before refresh.
var scrollTop = this.layersListEl.scrollTop;
this.layersListEl.innerHTML = '';
var layers = this.piskelController.getLayers();
layers.forEach(this.addLayerItem.bind(this));
this.updateButtonStatus_();
// Restore scroll
this.layersListEl.scrollTop = scrollTop;
// Ensure the currently the selected layer is visible.
var currentLayerEl = this.layersListEl.querySelector('.current-layer-item');
if (currentLayerEl) {
currentLayerEl.scrollIntoView();
currentLayerEl.scrollIntoViewIfNeeded(false);
}
};
ns.LayersListController.prototype.createButtonTooltips_ = function () {
var addTooltip = pskl.utils.TooltipFormatter.format('Create a layer', null, [
{key : 'shift', description : 'Clone current layer'}
]);
var addButton = this.rootEl.querySelector('[data-action="add"]');
addButton.setAttribute('title', addTooltip);
var moveDownTooltip = pskl.utils.TooltipFormatter.format('Move layer down', null, [
{key : 'shift', description : 'Move to the bottom'}
]);
var moveDownButton = this.rootEl.querySelector('[data-action="down"]');
moveDownButton.setAttribute('title', moveDownTooltip);
var moveUpTooltip = pskl.utils.TooltipFormatter.format('Move layer up', null, [
{key : 'shift', description : 'Move to the top'}
]);
var moveUpButton = this.rootEl.querySelector('[data-action="up"]');
moveUpButton.setAttribute('title', moveUpTooltip);
};
ns.LayersListController.prototype.initToggleLayerPreview_ = function () {
var descriptors = [{description : 'Opacity defined in PREFERENCES'}];
var helpText = 'Preview all layers';
@@ -50,7 +80,6 @@
ns.LayersListController.prototype.updateButtonStatus_ = function () {
var layers = this.piskelController.getLayers();
var currentLayer = this.piskelController.getCurrentLayer();
var index = this.piskelController.getCurrentLayerIndex();
var isLast = index === 0;
@@ -91,24 +120,62 @@
ns.LayersListController.prototype.addLayerItem = function (layer, index) {
var isSelected = this.piskelController.getCurrentLayer() === layer;
var isRenaming = isSelected && this.isRenaming;
var layerItemHtml = pskl.utils.Template.replace(this.layerItemTemplate_, {
'layername' : layer.getName(),
'layerindex' : index,
'isselected:current-layer-item' : isSelected,
'opacity': layer.getOpacity()
'opacity' : layer.getOpacity()
});
var layerItem = pskl.utils.Template.createFromHTML(layerItemHtml);
this.layersListEl.insertBefore(layerItem, this.layersListEl.firstChild);
if (layerItem.offsetWidth < layerItem.scrollWidth) {
var layerNameEl = layerItem.querySelector('.layer-name');
layerNameEl.classList.add('overflowing-name');
layerNameEl.setAttribute('title', layer.getName());
layerNameEl.setAttribute('rel', 'tooltip');
}
if (isSelected) {
layerItem.removeEventListener('dblclick', this.startRenamingCurrentLayer_);
layerItem.addEventListener('dblclick', this.startRenamingCurrentLayer_);
}
if (isRenaming) {
var layerNameInputHtml = pskl.utils.Template.replace(this.layerNameInputTemplate_, {
'layername' : layer.getName()
});
var layerNameInput = pskl.utils.Template.createFromHTML(layerNameInputHtml);
var layerNameEl = layerItem.querySelector('.layer-name');
layerItem.replaceChild(layerNameInput, layerNameEl);
layerNameInput.removeEventListener('blur', this.onRenameInput_);
layerNameInput.removeEventListener('keydown', this.onRenameInput_);
layerNameInput.addEventListener('blur', this.onRenameInput_);
layerNameInput.addEventListener('keydown', this.onRenameInput_);
layerNameInput.focus();
layerNameInput.select();
}
var opacity = layer.getOpacity();
if (opacity == 1) {
layerItem.querySelector('.layer-item-opacity').style.color = '#ffd700';
} else if (opacity == 0) {
layerItem.querySelector('.layer-item-opacity').style.color = '#969696';
} else {
layerItem.querySelector('.layer-item-opacity').style.color = '#ffffff';
}
};
ns.LayersListController.prototype.onClick_ = function (evt) {
var el = evt.target || evt.srcElement;
var index;
if (el.classList.contains('button')) {
this.onButtonClick_(el);
} else if (el.classList.contains('layer-item')) {
index = el.dataset.layerIndex;
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
this.onButtonClick_(el, evt);
} else if (el.classList.contains('layer-name')) {
var currentIndex = this.piskelController.getCurrentLayerIndex();
index = pskl.utils.Dom.getData(el, 'layerIndex');
if (index != currentIndex) {
var currentItem = el.parentElement.parentElement.querySelector('.current-layer-item');
currentItem.removeEventListener('dblclick', this.startRenamingCurrentLayer_);
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
}
} else if (el.classList.contains('layer-item-opacity')) {
index = pskl.utils.Dom.getData(el, 'layerIndex');
var layer = this.piskelController.getLayerAt(parseInt(index, 10));
@@ -117,36 +184,55 @@
}
};
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.startRenamingCurrentLayer_ = function () {
this.isRenaming = true;
this.renderLayerList_();
};
ns.LayersListController.prototype.onRenameInput_ = function (evt) {
var el = evt.target || evt.srcElement;
if (evt.key === 'Enter') {
this.finishRenamingCurrentLayer_(el, el.value);
} else if (!evt.key || evt.key === 'Escape') {
this.finishRenamingCurrentLayer_(el);
}
};
ns.LayersListController.prototype.finishRenamingCurrentLayer_ = function (input, newName) {
if (newName) {
var index = this.piskelController.getCurrentLayerIndex();
this.piskelController.renameLayerAt(index, newName);
}
input.removeEventListener('blur', this.onRenameInput_);
input.removeEventListener('keydown', this.onRenameInput_);
this.isRenaming = false;
this.renderLayerList_();
};
ns.LayersListController.prototype.mergeDownCurrentLayer_ = function () {
var index = this.piskelController.getCurrentLayerIndex();
this.piskelController.mergeDownLayerAt(index);
this.renderLayerList_();
};
ns.LayersListController.prototype.onButtonClick_ = function (button) {
ns.LayersListController.prototype.onButtonClick_ = function (button, evt) {
var action = button.getAttribute('data-action');
if (action == 'up') {
this.piskelController.moveLayerUp();
this.piskelController.moveLayerUp(evt.shiftKey);
} else if (action == 'down') {
this.piskelController.moveLayerDown();
this.piskelController.moveLayerDown(evt.shiftKey);
} else if (action == 'add') {
this.piskelController.createLayer();
if (evt.shiftKey) {
this.piskelController.duplicateCurrentLayer();
} else {
this.piskelController.createLayer();
}
} else if (action == 'delete') {
this.piskelController.removeCurrentLayer();
} else if (action == 'merge') {
this.mergeDownCurrentLayer_();
} else if (action == 'edit') {
this.renameCurrentLayer_();
this.startRenamingCurrentLayer_();
}
};

View File

@@ -16,14 +16,14 @@
this.minimapEl = document.createElement('DIV');
this.minimapEl.className = 'minimap-crop-frame';
this.minimapEl.style.display = 'none';
$(this.container).append(this.minimapEl);
this.container.appendChild(this.minimapEl);
// Init mouse events
$(this.container).mousedown(this.onMinimapMousedown_.bind(this));
$('body').mousemove(this.onMinimapMousemove_.bind(this));
$('body').mouseup(this.onMinimapMouseup_.bind(this));
this.container.addEventListener('mousedown', this.onMinimapMousedown_.bind(this));
document.body.addEventListener('mousemove', this.onMinimapMousemove_.bind(this));
document.body.addEventListener('mouseup', this.onMinimapMouseup_.bind(this));
$.subscribe(Events.ZOOM_CHANGED, $.proxy(this.renderMinimap_, this));
$.subscribe(Events.ZOOM_CHANGED, this.renderMinimap_.bind(this));
};
ns.MinimapController.prototype.renderMinimap_ = function () {
@@ -40,8 +40,9 @@
var minimapSize = this.getMinimapSize_();
var previewSize = this.getPreviewSize_();
var containerHeight = this.container.height();
var containerWidth = this.container.width();
var containerRect = this.container.getBoundingClientRect();
var containerHeight = containerRect.height;
var containerWidth = containerRect.width;
// offset(x, y) in frame pixels
var offset = this.drawingController.getRenderer().getOffset();
@@ -60,7 +61,7 @@
this.minimapEl.style.display = 'block';
this.minimapEl.style.width = Math.min(minimapSize.width, containerWidth) + 'px';
this.minimapEl.style.height = Math.min(minimapSize.height, containerHeight) + 'px';
this.minimapEl.style.left = Math.max(0, left) + 'px';
this.minimapEl.style.left = (Math.max(0, left) + Constants.RIGHT_COLUMN_PADDING_LEFT) + 'px';
this.minimapEl.style.top = Math.max(0, top) + 'px';
this.isVisible = true;

View File

@@ -7,8 +7,8 @@
* @public
*/
ns.NotificationController.prototype.init = function() {
$.subscribe(Events.SHOW_NOTIFICATION, $.proxy(this.displayMessage_, this));
$.subscribe(Events.HIDE_NOTIFICATION, $.proxy(this.removeMessage_, this));
$.subscribe(Events.SHOW_NOTIFICATION, this.displayMessage_.bind(this));
$.subscribe(Events.HIDE_NOTIFICATION, this.removeMessage_.bind(this));
};
/**
@@ -35,9 +35,9 @@
* @private
*/
ns.NotificationController.prototype.removeMessage_ = function (evt) {
var message = $('#user-message');
if (message.length) {
message.remove();
var message = document.querySelector('#user-message');
if (message) {
message.parentNode.removeChild(message);
}
};
})();

View File

@@ -1,6 +1,10 @@
(function () {
var ns = $.namespace('pskl.controller');
/**
* The PaletteController is responsible for handling the two color picker
* widgets found in the left column, below the tools.
*/
ns.PaletteController = function () {};
/**
@@ -31,24 +35,24 @@
// Initialize colorpickers:
var colorPicker = $('#color-picker');
colorPicker.spectrum($.extend({color: Constants.DEFAULT_PEN_COLOR}, spectrumCfg));
colorPicker.change({isPrimary : true}, $.proxy(this.onPickerChange_, this));
this.setTitleOnPicker_(Constants.DEFAULT_PEN_COLOR, colorPicker);
colorPicker.change({isPrimary : true}, this.onPickerChange_.bind(this));
this.setTitleOnPicker_(Constants.DEFAULT_PEN_COLOR, colorPicker.get(0));
var secondaryColorPicker = $('#secondary-color-picker');
secondaryColorPicker.spectrum($.extend({color: Constants.TRANSPARENT_COLOR}, spectrumCfg));
secondaryColorPicker.change({isPrimary : false}, $.proxy(this.onPickerChange_, this));
this.setTitleOnPicker_(Constants.TRANSPARENT_COLOR, secondaryColorPicker);
secondaryColorPicker.change({isPrimary : false}, this.onPickerChange_.bind(this));
this.setTitleOnPicker_(Constants.TRANSPARENT_COLOR, secondaryColorPicker.get(0));
var swapColorsIcon = $('.swap-colors-button');
swapColorsIcon.click(this.swapColors.bind(this));
var swapColorsIcon = document.querySelector('.swap-colors-button');
swapColorsIcon.addEventListener('click', this.swapColors.bind(this));
};
/**
* @private
*/
ns.PaletteController.prototype.onPickerChange_ = function(evt, isPrimary) {
var inputPicker = $(evt.target);
var color = inputPicker.val();
ns.PaletteController.prototype.onPickerChange_ = function(evt) {
var inputPicker = evt.target;
var color = inputPicker.value;
if (color != Constants.TRANSPARENT_COLOR) {
// Unless the color is TRANSPARENT_COLOR, format it to hexstring, as
@@ -67,7 +71,6 @@
* @private
*/
ns.PaletteController.prototype.onColorSelected_ = function(args, evt, color) {
var inputPicker = $(evt.target);
if (args.isPrimary) {
this.setPrimaryColor_(color);
} else {
@@ -76,12 +79,12 @@
};
ns.PaletteController.prototype.setPrimaryColor_ = function (color) {
this.updateColorPicker_(color, $('#color-picker'));
this.updateColorPicker_(color, document.querySelector('#color-picker'));
$.publish(Events.PRIMARY_COLOR_SELECTED, [color]);
};
ns.PaletteController.prototype.setSecondaryColor_ = function (color) {
this.updateColorPicker_(color, $('#secondary-color-picker'));
this.updateColorPicker_(color, document.querySelector('#secondary-color-picker'));
$.publish(Events.SECONDARY_COLOR_SELECTED, [color]);
};
@@ -92,13 +95,15 @@
};
ns.PaletteController.prototype.resetColors = function () {
pskl.app.selectedColorsService.reset();
this.setPrimaryColor_(Constants.DEFAULT_PEN_COLOR);
this.setSecondaryColor_(Constants.TRANSPARENT_COLOR);
};
/**
* @private
*/
ns.PaletteController.prototype.updateColorPicker_ = function (color, colorPicker) {
var jqueryColorPicker = $(colorPicker);
if (color == Constants.TRANSPARENT_COLOR) {
// We can set the current palette color to transparent.
// You can then combine this transparent color with an advanced
@@ -109,17 +114,17 @@
// The colorpicker can't be set to a transparent state.
// We set its background to white and insert the
// string "TRANSPARENT" to mimic this state:
colorPicker.spectrum('set', Constants.TRANSPARENT_COLOR);
colorPicker.val(Constants.TRANSPARENT_COLOR);
jqueryColorPicker.spectrum('set', Constants.TRANSPARENT_COLOR);
colorPicker.value = Constants.TRANSPARENT_COLOR;
} else {
colorPicker.spectrum('set', color);
jqueryColorPicker.spectrum('set', color);
}
this.setTitleOnPicker_(color, colorPicker);
};
ns.PaletteController.prototype.setTitleOnPicker_ = function (title, colorPicker) {
var parent = colorPicker.parent();
title = parent.data('initial-title') + '<br/>' + title;
parent.attr('data-original-title', title);
var parent = colorPicker.parentNode;
title = parent.dataset.initialTitle + '<br/>' + title;
parent.dataset.originalTitle = title;
};
})();

View File

@@ -29,7 +29,7 @@
$.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));
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
var shortcuts = pskl.service.keyboard.Shortcuts;
pskl.app.shortcutService.registerShortcut(shortcuts.COLOR.PREVIOUS_COLOR, this.selectPreviousColor_.bind(this));
@@ -51,12 +51,17 @@
};
ns.PalettesListController.prototype.fillColorListContainer = function () {
var colors = this.getSelectedPaletteColors_();
if (colors.length > 0) {
var html = colors.map(function (color, index) {
return pskl.utils.Template.replace(this.paletteColorTemplate_, {color : color, index : index});
var html = colors.filter(function (color) {
return !!color;
}).map(function (color, index) {
return pskl.utils.Template.replace(this.paletteColorTemplate_, {
color : color,
index : index + 1,
title : color.toUpperCase()
});
}.bind(this)).join('');
this.colorListContainer_.innerHTML = html;
@@ -64,6 +69,10 @@
} else {
this.colorListContainer_.innerHTML = pskl.utils.Template.get('palettes-list-no-colors-partial');
}
// If we have more than 10 colors, use tiny mode, where 10 colors will fit on the same
// line.
this.colorListContainer_.classList.toggle('tiny', colors.length > 10);
};
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
@@ -100,8 +109,8 @@
ns.PalettesListController.prototype.getCurrentColorIndex_ = function () {
var currentIndex = 0;
var selectedColor = document.querySelector('.' + PRIMARY_COLOR_CLASSNAME);
if (selectedColor) {
currentIndex = parseInt(selectedColor.dataset.colorIndex, 10);
if (selectedColor) {
currentIndex = parseInt(selectedColor.dataset.colorIndex, 10) - 1;
}
return currentIndex;
};
@@ -139,14 +148,14 @@
};
ns.PalettesListController.prototype.onCreatePaletteClick_ = function (evt) {
$.publish(Events.DIALOG_DISPLAY, {
$.publish(Events.DIALOG_SHOW, {
dialogId : 'create-palette'
});
};
ns.PalettesListController.prototype.onEditPaletteClick_ = function (evt) {
var paletteId = this.colorPaletteSelect_.value;
$.publish(Events.DIALOG_DISPLAY, {
$.publish(Events.DIALOG_SHOW, {
dialogId : 'create-palette',
initArgs : paletteId
});

View File

@@ -1,23 +1,19 @@
(function () {
var ns = $.namespace('pskl.controller');
ns.PenSizeController = function () {};
ns.PenSizeController = function () {
this.sizePicker = new pskl.widgets.SizePicker(this.onSizePickerChanged_.bind(this));
};
ns.PenSizeController.prototype.init = function () {
this.container = document.querySelector('.pen-size-container');
pskl.utils.Event.addEventListener(this.container, 'click', this.onPenSizeOptionClick_, this);
this.sizePicker.init(document.querySelector('.pen-size-container'));
$.subscribe(Events.PEN_SIZE_CHANGED, this.onPenSizeChanged_.bind(this));
this.updateSelectedOption_();
};
ns.PenSizeController.prototype.onPenSizeOptionClick_ = function (e) {
var size = e.target.dataset.size;
if (!isNaN(size)) {
size = parseInt(size, 10);
pskl.app.penSizeService.setPenSize(size);
}
ns.PenSizeController.prototype.onSizePickerChanged_ = function (size) {
pskl.app.penSizeService.setPenSize(size);
};
ns.PenSizeController.prototype.onPenSizeChanged_ = function (e) {
@@ -25,11 +21,7 @@
};
ns.PenSizeController.prototype.updateSelectedOption_ = function () {
pskl.utils.Dom.removeClass('selected', this.container);
var size = pskl.app.penSizeService.getPenSize();
var selectedOption = this.container.querySelector('[data-size="' + size + '"]');
if (selectedOption) {
selectedOption.classList.add('selected');
}
this.sizePicker.setSize(size);
};
})();

View File

@@ -10,9 +10,9 @@
};
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));
$.subscribe(Events.SHOW_PROGRESS, this.showProgress_.bind(this));
$.subscribe(Events.UPDATE_PROGRESS, this.updateProgress_.bind(this));
$.subscribe(Events.HIDE_PROGRESS, this.hideProgress_.bind(this));
};
ns.ProgressBarController.prototype.showProgress_ = function (event, progressInfo) {

View File

@@ -35,7 +35,8 @@
// Set SimplePen as default selected tool:
this.selectTool_(this.tools[0]);
// Activate listener on tool panel:
$('#tool-section').mousedown($.proxy(this.onToolIconClicked_, this));
var toolSection = document.querySelector('#tool-section');
toolSection.addEventListener('mousedown', this.onToolIconClicked_.bind(this));
$.subscribe(Events.SELECT_TOOL, this.onSelectToolEvent_.bind(this));
$.subscribe(Events.SHORTCUTS_CHANGED, this.createToolsDom_.bind(this));
@@ -45,14 +46,14 @@
* @private
*/
ns.ToolController.prototype.activateToolOnStage_ = function(tool) {
var stage = $('body');
var previousSelectedToolClass = stage.data('selected-tool-class');
var stage = document.body;
var previousSelectedToolClass = stage.dataset.selectedToolClass;
if (previousSelectedToolClass) {
stage.removeClass(previousSelectedToolClass);
stage.removeClass(pskl.tools.drawing.Move.TOOL_ID);
stage.classList.remove(previousSelectedToolClass);
stage.classList.remove(pskl.tools.drawing.Move.TOOL_ID);
}
stage.addClass(tool.toolId);
stage.data('selected-tool-class', tool.toolId);
stage.classList.add(tool.toolId);
stage.dataset.selectedToolClass = tool.toolId;
};
ns.ToolController.prototype.onSelectToolEvent_ = function(event, toolId) {
@@ -69,11 +70,13 @@
this.currentSelectedTool = tool;
this.activateToolOnStage_(this.currentSelectedTool);
var selectedToolElement = $('#tool-section .tool-icon.selected');
var toolElement = $('[data-tool-id=' + tool.toolId + ']');
var selectedToolElement = document.querySelector('#tool-section .tool-icon.selected');
if (selectedToolElement) {
selectedToolElement.classList.remove('selected');
}
selectedToolElement.removeClass('selected');
toolElement.addClass('selected');
var toolElement = document.querySelector('[data-tool-id=' + tool.toolId + ']');
toolElement.classList.add('selected');
$.publish(Events.TOOL_SELECTED, [tool]);
};
@@ -82,11 +85,11 @@
* @private
*/
ns.ToolController.prototype.onToolIconClicked_ = function(evt) {
var target = $(evt.target);
var clickedTool = target.closest('.tool-icon');
var target = evt.target;
var clickedTool = pskl.utils.Dom.getParentWithData(target, 'toolId');
if (clickedTool.length) {
var toolId = clickedTool.data().toolId;
if (clickedTool) {
var toolId = clickedTool.dataset.toolId;
var tool = this.getToolById_(toolId);
if (tool) {
this.selectTool_(tool);
@@ -116,7 +119,7 @@
var tool = this.tools[i];
html += this.toolIconBuilder.createIcon(tool);
}
$('#tools-container').html(html);
document.querySelector('#tools-container').innerHTML = html;
};
ns.ToolController.prototype.addKeyboardShortcuts_ = function () {

View File

@@ -1,22 +1,30 @@
(function () {
var ns = $.namespace('pskl.controller');
var SHOW_MORE_CLASS = 'show-more';
ns.TransformationsController = function () {
this.tools = [
new pskl.tools.transform.Flip(),
new pskl.tools.transform.Rotate(),
new pskl.tools.transform.Clone(),
new pskl.tools.transform.Center()
new pskl.tools.transform.Center(),
new pskl.tools.transform.Crop(),
];
this.toolIconBuilder = new pskl.tools.ToolIconBuilder();
};
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.container = document.querySelector('.transformations-container');
this.container.addEventListener('click', this.onTransformationClick_.bind(this));
this.showMoreLink = this.container.querySelector('.transformations-show-more-link');
this.showMoreLink.addEventListener('click', this.toggleShowMoreTools_.bind(this));
this.createToolsDom_();
this.updateShowMoreLink_();
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
};
ns.TransformationsController.prototype.applyTool = function (toolId, evt) {
@@ -30,13 +38,35 @@
ns.TransformationsController.prototype.onTransformationClick_ = function (evt) {
var toolId = evt.target.dataset.toolId;
this.applyTool(toolId, evt);
if (toolId) {
this.applyTool(toolId, evt);
}
};
ns.TransformationsController.prototype.toggleShowMoreTools_ = function (evt) {
var showMore = pskl.UserSettings.get(pskl.UserSettings.TRANSFORM_SHOW_MORE);
pskl.UserSettings.set(pskl.UserSettings.TRANSFORM_SHOW_MORE, !showMore);
};
ns.TransformationsController.prototype.onUserSettingsChange_ = function (evt, settingName) {
if (settingName == pskl.UserSettings.TRANSFORM_SHOW_MORE) {
this.updateShowMoreLink_();
}
};
ns.TransformationsController.prototype.updateShowMoreLink_ = function () {
var showMoreEnabled = pskl.UserSettings.get(pskl.UserSettings.TRANSFORM_SHOW_MORE);
this.container.classList.toggle(SHOW_MORE_CLASS, showMoreEnabled);
// Hide the link in case there are 4 or less tools available.
this.showMoreLink.classList.toggle('hidden', this.tools.length < 5);
};
ns.TransformationsController.prototype.createToolsDom_ = function() {
var html = this.tools.reduce(function (p, tool) {
return p + this.toolIconBuilder.createIcon(tool, 'left');
}.bind(this), '');
this.toolsContainer.innerHTML = html;
var toolsContainer = this.container.querySelector('.tools-wrapper');
toolsContainer.innerHTML = html;
};
})();

View File

@@ -0,0 +1,59 @@
(function () {
var ns = $.namespace('pskl.controller');
ns.UserWarningController = function (piskelController, currentColorsService) {
this.piskelController = piskelController;
this.currentColorsService = currentColorsService;
};
// This method is not attached to the prototype because we want to trigger it
// from markup generated for a notification message.
ns.UserWarningController.showPerformanceInfoDialog = function () {
$.publish(Events.DIALOG_SHOW, {
dialogId: 'performance-info'
});
};
ns.UserWarningController.prototype.init = function () {
$.subscribe(Events.PERFORMANCE_REPORT_CHANGED, this.onPerformanceReportChanged_.bind(this));
this.performanceLinkEl = document.querySelector('.performance-link');
pskl.utils.Event.addEventListener(
this.performanceLinkEl,
'click',
ns.UserWarningController.showPerformanceInfoDialog,
this
);
};
ns.UserWarningController.prototype.destroy = function () {
pskl.utils.Event.removeAllEventListeners(this);
this.performanceLinkEl = null;
};
ns.UserWarningController.prototype.onPerformanceReportChanged_ = function (event, report) {
var shouldDisplayWarning = report.hasProblem();
// Check if a performance warning is already displayed.
var isWarningDisplayed = this.performanceLinkEl.classList.contains('visible');
// Show/hide the performance warning link depending on the received report.
if (shouldDisplayWarning) {
this.performanceLinkEl.classList.add('visible');
} else {
this.performanceLinkEl.classList.remove('visible');
}
// Show a notification message if the new report indicates a performance issue
// and we were not displaying a warning before.
if (shouldDisplayWarning && !isWarningDisplayed) {
$.publish(Events.SHOW_NOTIFICATION, [{
'content': 'Performance problem detected, ' +
'<a href="#" style="color:red;"' +
'onclick="pskl.controller.UserWarningController.showPerformanceInfoDialog()">' +
'learn more?</a>',
'hideDelay' : 5000
}]);
}
};
})();

View File

@@ -4,14 +4,19 @@
ns.AbstractDialogController = function () {};
ns.AbstractDialogController.prototype.init = function () {
this.closeButton = document.querySelector('.dialog-close');
this.closeButton.addEventListener('click', this.closeDialog.bind(this));
var closeButton = document.querySelector('.dialog-close');
this.addEventListener(closeButton, 'click', this.closeDialog);
};
ns.AbstractDialogController.prototype.destroy = function () {};
ns.AbstractDialogController.prototype.addEventListener = function (el, type, cb) {
pskl.utils.Event.addEventListener(el, type, cb, this);
};
ns.AbstractDialogController.prototype.destroy = function () {
pskl.utils.Event.removeAllEventListeners(this);
};
ns.AbstractDialogController.prototype.closeDialog = function () {
this.destroy();
$.publish(Events.DIALOG_HIDE);
};

View File

@@ -1,8 +1,7 @@
(function () {
var ns = $.namespace('pskl.controller.dialogs');
ns.BrowseLocalController = function (piskelController) {
};
ns.BrowseLocalController = function (piskelController) {};
pskl.utils.inherit(ns.BrowseLocalController, ns.AbstractDialogController);
@@ -11,13 +10,12 @@
this.localStorageItemTemplate_ = pskl.utils.Template.get('local-storage-item-template');
this.service_ = pskl.app.localStorageService;
this.piskelList = $('.local-piskel-list');
this.prevSessionContainer = $('.previous-session');
this.service_ = pskl.app.indexedDbStorageService;
this.piskelList = document.querySelector('.local-piskel-list');
this.fillLocalPiskelsList_();
this.piskelList.click(this.onPiskelsListClick_.bind(this));
this.piskelList.addEventListener('click', this.onPiskelsListClick_.bind(this));
};
ns.BrowseLocalController.prototype.onPiskelsListClick_ = function (evt) {
@@ -37,21 +35,24 @@
};
ns.BrowseLocalController.prototype.fillLocalPiskelsList_ = function () {
var html = '';
var keys = this.service_.getKeys();
this.service_.getKeys().then(function (keys) {
var html = '';
keys.sort(function (k1, k2) {
if (k1.date < k2.date) {return 1;}
if (k1.date > k2.date) {return -1;}
return 0;
});
keys.sort(function (k1, k2) {
if (k1.date < k2.date) {return 1;}
if (k1.date > k2.date) {return -1;}
return 0;
});
keys.forEach((function (key) {
var date = pskl.utils.DateUtils.format(key.date, '{{Y}}/{{M}}/{{D}} {{H}}:{{m}}');
html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {
name : key.name,
date : date
});
}).bind(this));
keys.forEach((function (key) {
var date = pskl.utils.DateUtils.format(key.date, '{{Y}}/{{M}}/{{D}} {{H}}:{{m}}');
html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {name : key.name, date : date});
}).bind(this));
var tableBody_ = this.piskelList.get(0).tBodies[0];
tableBody_.innerHTML = html;
var tableBody_ = this.piskelList.tBodies[0];
tableBody_.innerHTML = html;
}.bind(this));
};
})();

View File

@@ -13,11 +13,12 @@
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
this.eventTrapInput = document.getElementById('cheatsheetEventTrap');
pskl.utils.Event.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_, this);
pskl.utils.Event.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_, this);
pskl.utils.Event.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_, this);
this.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_);
this.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_);
this.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_);
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_.bind(this));
this.onShortcutsChanged_ = this.onShortcutsChanged_.bind(this);
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
this.initMarkup_();
document.querySelector('.cheatsheet-helptext').setAttribute('title', this.getHelptextTitle_());
@@ -25,8 +26,11 @@
ns.CheatsheetController.prototype.destroy = function () {
this.eventTrapInput.blur();
pskl.utils.Event.removeAllEventListeners();
$.unsubscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
this.cheatsheetEl = null;
this.superclass.destroy.call(this);
};
ns.CheatsheetController.prototype.onRestoreDefaultsClick_ = function () {
@@ -140,7 +144,8 @@
title : title,
icon : descriptor.iconClass,
description : description,
key : this.formatKey_(shortcut.getDisplayKey()),
// Avoid sanitization
'!key!' : this.formatKey_(shortcut.getDisplayKey()),
className : shortcutClasses.join(' ')
});
@@ -152,10 +157,10 @@
key = key.replace('ctrl', 'cmd');
key = key.replace('alt', 'option');
}
key = key.replace(/left/i, '&#65513;');
key = key.replace(/up/i, '&#65514;');
key = key.replace(/right/i, '&#65515;');
key = key.replace(/down/i, '&#65516;');
key = key.replace(/left/i, '&larr;');
key = key.replace(/up/i, '&uarr;');
key = key.replace(/right/i, '&rarr;');
key = key.replace(/down/i, '&darr;');
key = key.replace(/>/g, '&gt;');
key = key.replace(/</g, '&lt;');
// add spaces around '+' delimiters

View File

@@ -19,12 +19,12 @@
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));
this.addEventListener(this.nameInput, 'input', this.onNameInputChange_);
this.addEventListener(this.hiddenFileInput, 'change', this.onFileInputChange_);
buttonsContainer.addEventListener('click', this.onButtonClick_.bind(this));
downloadButton.addEventListener('click', this.onDownloadButtonClick_.bind(this));
importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this));
this.addEventListener(buttonsContainer, 'click', this.onButtonClick_);
this.addEventListener(downloadButton, 'click', this.onDownloadButtonClick_);
this.addEventListener(importFileButton, 'click', this.onImportFileButtonClick_);
var colorsListContainer = document.querySelector('.colors-container');
this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer);
@@ -66,7 +66,10 @@
ns.CreatePaletteController.prototype.destroy = function () {
this.colorsListWidget.destroy();
this.superclass.destroy.call(this);
this.nameInput = null;
this.hiddenFileInput = null;
};
ns.CreatePaletteController.prototype.onButtonClick_ = function (evt) {

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