mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Compare commits
2 Commits
keyboard-c
...
greenkeepe
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5e46d8b7e2 | ||
![]() |
e15d7b2422 |
@@ -1,2 +0,0 @@
|
|||||||
# Exclude libs.
|
|
||||||
**/lib/**/*.js
|
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
# mac artifacts
|
# mac artefacts
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
|
||||||
# nodejs local installs
|
# nodejs local installs
|
||||||
@@ -15,12 +15,10 @@ cache
|
|||||||
# netbeans project folder
|
# netbeans project folder
|
||||||
nbproject
|
nbproject
|
||||||
|
|
||||||
# vscode workspace folder
|
|
||||||
.vscode
|
|
||||||
|
|
||||||
# git stackdumps
|
# git stackdumps
|
||||||
*.stackdump
|
*.stackdump
|
||||||
|
|
||||||
|
|
||||||
# diffs
|
# diffs
|
||||||
diff.txt
|
diff.txt
|
||||||
|
|
||||||
|
75
.jscsrc
Normal file
75
.jscsrc
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
@@ -1,9 +1,14 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "7.4.0"
|
- "4.1"
|
||||||
before_install:
|
before_install:
|
||||||
- npm update -g npm
|
- npm update -g npm
|
||||||
- npm install -g grunt-cli
|
- npm install -g grunt-cli
|
||||||
|
- git clone git://github.com/n1k0/casperjs.git ~/casperjs
|
||||||
|
- cd ~/casperjs
|
||||||
|
- git checkout tags/1.1.3
|
||||||
|
- export PATH=$PATH:`pwd`/bin
|
||||||
|
- cd -
|
||||||
before_script:
|
before_script:
|
||||||
- phantomjs --version
|
- phantomjs --version
|
||||||
- casperjs --version
|
- casperjs --version
|
||||||
|
70
Gruntfile.js
70
Gruntfile.js
@@ -12,7 +12,6 @@ module.exports = function(grunt) {
|
|||||||
// create a version based on the build timestamp
|
// create a version based on the build timestamp
|
||||||
var dateFormat = require('dateformat');
|
var dateFormat = require('dateformat');
|
||||||
var version = '-' + dateFormat(new Date(), "yyyy-mm-dd-hh-MM");
|
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
|
* Helper to prefix all strings in provided array with the provided path
|
||||||
@@ -83,12 +82,33 @@ module.exports = function(grunt) {
|
|||||||
css : ['src/css/**/*.css']
|
css : ['src/css/**/*.css']
|
||||||
},
|
},
|
||||||
|
|
||||||
eslint: {
|
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, 'Promise': true}
|
||||||
|
},
|
||||||
files: [
|
files: [
|
||||||
// Includes
|
// Includes
|
||||||
|
'Gruntfile.js',
|
||||||
|
'package.json',
|
||||||
'src/js/**/*.js',
|
'src/js/**/*.js',
|
||||||
// Exludes
|
// Excludes
|
||||||
// TODO: remove this (for now we still get warnings from the lib folder)
|
|
||||||
'!src/js/**/lib/**/*.js'
|
'!src/js/**/lib/**/*.js'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -174,8 +194,7 @@ module.exports = function(grunt) {
|
|||||||
dest: 'dest/tmp/index.html',
|
dest: 'dest/tmp/index.html',
|
||||||
options : {
|
options : {
|
||||||
globals : {
|
globals : {
|
||||||
'version' : version,
|
'version' : version
|
||||||
'releaseVersion' : releaseVersion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,6 +236,20 @@ module.exports = function(grunt) {
|
|||||||
src: ['dest/tmp/css/piskel-style-packaged' + version + '.css'],
|
src: ['dest/tmp/css/piskel-style-packaged' + version + '.css'],
|
||||||
dest: 'dest/prod/css/piskel-style-packaged' + version + '.css'
|
dest: 'dest/prod/css/piskel-style-packaged' + version + '.css'
|
||||||
}]
|
}]
|
||||||
|
},
|
||||||
|
// remove the fake header from the desktop build
|
||||||
|
desktop: {
|
||||||
|
options: {
|
||||||
|
patterns: [{
|
||||||
|
match: /<!--standalone-start-->(?:.|[\r\n])*<!--standalone-end-->/,
|
||||||
|
replacement: "",
|
||||||
|
description : "Remove everything between standalone-start & standalone-end"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
{src: ['dest/prod/index.html'], dest: 'dest/prod/index.html'}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -286,8 +319,7 @@ module.exports = function(grunt) {
|
|||||||
build_dir: './dest/desktop/', // destination folder of releases.
|
build_dir: './dest/desktop/', // destination folder of releases.
|
||||||
win: true,
|
win: true,
|
||||||
linux32: true,
|
linux32: true,
|
||||||
linux64: true,
|
linux64: true
|
||||||
flavor: "normal",
|
|
||||||
},
|
},
|
||||||
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
|
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
|
||||||
},
|
},
|
||||||
@@ -296,18 +328,7 @@ module.exports = function(grunt) {
|
|||||||
downloadUrl: 'https://dl.nwjs.io/',
|
downloadUrl: 'https://dl.nwjs.io/',
|
||||||
osx64: true,
|
osx64: true,
|
||||||
version : "0.19.4",
|
version : "0.19.4",
|
||||||
build_dir: './dest/desktop/',
|
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/"]
|
src: ['./dest/prod/**/*', "./package.json", "!./dest/desktop/"]
|
||||||
}
|
}
|
||||||
@@ -316,13 +337,11 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
// TEST TASKS
|
// TEST TASKS
|
||||||
// Run linting
|
// Run linting
|
||||||
grunt.registerTask('lint', ['eslint', 'leadingIndent:css']);
|
grunt.registerTask('lint', ['jscs:js', 'leadingIndent:css', 'jshint']);
|
||||||
// Run unit-tests
|
// Run unit-tests
|
||||||
grunt.registerTask('unit-test', ['karma']);
|
grunt.registerTask('unit-test', ['karma']);
|
||||||
// Run integration tests
|
// Run integration tests
|
||||||
grunt.registerTask('integration-test', ['build-dev', 'connect:test', 'casperjs:integration']);
|
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
|
// Run linting, unit tests, drawing tests and integration tests
|
||||||
grunt.registerTask('test', ['lint', 'unit-test', 'build-dev', 'connect:test', 'casperjs:drawing', 'casperjs:integration']);
|
grunt.registerTask('test', ['lint', 'unit-test', 'build-dev', 'connect:test', 'casperjs:drawing', 'casperjs:integration']);
|
||||||
|
|
||||||
@@ -337,9 +356,8 @@ module.exports = function(grunt) {
|
|||||||
grunt.registerTask('merge-statics', ['concat:js', 'concat:css', 'uglify']);
|
grunt.registerTask('merge-statics', ['concat:js', 'concat:css', 'uglify']);
|
||||||
grunt.registerTask('build', ['clean:prod', 'sprite', 'merge-statics', 'build-index.html', 'replace:mainPartial', 'replace:css', '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('build-dev', ['clean:dev', 'sprite', 'build-index.html', 'copy:dev']);
|
||||||
grunt.registerTask('desktop', ['clean:desktop', 'default', 'nwjs:windows']);
|
grunt.registerTask('desktop', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:windows']);
|
||||||
grunt.registerTask('desktop-mac', ['clean:desktop', 'default', 'nwjs:macos']);
|
grunt.registerTask('desktop-mac', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:macos']);
|
||||||
grunt.registerTask('desktop-mac-old', ['clean:desktop', 'default', 'replace:desktop', 'nwjs:macos_old']);
|
|
||||||
|
|
||||||
// SERVER TASKS
|
// SERVER TASKS
|
||||||
// Start webserver and watch for changes
|
// Start webserver and watch for changes
|
||||||
|
76
README.md
76
README.md
@@ -1,21 +1,52 @@
|
|||||||
Piskel
|
Piskel
|
||||||
======
|
======
|
||||||
|
|
||||||
[](https://travis-ci.org/piskelapp/piskel) [](http://gruntjs.com/)
|
[](https://greenkeeper.io/)
|
||||||
|
|
||||||
Piskel is an easy-to-use sprite editor. It can be used to create game sprites, animations, pixel-art...
|
[](https://travis-ci.org/juliandescottes/piskel) [](http://gruntjs.com/)
|
||||||
It is the editor used in **[piskelapp.com](http://piskelapp.com)**.
|
|
||||||
|
|
||||||
<img
|
A simple web-based tool for Spriting and Pixel art.
|
||||||
src="https://screenletstore.appspot.com/img/95aaa0f0-37a4-11e7-a652-7b8128ce3e3b.png"
|
|
||||||
title="Piskel editor screenshot"
|
|
||||||
width="500">
|
|
||||||
|
|
||||||
## About Piskel
|

|
||||||
|
|
||||||
### Built with
|
You can try the standalone editor at **http://juliandescottes.github.io/piskel** or see it integrated in **http://piskelapp.com**.
|
||||||
|
|
||||||
The Piskel editor is purely built in **JavaScript, HTML and CSS**.
|
Piskel is mainly developped by :
|
||||||
|
|
||||||
|
* **[@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
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* **pixelart** : create crazy/pretty pixelart animations for fun !
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
We also use the following **libraries** :
|
We also use the following **libraries** :
|
||||||
* [spectrum](https://github.com/bgrins/spectrum) : awesome standalone colorpicker
|
* [spectrum](https://github.com/bgrins/spectrum) : awesome standalone colorpicker
|
||||||
@@ -30,32 +61,17 @@ As well as some **icons** from the [Noun Project](http://thenounproject.com/) :
|
|||||||
* Folder by Simple Icons from The Noun Project
|
* Folder by Simple Icons from The Noun Project
|
||||||
* (and probably one or two others)
|
* (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 ?
|
## Contributing ?
|
||||||
|
|
||||||
Help is always welcome !
|
Help is always welcome !
|
||||||
|
|
||||||
* **Issues** : Found a problem when using the application, want to request a feature, [open an issue](https://github.com/piskelapp/piskel/issues).
|
* **Issues** : Found a problem when using the application, want to request a feature, [open an issue](https://github.com/juliandescottes/piskel/issues).
|
||||||
* **Development** : Have a look at the [wiki](https://github.com/piskelapp/piskel/wiki) to set up the development environment
|
* **Participate** : Have a look at the [wiki](https://github.com/juliandescottes/piskel/wiki) to set up the development environment
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright 2017 Julian Descottes
|
Copyright 2016 Julian Descottes
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -69,3 +85,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
|
## Mobile/Tablets
|
||||||
|
|
||||||
|
There is no support for mobile for now.
|
||||||
|
|
||||||
|
@@ -6,8 +6,6 @@ const fse = require('fs-extra');
|
|||||||
const PISKEL_PATH = path.resolve(__dirname, '..');
|
const PISKEL_PATH = path.resolve(__dirname, '..');
|
||||||
const PISKELAPP_PATH = path.resolve(__dirname, '../../piskel-website');
|
const PISKELAPP_PATH = path.resolve(__dirname, '../../piskel-website');
|
||||||
|
|
||||||
var pjson = require('../package.json');
|
|
||||||
|
|
||||||
// Callbacks sorted by call sequence.
|
// Callbacks sorted by call sequence.
|
||||||
function onCopy(err) {
|
function onCopy(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -17,16 +15,7 @@ function onCopy(err) {
|
|||||||
|
|
||||||
console.log('Copied static files to piskel-website...');
|
console.log('Copied static files to piskel-website...');
|
||||||
let previousPartialPath = path.resolve(PISKELAPP_PATH, 'templates/editor/main-partial.html');
|
let previousPartialPath = path.resolve(PISKELAPP_PATH, 'templates/editor/main-partial.html');
|
||||||
fs.access(previousPartialPath, fs.constants.F_OK, function (err) {
|
fs.unlink(previousPartialPath, onDeletePreviousPartial);
|
||||||
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) {
|
function onDeletePreviousPartial(err) {
|
||||||
@@ -63,17 +52,6 @@ function onDeleteTempPartial(err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('Temporary main partial deleted...');
|
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!');
|
console.log('Finished!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,80 +0,0 @@
|
|||||||
<?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>
|
|
Before Width: | Height: | Size: 3.7 KiB |
23
package.json
23
package.json
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "piskel",
|
"name": "piskel",
|
||||||
"version": "0.12.1",
|
"version": "0.10.0",
|
||||||
"description": "Pixel art editor",
|
"description": "Pixel art editor",
|
||||||
"author": "Julian Descottes <julian.descottes@gmail.com>",
|
"author": "Julian Descottes <julian.descottes@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Vincent Renaudin"
|
"Vincent Renaudin"
|
||||||
],
|
],
|
||||||
"homepage": "http://github.com/piskelapp/piskel",
|
"homepage": "http://github.com/juliandescottes/piskel",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "http://github.com/piskelapp/piskel.git"
|
"url": "http://github.com/juliandescottes/piskel.git"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dest/prod",
|
"dest/prod",
|
||||||
@@ -24,13 +24,12 @@
|
|||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
"start": "nodewebkit",
|
"start": "nodewebkit",
|
||||||
"preversion": "grunt test build",
|
"preversion": "grunt test build",
|
||||||
"postversion": "git push && git push --tags && npm publish",
|
"postversion": "git push && git push --tags && npm publish"
|
||||||
"release": "grunt && node ./bin/copy-to-piskel-website"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dateformat": "2.0.0",
|
"dateformat": "2.0.0",
|
||||||
"fs-extra": "3.0.1",
|
"fs-extra": "3.0.1",
|
||||||
"grunt": "0.4.5",
|
"grunt": "^1.0.1",
|
||||||
"grunt-casperjs": "^2.2.1",
|
"grunt-casperjs": "^2.2.1",
|
||||||
"grunt-contrib-clean": "1.1.0",
|
"grunt-contrib-clean": "1.1.0",
|
||||||
"grunt-contrib-concat": "1.0.1",
|
"grunt-contrib-concat": "1.0.1",
|
||||||
@@ -39,10 +38,9 @@
|
|||||||
"grunt-contrib-jshint": "1.1.0",
|
"grunt-contrib-jshint": "1.1.0",
|
||||||
"grunt-contrib-uglify": "2.3.0",
|
"grunt-contrib-uglify": "2.3.0",
|
||||||
"grunt-contrib-watch": "1.0.0",
|
"grunt-contrib-watch": "1.0.0",
|
||||||
"grunt-eslint": "^19.0.0",
|
"grunt-include-replace": "5.0.0",
|
||||||
"grunt-include-replace": "4.0.1",
|
"grunt-jscs": "3.0.1",
|
||||||
"grunt-jscs": "2.8.0",
|
"grunt-karma": "2.0.0",
|
||||||
"grunt-karma": "1.0.0",
|
|
||||||
"grunt-leading-indent": "0.2.0",
|
"grunt-leading-indent": "0.2.0",
|
||||||
"grunt-nw-builder": "3.1.0",
|
"grunt-nw-builder": "3.1.0",
|
||||||
"grunt-open": "0.2.3",
|
"grunt-open": "0.2.3",
|
||||||
@@ -50,9 +48,10 @@
|
|||||||
"grunt-spritesmith": "6.4.0",
|
"grunt-spritesmith": "6.4.0",
|
||||||
"jasmine-core": "2.6.1",
|
"jasmine-core": "2.6.1",
|
||||||
"karma": "1.7.0",
|
"karma": "1.7.0",
|
||||||
|
"karma-chrome-launcher": "2.1.1",
|
||||||
"karma-jasmine": "1.1.0",
|
"karma-jasmine": "1.1.0",
|
||||||
"karma-phantomjs-launcher": "1.0.4",
|
"karma-phantomjs-launcher": "1.0.4",
|
||||||
"load-grunt-tasks": "3.5.0",
|
"load-grunt-tasks": "3.5.2",
|
||||||
"phantomjs": "2.1.7",
|
"phantomjs": "2.1.7",
|
||||||
"phantomjs-polyfill-object-assign": "0.0.2",
|
"phantomjs-polyfill-object-assign": "0.0.2",
|
||||||
"promise-polyfill": "6.0.2",
|
"promise-polyfill": "6.0.2",
|
||||||
@@ -63,6 +62,6 @@
|
|||||||
"icon": "dest/prod/logo.png",
|
"icon": "dest/prod/logo.png",
|
||||||
"toolbar": false,
|
"toolbar": false,
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 700
|
"height": 500
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,144 +0,0 @@
|
|||||||
#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 .session-list-empty,
|
|
||||||
.browse-backups .snapshot-list-empty {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
width: 200px;
|
|
||||||
margin-top: 100px;
|
|
||||||
margin-left: -130px;
|
|
||||||
padding: 30px;
|
|
||||||
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid;
|
|
||||||
color: #bbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
@@ -3,19 +3,6 @@
|
|||||||
/* Browse local piskels panel */
|
/* 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 {
|
.local-piskel-list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
101
src/css/dialogs-import-image.css
Normal file
101
src/css/dialogs-import-image.css
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/************************************************************************************************/
|
||||||
|
/* 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: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
[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;
|
||||||
|
}
|
292
src/css/dialogs-import.css
vendored
292
src/css/dialogs-import.css
vendored
@@ -1,292 +0,0 @@
|
|||||||
#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;
|
|
||||||
border: 1px solid gold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.import-meta-label {
|
|
||||||
border-radius: 2px 0 0 2px;
|
|
||||||
color: var(--highlight-color);
|
|
||||||
border-right-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.import-meta-title .import-meta-label {
|
|
||||||
border-right-width: 1px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.import-meta-value {
|
|
||||||
border-radius: 0 2px 2px 0;
|
|
||||||
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-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.import-resize-option :checked + span,
|
|
||||||
.insert-mode-option :checked + span {
|
|
||||||
color: var(--highlight-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ADJUST SIZE
|
|
||||||
*/
|
|
||||||
.import-resize-anchor-info,
|
|
||||||
.import-resize-option-label {
|
|
||||||
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;
|
|
||||||
}
|
|
@@ -48,6 +48,19 @@
|
|||||||
margin-top: 0;
|
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 {
|
.dialog-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position : relative;
|
position : relative;
|
||||||
|
@@ -54,9 +54,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.add-frame-action {
|
.add-frame-action {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -74,7 +71,6 @@
|
|||||||
.add-frame-action-icon {
|
.add-frame-action-icon {
|
||||||
margin: 3px;
|
margin: 3px;
|
||||||
float: left;
|
float: left;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-frame-action .label {
|
.add-frame-action .label {
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
/***********************/
|
.pen-size-container {
|
||||||
/* SIZE PICKER WIDGET */
|
|
||||||
/***********************/
|
|
||||||
|
|
||||||
.size-picker-container {
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px 5px;
|
padding: 5px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option {
|
.pen-size-option {
|
||||||
float: left;
|
float: left;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
@@ -19,20 +15,20 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option[data-size='1'] {
|
.pen-size-option[data-size='1'] {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
.size-picker-option[data-size='2'] {
|
.pen-size-option[data-size='2'] {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
.size-picker-option[data-size='3'] {
|
.pen-size-option[data-size='3'] {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
}
|
}
|
||||||
.size-picker-option[data-size='4'] {
|
.pen-size-option[data-size='4'] {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option:before {
|
.pen-size-option:before {
|
||||||
content: '';
|
content: '';
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -43,19 +39,19 @@
|
|||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option:hover {
|
.pen-size-option:hover {
|
||||||
border-color: #888;
|
border-color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option.selected:before {
|
.pen-size-option.selected:before {
|
||||||
background-color: var(--highlight-color);
|
background-color: var(--highlight-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option.selected {
|
.pen-size-option.selected {
|
||||||
border-color: var(--highlight-color);
|
border-color: var(--highlight-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-picker-option.labeled:before {
|
.pen-size-option.labeled:before {
|
||||||
content: attr(real-size);
|
content: attr(real-pen-size);
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
@@ -5,7 +5,6 @@ html, body {
|
|||||||
cursor : default;
|
cursor : default;
|
||||||
font-family: Arial;
|
font-family: Arial;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 1.1;
|
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-khtml-user-select: none;
|
-khtml-user-select: none;
|
||||||
|
@@ -1,14 +1,6 @@
|
|||||||
/********************************/
|
/*******************************/
|
||||||
/* Preferences Settings panel */
|
/* Application Setting panel */
|
||||||
/********************************/
|
/*******************************/
|
||||||
|
|
||||||
.settings-section-preferences {
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0 20px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-picker-wrapper {
|
.background-picker-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -43,11 +35,14 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layer-opacity-input,
|
.layer-opacity-input {
|
||||||
.tile-mask-opacity-input {
|
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.seamless-opacity-input {
|
||||||
|
width: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-opacity-text {
|
.settings-opacity-text {
|
||||||
height: 31px;
|
height: 31px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -59,76 +54,16 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-item-grid-size,
|
|
||||||
.settings-item-grid-color {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-item-grid-size > label,
|
|
||||||
.settings-item-grid-color > label {
|
|
||||||
width: 65px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-item-grid-size .size-picker-option {
|
|
||||||
border-color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-item-grid-size .size-picker-option:not(.selected):hover {
|
|
||||||
border-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-width-select,
|
.grid-width-select,
|
||||||
.color-format-select {
|
.color-format-select {
|
||||||
margin: 5px 5px 0 5px;
|
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 */
|
/* Override the default 10px margin bottom for this panel */
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-section-preferences .button-primary {
|
.settings-section-application .button-primary {
|
||||||
margin-top: 10px;
|
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;
|
|
||||||
}
|
|
@@ -43,29 +43,8 @@
|
|||||||
float : left;
|
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{
|
.preview-upload-ongoing:before{
|
||||||
content: "Upload in progress...";
|
content: "Upload ongoing ...";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -121,6 +100,45 @@
|
|||||||
line-height: 23px;
|
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: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.export-tab {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.export-tab.selected,
|
||||||
|
.export-tab:hover {
|
||||||
|
color: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.export-tab.selected {
|
||||||
|
border-color: var(--highlight-color);
|
||||||
|
border-bottom-color: #444;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.export-panel-header {
|
.export-panel-header {
|
||||||
padding: 10px 5px 0px;
|
padding: 10px 5px 0px;
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,103 @@
|
|||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resize-anchor-container {
|
/*****************/
|
||||||
|
/* ANCHOR WIDGET */
|
||||||
|
/*****************/
|
||||||
|
|
||||||
|
.resize-origin-container {
|
||||||
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 70px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: inline-block;
|
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 var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: var(--highlight-color);
|
||||||
|
margin-left: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-origin-option[data-neighbor="left"]:before {
|
||||||
|
border-right-color: var(--highlight-color);
|
||||||
|
margin-top: -4px;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-origin-option[data-neighbor="top"]:before {
|
||||||
|
border-bottom-color: var(--highlight-color);
|
||||||
|
margin-top: -6px;
|
||||||
|
margin-left: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-origin-option[data-neighbor="right"]:before {
|
||||||
|
border-left-color: var(--highlight-color);
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
113
src/css/sprites.css
Normal file
113
src/css/sprites.css
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
@@ -55,10 +55,6 @@ body {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TOOLTIPS
|
* TOOLTIPS
|
||||||
*/
|
*/
|
||||||
|
@@ -76,11 +76,6 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.palettes-list-colors.tiny > .palettes-list-color {
|
|
||||||
width: calc((100% - 35px) / 10);
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palettes-list-color div {
|
.palettes-list-color div {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -126,8 +121,7 @@
|
|||||||
* Color index for the 9 first colors
|
* Color index for the 9 first colors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
:not(.tiny) > .palettes-list-color:nth-child(-n+10):after {
|
.palettes-list-color:nth-child(-n+10):after {
|
||||||
content: attr(data-color-index);
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -142,3 +136,39 @@
|
|||||||
padding: 2px 3px 2px 3px;
|
padding: 2px 3px 2px 3px;
|
||||||
border-radius: 0 0 0 2px;
|
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";
|
||||||
|
}
|
||||||
|
@@ -3,38 +3,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.transformations-container .tool-icon {
|
.transformations-container .tool-icon {
|
||||||
margin: 0 0 5px 0;
|
float:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
@@ -1,98 +0,0 @@
|
|||||||
/*****************/
|
|
||||||
/* 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;
|
|
||||||
}
|
|
@@ -1,55 +0,0 @@
|
|||||||
/***********************/
|
|
||||||
/* 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;
|
|
||||||
}
|
|
@@ -1,42 +0,0 @@
|
|||||||
/*****************/
|
|
||||||
/* 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;
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
.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: 1.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 393 B |
Binary file not shown.
Before Width: | Height: | Size: 693 B |
@@ -22,7 +22,9 @@
|
|||||||
color:white;">
|
color:white;">
|
||||||
<span style="top:45%">Loading Piskel ...</span>
|
<span style="top:45%">Loading Piskel ...</span>
|
||||||
</div>
|
</div>
|
||||||
|
<!--standalone-start-->
|
||||||
@@include('templates/debug-header.html', {})
|
@@include('templates/debug-header.html', {})
|
||||||
|
<!--standalone-end-->
|
||||||
|
|
||||||
<!-- the comment below indicates the beginning of markup reused by the editor integrated in piskelapp.com -->
|
<!-- the comment below indicates the beginning of markup reused by the editor integrated in piskelapp.com -->
|
||||||
<!-- do not delete, do not move :) -->
|
<!-- do not delete, do not move :) -->
|
||||||
@@ -67,7 +69,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@include('templates/misc-templates.html', {})
|
@@include('templates/misc-templates.html', {})
|
||||||
@@include('templates/data-uri-export.html', {})
|
|
||||||
@@include('templates/popup-preview.html', {})
|
@@include('templates/popup-preview.html', {})
|
||||||
|
|
||||||
<span class="cheatsheet-link icon-common-keyboard-gold"
|
<span class="cheatsheet-link icon-common-keyboard-gold"
|
||||||
@@ -76,19 +77,15 @@
|
|||||||
rel="tooltip" data-placement="left" title="Performance problem detected, learn more."> </div>
|
rel="tooltip" data-placement="left" title="Performance problem detected, learn more."> </div>
|
||||||
|
|
||||||
<!-- dialogs partials -->
|
<!-- dialogs partials -->
|
||||||
@@include('templates/dialogs/browse-backups.html', {})
|
@@include('templates/dialogs/create-palette.html', {})
|
||||||
|
@@include('templates/dialogs/import-image.html', {})
|
||||||
@@include('templates/dialogs/browse-local.html', {})
|
@@include('templates/dialogs/browse-local.html', {})
|
||||||
@@include('templates/dialogs/cheatsheet.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/performance-info.html', {})
|
||||||
@@include('templates/dialogs/unsupported-browser.html', {})
|
@@include('templates/dialogs/unsupported-browser.html', {})
|
||||||
|
|
||||||
<!-- settings-panel partials -->
|
<!-- settings-panel partials -->
|
||||||
@@include('templates/settings/preferences.html', {})
|
@@include('templates/settings/application.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/resize.html', {})
|
||||||
@@include('templates/settings/save.html', {})
|
@@include('templates/settings/save.html', {})
|
||||||
@@include('templates/settings/import.html', {})
|
@@include('templates/settings/import.html', {})
|
||||||
|
@@ -1,99 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -12,7 +12,7 @@ var Constants = {
|
|||||||
MAX_HEIGHT : 1024,
|
MAX_HEIGHT : 1024,
|
||||||
MAX_WIDTH : 1024,
|
MAX_WIDTH : 1024,
|
||||||
|
|
||||||
MAX_PALETTE_COLORS : 256,
|
MAX_PALETTE_COLORS : 100,
|
||||||
// allow current colors service to get up to 256 colors.
|
// allow current colors service to get up to 256 colors.
|
||||||
// GIF generation is different if the color count goes over 256.
|
// GIF generation is different if the color count goes over 256.
|
||||||
MAX_WORKER_COLORS : 256,
|
MAX_WORKER_COLORS : 256,
|
||||||
@@ -58,11 +58,8 @@ var Constants = {
|
|||||||
// The datastore limit is 1 MiB, which we roughly approximate to 1 million characters.
|
// The datastore limit is 1 MiB, which we roughly approximate to 1 million characters.
|
||||||
APPENGINE_SAVE_LIMIT : 1 * 1024 * 1024,
|
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
|
// SERVICE URLS
|
||||||
APPENGINE_SAVE_URL : 'save',
|
APPENGINE_SAVE_URL : 'save',
|
||||||
IMAGE_SERVICE_UPLOAD_URL : '{{protocol}}://piskel-imgstore-b.appspot.com/__/upload',
|
IMAGE_SERVICE_UPLOAD_URL : 'http://piskel-imgstore-b.appspot.com/__/upload',
|
||||||
IMAGE_SERVICE_GET_URL : '{{protocol}}://piskel-imgstore-b.appspot.com/img/'
|
IMAGE_SERVICE_GET_URL : 'http://piskel-imgstore-b.appspot.com/img/'
|
||||||
};
|
};
|
||||||
|
@@ -15,7 +15,7 @@ var Events = {
|
|||||||
DRAG_START : 'DRAG_START',
|
DRAG_START : 'DRAG_START',
|
||||||
DRAG_END : 'DRAG_END',
|
DRAG_END : 'DRAG_END',
|
||||||
|
|
||||||
DIALOG_SHOW : 'DIALOG_SHOW',
|
DIALOG_DISPLAY : 'DIALOG_DISPLAY',
|
||||||
DIALOG_HIDE : 'DIALOG_HIDE',
|
DIALOG_HIDE : 'DIALOG_HIDE',
|
||||||
|
|
||||||
PALETTE_LIST_UPDATED : 'PALETTE_LIST_UPDATED',
|
PALETTE_LIST_UPDATED : 'PALETTE_LIST_UPDATED',
|
||||||
@@ -64,10 +64,9 @@ var Events = {
|
|||||||
SELECTION_CREATED: 'SELECTION_CREATED',
|
SELECTION_CREATED: 'SELECTION_CREATED',
|
||||||
SELECTION_MOVE_REQUEST: 'SELECTION_MOVE_REQUEST',
|
SELECTION_MOVE_REQUEST: 'SELECTION_MOVE_REQUEST',
|
||||||
SELECTION_DISMISSED: 'SELECTION_DISMISSED',
|
SELECTION_DISMISSED: 'SELECTION_DISMISSED',
|
||||||
|
SELECTION_COPY: 'SELECTION_COPY',
|
||||||
CLIPBOARD_COPY: 'CLIPBOARD_COPY',
|
SELECTION_CUT: 'SELECTION_CUT',
|
||||||
CLIPBOARD_CUT: 'CLIPBOARD_CUT',
|
SELECTION_PASTE: 'SELECTION_PASTE',
|
||||||
CLIPBOARD_PASTE: 'CLIPBOARD_PASTE',
|
|
||||||
|
|
||||||
SHOW_NOTIFICATION: 'SHOW_NOTIFICATION',
|
SHOW_NOTIFICATION: 'SHOW_NOTIFICATION',
|
||||||
HIDE_NOTIFICATION: 'HIDE_NOTIFICATION',
|
HIDE_NOTIFICATION: 'HIDE_NOTIFICATION',
|
||||||
|
@@ -10,23 +10,14 @@
|
|||||||
ns.app = {
|
ns.app = {
|
||||||
|
|
||||||
init : function () {
|
init : function () {
|
||||||
// Run preferences migration scripts for version v0.12.0
|
|
||||||
pskl.UserSettings.migrate_to_v0_12();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When started from APP Engine, appEngineToken_ (Boolean) should be set on window.pskl
|
* When started from APP Engine, appEngineToken_ (Boolean) should be set on window.pskl
|
||||||
*/
|
*/
|
||||||
this.isAppEngineVersion = !!pskl.appEngineToken_;
|
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 = new pskl.service.keyboard.ShortcutService();
|
||||||
this.shortcutService.init();
|
this.shortcutService.init();
|
||||||
|
|
||||||
this.inputService = new pskl.service.keyboard.InputService();
|
|
||||||
this.inputService.init();
|
|
||||||
|
|
||||||
var size = pskl.UserSettings.get(pskl.UserSettings.DEFAULT_SIZE);
|
var size = pskl.UserSettings.get(pskl.UserSettings.DEFAULT_SIZE);
|
||||||
var fps = Constants.DEFAULT.FPS;
|
var fps = Constants.DEFAULT.FPS;
|
||||||
var descriptor = new pskl.model.piskel.Descriptor('New Piskel', '');
|
var descriptor = new pskl.model.piskel.Descriptor('New Piskel', '');
|
||||||
@@ -120,9 +111,6 @@
|
|||||||
this.canvasBackgroundController = new pskl.controller.CanvasBackgroundController();
|
this.canvasBackgroundController = new pskl.controller.CanvasBackgroundController();
|
||||||
this.canvasBackgroundController.init();
|
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 = new pskl.service.storage.LocalStorageService(this.piskelController);
|
||||||
this.localStorageService.init();
|
this.localStorageService.init();
|
||||||
|
|
||||||
@@ -177,9 +165,6 @@
|
|||||||
this.currentColorsService);
|
this.currentColorsService);
|
||||||
this.performanceReportService.init();
|
this.performanceReportService.init();
|
||||||
|
|
||||||
this.clipboardService = new pskl.service.ClipboardService(this.piskelController);
|
|
||||||
this.clipboardService.init();
|
|
||||||
|
|
||||||
this.drawingLoop = new pskl.rendering.DrawingLoop();
|
this.drawingLoop = new pskl.rendering.DrawingLoop();
|
||||||
this.drawingLoop.addCallback(this.render, this);
|
this.drawingLoop.addCallback(this.render, this);
|
||||||
this.drawingLoop.start();
|
this.drawingLoop.start();
|
||||||
@@ -202,16 +187,11 @@
|
|||||||
gui.Window.get().menu = mb;
|
gui.Window.get().menu = mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pskl.utils.Environment.isIntegrationTest() && pskl.utils.UserAgent.isUnsupported()) {
|
if (pskl.utils.UserAgent.isUnsupported()) {
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
dialogId : 'unsupported-browser'
|
dialogId : 'unsupported-browser'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pskl.utils.Environment.isDebug()) {
|
|
||||||
pskl.app.shortcutService.registerShortcut(pskl.service.keyboard.Shortcuts.DEBUG.RELOAD_STYLES,
|
|
||||||
window.reloadStyles);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPiskel_ : function (piskelData) {
|
loadPiskel_ : function (piskelData) {
|
||||||
|
@@ -44,7 +44,6 @@
|
|||||||
// State of drawing controller:
|
// State of drawing controller:
|
||||||
this.isClicked = false;
|
this.isClicked = false;
|
||||||
this.previousMousemoveTime = 0;
|
this.previousMousemoveTime = 0;
|
||||||
this.lastUpdateInputs_ = 0;
|
|
||||||
this.currentToolBehavior = null;
|
this.currentToolBehavior = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,16 +65,6 @@
|
|||||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.INCREASE_ZOOM, this.updateZoom_.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.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'));
|
|
||||||
|
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_UP, this.updateCursor_.bind(this, 'up'));
|
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_RIGHT, this.updateCursor_.bind(this, 'right'));
|
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_DOWN, this.updateCursor_.bind(this, 'down'));
|
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.CURSOR_LEFT, this.updateCursor_.bind(this, 'left'));
|
|
||||||
|
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
this.afterWindowResize_();
|
this.afterWindowResize_();
|
||||||
this.resetZoom_();
|
this.resetZoom_();
|
||||||
@@ -163,10 +152,6 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.DrawingController.prototype.onMousedown_ = function (event) {
|
ns.DrawingController.prototype.onMousedown_ = function (event) {
|
||||||
if (this.isClicked) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.publish(Events.MOUSE_EVENT, [event, this]);
|
$.publish(Events.MOUSE_EVENT, [event, this]);
|
||||||
var frame = this.piskelController.getCurrentFrame();
|
var frame = this.piskelController.getCurrentFrame();
|
||||||
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
|
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
|
||||||
@@ -215,7 +200,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger tool move on key up in order to acknowledge modifier changes.
|
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.DrawingController.prototype.onKeyup_ = function (event) {
|
ns.DrawingController.prototype.onKeyup_ = function (event) {
|
||||||
@@ -278,106 +262,6 @@
|
|||||||
this.updateZoom_(modifier, coords);
|
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
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.updateCursor_ = function (dir) {
|
|
||||||
var x = this.currentX || 0;
|
|
||||||
var y = this.currentY || 0;
|
|
||||||
if (dir === 'up') {
|
|
||||||
y -= 1;
|
|
||||||
} else if (dir === 'right') {
|
|
||||||
x += 1;
|
|
||||||
} else if (dir === 'down') {
|
|
||||||
y += 1;
|
|
||||||
} else if (dir === 'left') {
|
|
||||||
x -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentX = x;
|
|
||||||
this.currentY = y;
|
|
||||||
|
|
||||||
var screenCoordinates = this.getScreenCoordinates(x, y);
|
|
||||||
|
|
||||||
var event = {
|
|
||||||
'type': 'mousemove',
|
|
||||||
'button': 0,
|
|
||||||
'shiftKey': false,
|
|
||||||
'altKey': false,
|
|
||||||
'ctrlKey': false
|
|
||||||
};
|
|
||||||
|
|
||||||
event.clientX = screenCoordinates.x;
|
|
||||||
event.clientY = screenCoordinates.y;
|
|
||||||
|
|
||||||
this.onMousemove_(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.DrawingController.prototype.clickCursor_ = function () {
|
|
||||||
var x = this.currentX || 0;
|
|
||||||
var y = this.currentY || 0;
|
|
||||||
|
|
||||||
var screenCoordinates = this.getScreenCoordinates(x, y);
|
|
||||||
|
|
||||||
var event = {
|
|
||||||
'type': 'mousedown',
|
|
||||||
'button': 0,
|
|
||||||
'shiftKey': false,
|
|
||||||
'altKey': false,
|
|
||||||
'ctrlKey': false
|
|
||||||
};
|
|
||||||
|
|
||||||
event.clientX = screenCoordinates.x;
|
|
||||||
event.clientY = screenCoordinates.y;
|
|
||||||
|
|
||||||
this.onMousedown_(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.DrawingController.prototype.releaseCursor_ = function () {
|
|
||||||
var x = this.currentX || 0;
|
|
||||||
var y = this.currentY || 0;
|
|
||||||
|
|
||||||
var screenCoordinates = this.getScreenCoordinates(x, y);
|
|
||||||
|
|
||||||
var event = {
|
|
||||||
'type': 'mouseup',
|
|
||||||
'button': 0,
|
|
||||||
'shiftKey': false,
|
|
||||||
'altKey': false,
|
|
||||||
'ctrlKey': false
|
|
||||||
};
|
|
||||||
|
|
||||||
event.clientX = screenCoordinates.x;
|
|
||||||
event.clientY = screenCoordinates.y;
|
|
||||||
|
|
||||||
this.onMouseup_(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the current zoom level by a given multiplier.
|
* Update the current zoom level by a given multiplier.
|
||||||
*
|
*
|
||||||
@@ -517,20 +401,6 @@
|
|||||||
|
|
||||||
this.renderer.render(currentFrame);
|
this.renderer.render(currentFrame);
|
||||||
this.overlayRenderer.render(this.overlayFrame);
|
this.overlayRenderer.render(this.overlayFrame);
|
||||||
|
|
||||||
this.updateInputs_();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.DrawingController.prototype.updateInputs_ = function () {
|
|
||||||
var shortcuts = pskl.service.keyboard.Shortcuts;
|
|
||||||
|
|
||||||
if (pskl.app.inputService.isKeyPressed(shortcuts.MISC.CURSOR_CLICK)) {
|
|
||||||
this.clickCursor_();
|
|
||||||
this.isClickingCursor_ = true;
|
|
||||||
} else if (this.isClickingCursor_) {
|
|
||||||
this.releaseCursor_();
|
|
||||||
this.isClickingCursor_ = false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
this.rootEl.addEventListener('click', this.onClick_.bind(this));
|
this.rootEl.addEventListener('click', this.onClick_.bind(this));
|
||||||
this.toggleLayerPreviewEl.addEventListener('click', this.toggleLayerPreview_.bind(this));
|
this.toggleLayerPreviewEl.addEventListener('click', this.toggleLayerPreview_.bind(this));
|
||||||
|
|
||||||
this.createButtonTooltips_();
|
|
||||||
this.initToggleLayerPreview_();
|
this.initToggleLayerPreview_();
|
||||||
|
|
||||||
this.renderLayerList_();
|
this.renderLayerList_();
|
||||||
@@ -46,26 +45,6 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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 () {
|
ns.LayersListController.prototype.initToggleLayerPreview_ = function () {
|
||||||
var descriptors = [{description : 'Opacity defined in PREFERENCES'}];
|
var descriptors = [{description : 'Opacity defined in PREFERENCES'}];
|
||||||
var helpText = 'Preview all layers';
|
var helpText = 'Preview all layers';
|
||||||
@@ -138,7 +117,7 @@
|
|||||||
var el = evt.target || evt.srcElement;
|
var el = evt.target || evt.srcElement;
|
||||||
var index;
|
var index;
|
||||||
if (el.classList.contains('button')) {
|
if (el.classList.contains('button')) {
|
||||||
this.onButtonClick_(el, evt);
|
this.onButtonClick_(el);
|
||||||
} else if (el.classList.contains('layer-name')) {
|
} else if (el.classList.contains('layer-name')) {
|
||||||
index = pskl.utils.Dom.getData(el, 'layerIndex');
|
index = pskl.utils.Dom.getData(el, 'layerIndex');
|
||||||
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
|
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
|
||||||
@@ -166,18 +145,14 @@
|
|||||||
this.renderLayerList_();
|
this.renderLayerList_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.LayersListController.prototype.onButtonClick_ = function (button, evt) {
|
ns.LayersListController.prototype.onButtonClick_ = function (button) {
|
||||||
var action = button.getAttribute('data-action');
|
var action = button.getAttribute('data-action');
|
||||||
if (action == 'up') {
|
if (action == 'up') {
|
||||||
this.piskelController.moveLayerUp(evt.shiftKey);
|
this.piskelController.moveLayerUp();
|
||||||
} else if (action == 'down') {
|
} else if (action == 'down') {
|
||||||
this.piskelController.moveLayerDown(evt.shiftKey);
|
this.piskelController.moveLayerDown();
|
||||||
} else if (action == 'add') {
|
} else if (action == 'add') {
|
||||||
if (evt.shiftKey) {
|
this.piskelController.createLayer();
|
||||||
this.piskelController.duplicateCurrentLayer();
|
|
||||||
} else {
|
|
||||||
this.piskelController.createLayer();
|
|
||||||
}
|
|
||||||
} else if (action == 'delete') {
|
} else if (action == 'delete') {
|
||||||
this.piskelController.removeCurrentLayer();
|
this.piskelController.removeCurrentLayer();
|
||||||
} else if (action == 'merge') {
|
} else if (action == 'merge') {
|
||||||
|
@@ -51,17 +51,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PalettesListController.prototype.fillColorListContainer = function () {
|
ns.PalettesListController.prototype.fillColorListContainer = function () {
|
||||||
|
|
||||||
var colors = this.getSelectedPaletteColors_();
|
var colors = this.getSelectedPaletteColors_();
|
||||||
|
|
||||||
if (colors.length > 0) {
|
if (colors.length > 0) {
|
||||||
var html = colors.filter(function (color) {
|
var html = colors.map(function (color, index) {
|
||||||
return !!color;
|
return pskl.utils.Template.replace(this.paletteColorTemplate_, {color : color, index : index});
|
||||||
}).map(function (color, index) {
|
|
||||||
return pskl.utils.Template.replace(this.paletteColorTemplate_, {
|
|
||||||
color : color,
|
|
||||||
index : index + 1,
|
|
||||||
title : color.toUpperCase()
|
|
||||||
});
|
|
||||||
}.bind(this)).join('');
|
}.bind(this)).join('');
|
||||||
this.colorListContainer_.innerHTML = html;
|
this.colorListContainer_.innerHTML = html;
|
||||||
|
|
||||||
@@ -69,10 +64,6 @@
|
|||||||
} else {
|
} else {
|
||||||
this.colorListContainer_.innerHTML = pskl.utils.Template.get('palettes-list-no-colors-partial');
|
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) {
|
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
|
||||||
@@ -110,7 +101,7 @@
|
|||||||
var currentIndex = 0;
|
var currentIndex = 0;
|
||||||
var selectedColor = document.querySelector('.' + PRIMARY_COLOR_CLASSNAME);
|
var selectedColor = document.querySelector('.' + PRIMARY_COLOR_CLASSNAME);
|
||||||
if (selectedColor) {
|
if (selectedColor) {
|
||||||
currentIndex = parseInt(selectedColor.dataset.colorIndex, 10) - 1;
|
currentIndex = parseInt(selectedColor.dataset.colorIndex, 10);
|
||||||
}
|
}
|
||||||
return currentIndex;
|
return currentIndex;
|
||||||
};
|
};
|
||||||
@@ -148,14 +139,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PalettesListController.prototype.onCreatePaletteClick_ = function (evt) {
|
ns.PalettesListController.prototype.onCreatePaletteClick_ = function (evt) {
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
dialogId : 'create-palette'
|
dialogId : 'create-palette'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PalettesListController.prototype.onEditPaletteClick_ = function (evt) {
|
ns.PalettesListController.prototype.onEditPaletteClick_ = function (evt) {
|
||||||
var paletteId = this.colorPaletteSelect_.value;
|
var paletteId = this.colorPaletteSelect_.value;
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
dialogId : 'create-palette',
|
dialogId : 'create-palette',
|
||||||
initArgs : paletteId
|
initArgs : paletteId
|
||||||
});
|
});
|
||||||
|
@@ -1,19 +1,23 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.controller');
|
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 () {
|
ns.PenSizeController.prototype.init = function () {
|
||||||
this.sizePicker.init(document.querySelector('.pen-size-container'));
|
this.container = document.querySelector('.pen-size-container');
|
||||||
|
pskl.utils.Event.addEventListener(this.container, 'click', this.onPenSizeOptionClick_, this);
|
||||||
|
|
||||||
$.subscribe(Events.PEN_SIZE_CHANGED, this.onPenSizeChanged_.bind(this));
|
$.subscribe(Events.PEN_SIZE_CHANGED, this.onPenSizeChanged_.bind(this));
|
||||||
|
|
||||||
this.updateSelectedOption_();
|
this.updateSelectedOption_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PenSizeController.prototype.onSizePickerChanged_ = function (size) {
|
ns.PenSizeController.prototype.onPenSizeOptionClick_ = function (e) {
|
||||||
pskl.app.penSizeService.setPenSize(size);
|
var size = e.target.dataset.size;
|
||||||
|
if (!isNaN(size)) {
|
||||||
|
size = parseInt(size, 10);
|
||||||
|
pskl.app.penSizeService.setPenSize(size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PenSizeController.prototype.onPenSizeChanged_ = function (e) {
|
ns.PenSizeController.prototype.onPenSizeChanged_ = function (e) {
|
||||||
@@ -21,7 +25,19 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PenSizeController.prototype.updateSelectedOption_ = function () {
|
ns.PenSizeController.prototype.updateSelectedOption_ = function () {
|
||||||
|
pskl.utils.Dom.removeClass('labeled', this.container);
|
||||||
|
pskl.utils.Dom.removeClass('selected', this.container);
|
||||||
var size = pskl.app.penSizeService.getPenSize();
|
var size = pskl.app.penSizeService.getPenSize();
|
||||||
this.sizePicker.setSize(size);
|
var selectedOption;
|
||||||
|
if (size <= 4) {
|
||||||
|
selectedOption = this.container.querySelector('[data-size="' + size + '"]');
|
||||||
|
} else {
|
||||||
|
selectedOption = this.container.querySelector('[data-size="4"]');
|
||||||
|
selectedOption.classList.add('labeled');
|
||||||
|
selectedOption.setAttribute('real-pen-size', size);
|
||||||
|
}
|
||||||
|
if (selectedOption) {
|
||||||
|
selectedOption.classList.add('selected');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -1,30 +1,22 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.controller');
|
var ns = $.namespace('pskl.controller');
|
||||||
var SHOW_MORE_CLASS = 'show-more';
|
|
||||||
|
|
||||||
ns.TransformationsController = function () {
|
ns.TransformationsController = function () {
|
||||||
this.tools = [
|
this.tools = [
|
||||||
new pskl.tools.transform.Flip(),
|
new pskl.tools.transform.Flip(),
|
||||||
new pskl.tools.transform.Rotate(),
|
new pskl.tools.transform.Rotate(),
|
||||||
new pskl.tools.transform.Clone(),
|
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();
|
this.toolIconBuilder = new pskl.tools.ToolIconBuilder();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.TransformationsController.prototype.init = function () {
|
ns.TransformationsController.prototype.init = function () {
|
||||||
this.container = document.querySelector('.transformations-container');
|
var container = document.querySelector('.transformations-container');
|
||||||
this.container.addEventListener('click', this.onTransformationClick_.bind(this));
|
this.toolsContainer = container.querySelector('.tools-wrapper');
|
||||||
|
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.createToolsDom_();
|
||||||
this.updateShowMoreLink_();
|
|
||||||
|
|
||||||
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.TransformationsController.prototype.applyTool = function (toolId, evt) {
|
ns.TransformationsController.prototype.applyTool = function (toolId, evt) {
|
||||||
@@ -38,35 +30,13 @@
|
|||||||
|
|
||||||
ns.TransformationsController.prototype.onTransformationClick_ = function (evt) {
|
ns.TransformationsController.prototype.onTransformationClick_ = function (evt) {
|
||||||
var toolId = evt.target.dataset.toolId;
|
var toolId = evt.target.dataset.toolId;
|
||||||
if (toolId) {
|
this.applyTool(toolId, evt);
|
||||||
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() {
|
ns.TransformationsController.prototype.createToolsDom_ = function() {
|
||||||
var html = this.tools.reduce(function (p, tool) {
|
var html = this.tools.reduce(function (p, tool) {
|
||||||
return p + this.toolIconBuilder.createIcon(tool, 'left');
|
return p + this.toolIconBuilder.createIcon(tool, 'left');
|
||||||
}.bind(this), '');
|
}.bind(this), '');
|
||||||
var toolsContainer = this.container.querySelector('.tools-wrapper');
|
this.toolsContainer.innerHTML = html;
|
||||||
toolsContainer.innerHTML = html;
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
// This method is not attached to the prototype because we want to trigger it
|
// This method is not attached to the prototype because we want to trigger it
|
||||||
// from markup generated for a notification message.
|
// from markup generated for a notification message.
|
||||||
ns.UserWarningController.showPerformanceInfoDialog = function () {
|
ns.UserWarningController.showPerformanceInfoDialog = function () {
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
dialogId: 'performance-info'
|
dialogId: 'performance-info'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@@ -4,19 +4,14 @@
|
|||||||
ns.AbstractDialogController = function () {};
|
ns.AbstractDialogController = function () {};
|
||||||
|
|
||||||
ns.AbstractDialogController.prototype.init = function () {
|
ns.AbstractDialogController.prototype.init = function () {
|
||||||
var closeButton = document.querySelector('.dialog-close');
|
this.closeButton = document.querySelector('.dialog-close');
|
||||||
this.addEventListener(closeButton, 'click', this.closeDialog);
|
this.closeButton.addEventListener('click', this.closeDialog.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AbstractDialogController.prototype.addEventListener = function (el, type, cb) {
|
ns.AbstractDialogController.prototype.destroy = function () {};
|
||||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractDialogController.prototype.destroy = function () {
|
|
||||||
pskl.utils.Event.removeAllEventListeners(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractDialogController.prototype.closeDialog = function () {
|
ns.AbstractDialogController.prototype.closeDialog = function () {
|
||||||
|
this.destroy();
|
||||||
$.publish(Events.DIALOG_HIDE);
|
$.publish(Events.DIALOG_HIDE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.controller.dialogs');
|
var ns = $.namespace('pskl.controller.dialogs');
|
||||||
|
|
||||||
ns.BrowseLocalController = function (piskelController) {};
|
ns.BrowseLocalController = function (piskelController) {
|
||||||
|
};
|
||||||
|
|
||||||
pskl.utils.inherit(ns.BrowseLocalController, ns.AbstractDialogController);
|
pskl.utils.inherit(ns.BrowseLocalController, ns.AbstractDialogController);
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
|
|
||||||
this.localStorageItemTemplate_ = pskl.utils.Template.get('local-storage-item-template');
|
this.localStorageItemTemplate_ = pskl.utils.Template.get('local-storage-item-template');
|
||||||
|
|
||||||
this.service_ = pskl.app.indexedDbStorageService;
|
this.service_ = pskl.app.localStorageService;
|
||||||
this.piskelList = $('.local-piskel-list');
|
this.piskelList = $('.local-piskel-list');
|
||||||
this.prevSessionContainer = $('.previous-session');
|
this.prevSessionContainer = $('.previous-session');
|
||||||
|
|
||||||
@@ -36,24 +37,24 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.BrowseLocalController.prototype.fillLocalPiskelsList_ = function () {
|
ns.BrowseLocalController.prototype.fillLocalPiskelsList_ = function () {
|
||||||
this.service_.getKeys().then(function (keys) {
|
var html = '';
|
||||||
var html = '';
|
var keys = this.service_.getKeys();
|
||||||
keys.sort(function (k1, k2) {
|
|
||||||
if (k1.date < k2.date) {return 1;}
|
keys.sort(function (k1, k2) {
|
||||||
if (k1.date > k2.date) {return -1;}
|
if (k1.date < k2.date) {return 1;}
|
||||||
return 0;
|
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 tableBody_ = this.piskelList.get(0).tBodies[0];
|
||||||
var date = pskl.utils.DateUtils.format(key.date, '{{Y}}/{{M}}/{{D}} {{H}}:{{m}}');
|
tableBody_.innerHTML = html;
|
||||||
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;
|
|
||||||
}.bind(this));
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -13,12 +13,11 @@
|
|||||||
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
|
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
|
||||||
this.eventTrapInput = document.getElementById('cheatsheetEventTrap');
|
this.eventTrapInput = document.getElementById('cheatsheetEventTrap');
|
||||||
|
|
||||||
this.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_);
|
pskl.utils.Event.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_, this);
|
||||||
this.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_);
|
pskl.utils.Event.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_, this);
|
||||||
this.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_);
|
pskl.utils.Event.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_, this);
|
||||||
|
|
||||||
this.onShortcutsChanged_ = this.onShortcutsChanged_.bind(this);
|
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_.bind(this));
|
||||||
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
|
|
||||||
|
|
||||||
this.initMarkup_();
|
this.initMarkup_();
|
||||||
document.querySelector('.cheatsheet-helptext').setAttribute('title', this.getHelptextTitle_());
|
document.querySelector('.cheatsheet-helptext').setAttribute('title', this.getHelptextTitle_());
|
||||||
@@ -26,11 +25,8 @@
|
|||||||
|
|
||||||
ns.CheatsheetController.prototype.destroy = function () {
|
ns.CheatsheetController.prototype.destroy = function () {
|
||||||
this.eventTrapInput.blur();
|
this.eventTrapInput.blur();
|
||||||
|
pskl.utils.Event.removeAllEventListeners();
|
||||||
$.unsubscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
|
|
||||||
this.cheatsheetEl = null;
|
this.cheatsheetEl = null;
|
||||||
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.CheatsheetController.prototype.onRestoreDefaultsClick_ = function () {
|
ns.CheatsheetController.prototype.onRestoreDefaultsClick_ = function () {
|
||||||
@@ -144,8 +140,7 @@
|
|||||||
title : title,
|
title : title,
|
||||||
icon : descriptor.iconClass,
|
icon : descriptor.iconClass,
|
||||||
description : description,
|
description : description,
|
||||||
// Avoid sanitization
|
key : this.formatKey_(shortcut.getDisplayKey()),
|
||||||
'!key!' : this.formatKey_(shortcut.getDisplayKey()),
|
|
||||||
className : shortcutClasses.join(' ')
|
className : shortcutClasses.join(' ')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -19,12 +19,12 @@
|
|||||||
var downloadButton = document.querySelector('.create-palette-download-button');
|
var downloadButton = document.querySelector('.create-palette-download-button');
|
||||||
var importFileButton = document.querySelector('.create-palette-import-button');
|
var importFileButton = document.querySelector('.create-palette-import-button');
|
||||||
|
|
||||||
this.addEventListener(this.nameInput, 'input', this.onNameInputChange_);
|
this.nameInput.addEventListener('input', this.onNameInputChange_.bind(this));
|
||||||
this.addEventListener(this.hiddenFileInput, 'change', this.onFileInputChange_);
|
this.hiddenFileInput.addEventListener('change', this.onFileInputChange_.bind(this));
|
||||||
|
|
||||||
this.addEventListener(buttonsContainer, 'click', this.onButtonClick_);
|
buttonsContainer.addEventListener('click', this.onButtonClick_.bind(this));
|
||||||
this.addEventListener(downloadButton, 'click', this.onDownloadButtonClick_);
|
downloadButton.addEventListener('click', this.onDownloadButtonClick_.bind(this));
|
||||||
this.addEventListener(importFileButton, 'click', this.onImportFileButtonClick_);
|
importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this));
|
||||||
|
|
||||||
var colorsListContainer = document.querySelector('.colors-container');
|
var colorsListContainer = document.querySelector('.colors-container');
|
||||||
this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer);
|
this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer);
|
||||||
@@ -66,10 +66,7 @@
|
|||||||
|
|
||||||
ns.CreatePaletteController.prototype.destroy = function () {
|
ns.CreatePaletteController.prototype.destroy = function () {
|
||||||
this.colorsListWidget.destroy();
|
this.colorsListWidget.destroy();
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
|
|
||||||
this.nameInput = null;
|
this.nameInput = null;
|
||||||
this.hiddenFileInput = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.CreatePaletteController.prototype.onButtonClick_ = function (evt) {
|
ns.CreatePaletteController.prototype.onButtonClick_ = function (evt) {
|
||||||
|
@@ -14,9 +14,9 @@
|
|||||||
template : 'templates/dialogs/browse-local.html',
|
template : 'templates/dialogs/browse-local.html',
|
||||||
controller : ns.BrowseLocalController
|
controller : ns.BrowseLocalController
|
||||||
},
|
},
|
||||||
'import' : {
|
'import-image' : {
|
||||||
template : 'templates/dialogs/import.html',
|
template : 'templates/dialogs/import-image.html',
|
||||||
controller : ns.importwizard.ImportWizard
|
controller : ns.ImportImageController
|
||||||
},
|
},
|
||||||
'performance-info' : {
|
'performance-info' : {
|
||||||
template : 'templates/dialogs/performance-info.html',
|
template : 'templates/dialogs/performance-info.html',
|
||||||
@@ -25,10 +25,6 @@
|
|||||||
'unsupported-browser' : {
|
'unsupported-browser' : {
|
||||||
template : 'templates/dialogs/unsupported-browser.html',
|
template : 'templates/dialogs/unsupported-browser.html',
|
||||||
controller : ns.UnsupportedBrowserController
|
controller : ns.UnsupportedBrowserController
|
||||||
},
|
|
||||||
'browse-backups' : {
|
|
||||||
template : 'templates/dialogs/browse-backups.html',
|
|
||||||
controller : ns.backups.BrowseBackups
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,7 +38,7 @@
|
|||||||
this.dialogContainer_ = document.getElementById('dialog-container');
|
this.dialogContainer_ = document.getElementById('dialog-container');
|
||||||
this.dialogWrapper_ = document.getElementById('dialog-container-wrapper');
|
this.dialogWrapper_ = document.getElementById('dialog-container-wrapper');
|
||||||
|
|
||||||
$.subscribe(Events.DIALOG_SHOW, this.onDialogDisplayEvent_.bind(this));
|
$.subscribe(Events.DIALOG_DISPLAY, this.onDialogDisplayEvent_.bind(this));
|
||||||
$.subscribe(Events.DIALOG_HIDE, this.hideDialog.bind(this));
|
$.subscribe(Events.DIALOG_HIDE, this.hideDialog.bind(this));
|
||||||
|
|
||||||
var createPaletteShortcut = pskl.service.keyboard.Shortcuts.COLOR.CREATE_PALETTE;
|
var createPaletteShortcut = pskl.service.keyboard.Shortcuts.COLOR.CREATE_PALETTE;
|
||||||
@@ -55,6 +51,7 @@
|
|||||||
// adding the .animated class here instead of in the markup to avoid an animation during app startup
|
// adding the .animated class here instead of in the markup to avoid an animation during app startup
|
||||||
this.dialogWrapper_.classList.add('animated');
|
this.dialogWrapper_.classList.add('animated');
|
||||||
pskl.utils.Event.addEventListener(this.dialogWrapper_, 'click', this.onWrapperClicked_, this);
|
pskl.utils.Event.addEventListener(this.dialogWrapper_, 'click', this.onWrapperClicked_, this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DialogsController.prototype.onCreatePaletteShortcut_ = function () {
|
ns.DialogsController.prototype.onCreatePaletteShortcut_ = function () {
|
||||||
|
261
src/js/controller/dialogs/ImportImageController.js
Normal file
261
src/js/controller/dialogs/ImportImageController.js
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.controller.dialogs');
|
||||||
|
|
||||||
|
ns.ImportImageController = function (piskelController) {
|
||||||
|
this.importedImage_ = null;
|
||||||
|
this.file_ = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
pskl.utils.inherit(ns.ImportImageController, ns.AbstractDialogController);
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.init = function (file) {
|
||||||
|
this.superclass.init.call(this);
|
||||||
|
|
||||||
|
this.file_ = file;
|
||||||
|
|
||||||
|
this.importPreview = $('.import-section-preview');
|
||||||
|
|
||||||
|
this.fileNameContainer = $('.import-image-file-name');
|
||||||
|
|
||||||
|
this.importType = $('[name=import-type]');
|
||||||
|
|
||||||
|
this.resizeWidth = $('[name=resize-width]');
|
||||||
|
this.resizeHeight = $('[name=resize-height]');
|
||||||
|
this.smoothResize = $('[name=smooth-resize-checkbox]');
|
||||||
|
|
||||||
|
this.frameSizeX = $('[name=frame-size-x]');
|
||||||
|
this.frameSizeY = $('[name=frame-size-y]');
|
||||||
|
this.frameOffsetX = $('[name=frame-offset-x]');
|
||||||
|
this.frameOffsetY = $('[name=frame-offset-y]');
|
||||||
|
|
||||||
|
this.importType.change(this.onImportTypeChange_.bind(this));
|
||||||
|
|
||||||
|
this.resizeWidth.keyup(this.onResizeInputKeyUp_.bind(this, 'width'));
|
||||||
|
this.resizeHeight.keyup(this.onResizeInputKeyUp_.bind(this, 'height'));
|
||||||
|
this.frameSizeX.keyup(this.onFrameInputKeyUp_.bind(this, 'frameSizeX'));
|
||||||
|
this.frameSizeY.keyup(this.onFrameInputKeyUp_.bind(this, 'frameSizeY'));
|
||||||
|
this.frameOffsetX.keyup(this.onFrameInputKeyUp_.bind(this, 'frameOffsetX'));
|
||||||
|
this.frameOffsetY.keyup(this.onFrameInputKeyUp_.bind(this, 'frameOffsetY'));
|
||||||
|
|
||||||
|
this.importImageForm = $('[name=import-image-form]');
|
||||||
|
this.importImageForm.submit(this.onImportFormSubmit_.bind(this));
|
||||||
|
|
||||||
|
pskl.utils.FileUtils.readImageFile(this.file_, this.onImageLoaded_.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.onImportTypeChange_ = function (evt) {
|
||||||
|
if (this.getImportType_() === 'single') {
|
||||||
|
// Using single image, so remove the frame grid
|
||||||
|
this.hideFrameGrid_();
|
||||||
|
} else {
|
||||||
|
// Using spritesheet import, so draw the frame grid in the preview
|
||||||
|
var x = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
||||||
|
var y = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
||||||
|
var w = this.sanitizeInputValue_(this.frameSizeX, 1);
|
||||||
|
var h = this.sanitizeInputValue_(this.frameSizeY, 1);
|
||||||
|
this.drawFrameGrid_(x, y, w, h);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.onImportFormSubmit_ = function (evt) {
|
||||||
|
evt.originalEvent.preventDefault();
|
||||||
|
this.importImageToPiskel_();
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.onResizeInputKeyUp_ = function (from, evt) {
|
||||||
|
if (this.importedImage_) {
|
||||||
|
this.synchronizeResizeFields_(evt.target.value, from);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.onFrameInputKeyUp_ = function (from, evt) {
|
||||||
|
if (this.importedImage_) {
|
||||||
|
this.synchronizeFrameFields_(evt.target.value, from);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.synchronizeResizeFields_ = function (value, from) {
|
||||||
|
value = parseInt(value, 10);
|
||||||
|
if (isNaN(value)) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
var height = this.importedImage_.height;
|
||||||
|
var width = this.importedImage_.width;
|
||||||
|
|
||||||
|
// Select single image import type since the user changed a value here
|
||||||
|
this.importType.filter('[value="single"]').attr('checked', 'checked');
|
||||||
|
|
||||||
|
if (from === 'width') {
|
||||||
|
this.resizeHeight.val(Math.round(value * height / width));
|
||||||
|
} else {
|
||||||
|
this.resizeWidth.val(Math.round(value * width / height));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.synchronizeFrameFields_ = function (value, from) {
|
||||||
|
value = parseInt(value, 10);
|
||||||
|
if (isNaN(value)) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the frame input values
|
||||||
|
var frameSizeX = this.sanitizeInputValue_(this.frameSizeX, 1);
|
||||||
|
var frameSizeY = this.sanitizeInputValue_(this.frameSizeY, 1);
|
||||||
|
var frameOffsetX = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
||||||
|
var frameOffsetY = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
||||||
|
|
||||||
|
// Select spritesheet import type since the user changed a value here
|
||||||
|
this.importType.filter('[value="sheet"]').attr('checked', 'checked');
|
||||||
|
|
||||||
|
// Draw the grid
|
||||||
|
this.drawFrameGrid_(frameOffsetX, frameOffsetY, frameSizeX, frameSizeY);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.sanitizeInputValue_ = function(input, minValue) {
|
||||||
|
var value = parseInt(input.val(), 10);
|
||||||
|
if (value <= minValue || isNaN(value)) {
|
||||||
|
input.val(minValue);
|
||||||
|
value = minValue;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.getImportType_ = function () {
|
||||||
|
return this.importType.filter(':checked').val();
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.onImageLoaded_ = function (image) {
|
||||||
|
this.importedImage_ = image;
|
||||||
|
|
||||||
|
var w = this.importedImage_.width;
|
||||||
|
var h = this.importedImage_.height;
|
||||||
|
|
||||||
|
// FIXME : We remove the onload callback here because JsGif will insert
|
||||||
|
// the image again and we want to avoid retriggering the image onload
|
||||||
|
this.importedImage_.onload = function () {};
|
||||||
|
|
||||||
|
var fileName = this.extractFileNameFromPath_(this.file_.name);
|
||||||
|
this.fileNameContainer.text(fileName);
|
||||||
|
this.fileNameContainer.attr('title', fileName);
|
||||||
|
|
||||||
|
this.resizeWidth.val(w);
|
||||||
|
this.resizeHeight.val(h);
|
||||||
|
|
||||||
|
this.frameSizeX.val(w);
|
||||||
|
this.frameSizeY.val(h);
|
||||||
|
this.frameOffsetX.val(0);
|
||||||
|
this.frameOffsetY.val(0);
|
||||||
|
|
||||||
|
this.importPreview.width('auto');
|
||||||
|
this.importPreview.height('auto');
|
||||||
|
this.importPreview.html('');
|
||||||
|
this.importPreview.append(this.createImagePreview_());
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.createImagePreview_ = function () {
|
||||||
|
var image = document.createElement('IMG');
|
||||||
|
image.src = this.importedImage_.src;
|
||||||
|
return image;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.extractFileNameFromPath_ = function (path) {
|
||||||
|
var parts = [];
|
||||||
|
if (path.indexOf('/') !== -1) {
|
||||||
|
parts = path.split('/');
|
||||||
|
} else if (path.indexOf('\\') !== -1) {
|
||||||
|
parts = path.split('\\');
|
||||||
|
} else {
|
||||||
|
parts = [path];
|
||||||
|
}
|
||||||
|
return parts[parts.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.importImageToPiskel_ = function () {
|
||||||
|
if (this.importedImage_) {
|
||||||
|
if (window.confirm('You are about to create a new Piskel, unsaved changes will be lost.')) {
|
||||||
|
pskl.app.importService.newPiskelFromImage(
|
||||||
|
this.importedImage_,
|
||||||
|
{
|
||||||
|
importType: this.getImportType_(),
|
||||||
|
frameSizeX: this.getImportType_() === 'single' ?
|
||||||
|
this.resizeWidth.val() : this.sanitizeInputValue_(this.frameSizeX, 1),
|
||||||
|
frameSizeY: this.getImportType_() === 'single' ?
|
||||||
|
this.resizeHeight.val() : this.sanitizeInputValue_(this.frameSizeY, 1),
|
||||||
|
frameOffsetX: this.sanitizeInputValue_(this.frameOffsetX, 0),
|
||||||
|
frameOffsetY: this.sanitizeInputValue_(this.frameOffsetY, 0),
|
||||||
|
smoothing: !!this.smoothResize.prop('checked')
|
||||||
|
},
|
||||||
|
this.closeDialog.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.drawFrameGrid_ = function (frameX, frameY, frameW, frameH) {
|
||||||
|
if (!this.importedImage_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the sizes of the source and preview images
|
||||||
|
var width = this.importedImage_.width;
|
||||||
|
var height = this.importedImage_.height;
|
||||||
|
var previewWidth = this.importPreview.width();
|
||||||
|
var previewHeight = this.importPreview.height();
|
||||||
|
|
||||||
|
var canvasWrapper = this.importPreview.children('canvas');
|
||||||
|
var canvas = canvasWrapper.get(0);
|
||||||
|
if (!canvasWrapper.length) {
|
||||||
|
// Create a new canvas for the grid
|
||||||
|
canvas = pskl.utils.CanvasUtils.createCanvas(
|
||||||
|
previewWidth + 1,
|
||||||
|
previewHeight + 1);
|
||||||
|
this.importPreview.append(canvas);
|
||||||
|
canvasWrapper = $(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
context.beginPath();
|
||||||
|
|
||||||
|
// Calculate the number of whole frames
|
||||||
|
var countX = Math.floor((width - frameX) / frameW);
|
||||||
|
var countY = Math.floor((height - frameY) / frameH);
|
||||||
|
|
||||||
|
if (countX > 0 && countY > 0) {
|
||||||
|
var scaleX = previewWidth / width;
|
||||||
|
var scaleY = previewHeight / height;
|
||||||
|
var maxWidth = countX * frameW + frameX;
|
||||||
|
var maxHeight = countY * frameH + frameY;
|
||||||
|
|
||||||
|
// Draw the vertical lines
|
||||||
|
for (var x = frameX + 0.5; x < maxWidth + 1 && x < width + 1; x += frameW) {
|
||||||
|
context.moveTo(x * scaleX, frameY * scaleY);
|
||||||
|
context.lineTo(x * scaleX, maxHeight * scaleY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the horizontal lines
|
||||||
|
for (var y = frameY + 0.5; y < maxHeight + 1 && y < height + 1; y += frameH) {
|
||||||
|
context.moveTo(frameX * scaleX, y * scaleY);
|
||||||
|
context.lineTo(maxWidth * scaleX, y * scaleY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the line style to dashed
|
||||||
|
context.lineWidth = 1;
|
||||||
|
context.setLineDash([2, 1]);
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
// Show the canvas
|
||||||
|
canvasWrapper.show();
|
||||||
|
this.importPreview.addClass('no-border');
|
||||||
|
} else {
|
||||||
|
this.hideFrameGrid_();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportImageController.prototype.hideFrameGrid_ = function() {
|
||||||
|
this.importPreview.children('canvas').hide();
|
||||||
|
this.importPreview.removeClass('no-border');
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@@ -1,81 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.backups');
|
|
||||||
|
|
||||||
var stepDefinitions = {
|
|
||||||
'SELECT_SESSION' : {
|
|
||||||
controller : ns.steps.SelectSession,
|
|
||||||
template : 'backups-select-session'
|
|
||||||
},
|
|
||||||
'SESSION_DETAILS' : {
|
|
||||||
controller : ns.steps.SessionDetails,
|
|
||||||
template : 'backups-session-details'
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BrowseBackups = function (piskelController, args) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
|
|
||||||
// Backups data object used by steps to communicate and share their
|
|
||||||
// results.
|
|
||||||
this.backupsData = {
|
|
||||||
sessions: [],
|
|
||||||
selectedSession : null
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.BrowseBackups, pskl.controller.dialogs.AbstractDialogController);
|
|
||||||
|
|
||||||
ns.BrowseBackups.prototype.init = function () {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
|
|
||||||
// Prepare wizard steps.
|
|
||||||
this.steps = this.createSteps_();
|
|
||||||
|
|
||||||
// Start wizard widget.
|
|
||||||
var wizardContainer = document.querySelector('.backups-wizard-container');
|
|
||||||
this.wizard = new pskl.widgets.Wizard(this.steps, wizardContainer);
|
|
||||||
this.wizard.init();
|
|
||||||
|
|
||||||
this.wizard.goTo('SELECT_SESSION');
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BrowseBackups.prototype.back = function () {
|
|
||||||
this.wizard.back();
|
|
||||||
this.wizard.getCurrentStep().instance.onShow();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BrowseBackups.prototype.next = function () {
|
|
||||||
var step = this.wizard.getCurrentStep();
|
|
||||||
if (step.name === 'SELECT_SESSION') {
|
|
||||||
this.wizard.goTo('SESSION_DETAILS');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BrowseBackups.prototype.destroy = function (file) {
|
|
||||||
Object.keys(this.steps).forEach(function (stepName) {
|
|
||||||
var step = this.steps[stepName];
|
|
||||||
step.instance.destroy();
|
|
||||||
step.instance = null;
|
|
||||||
step.el = null;
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BrowseBackups.prototype.createSteps_ = function () {
|
|
||||||
var steps = {};
|
|
||||||
Object.keys(stepDefinitions).forEach(function (stepName) {
|
|
||||||
var definition = stepDefinitions[stepName];
|
|
||||||
var el = pskl.utils.Template.getAsHTML(definition.template);
|
|
||||||
var instance = new definition.controller(this.piskelController, this, el);
|
|
||||||
instance.init();
|
|
||||||
steps[stepName] = {
|
|
||||||
name: stepName,
|
|
||||||
el: el,
|
|
||||||
instance: instance
|
|
||||||
};
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
return steps;
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,96 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.backups.steps');
|
|
||||||
|
|
||||||
// Should match the transition duration for.session-item defined in dialogs-browse-backups.css
|
|
||||||
var DELETE_TRANSITION_DURATION = 500;
|
|
||||||
/**
|
|
||||||
* Helper that returns a promise that will resolve after waiting for a
|
|
||||||
* given time (in ms).
|
|
||||||
*
|
|
||||||
* @param {Number} time
|
|
||||||
* The time to wait.
|
|
||||||
* @return {Promise} promise that resolves after time.
|
|
||||||
*/
|
|
||||||
var wait = function (time) {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
setTimeout(function () {
|
|
||||||
deferred.resolve();
|
|
||||||
}, time);
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession = function (piskelController, backupsController, container) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.backupsController = backupsController;
|
|
||||||
this.container = container;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.addEventListener = function (el, type, cb) {
|
|
||||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.init = function () {
|
|
||||||
this.addEventListener(this.container, 'click', this.onContainerClick_);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.onShow = function () {
|
|
||||||
this.update();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.update = function () {
|
|
||||||
pskl.app.backupService.list().then(function (sessions) {
|
|
||||||
var html = '';
|
|
||||||
if (sessions.length === 0) {
|
|
||||||
html = pskl.utils.Template.get('session-list-empty');
|
|
||||||
} else {
|
|
||||||
var sessionItemTemplate = pskl.utils.Template.get('session-list-item');
|
|
||||||
var html = '';
|
|
||||||
sessions.forEach(function (session) {
|
|
||||||
if (session.id === pskl.app.sessionId) {
|
|
||||||
// Do not show backups for the current session.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var view = {
|
|
||||||
id: session.id,
|
|
||||||
name: session.name,
|
|
||||||
description: session.description ? '- ' + session.description : '',
|
|
||||||
date: pskl.utils.DateUtils.format(session.endDate, 'the {{Y}}/{{M}}/{{D}} at {{H}}:{{m}}'),
|
|
||||||
count: session.count === 1 ? '1 snapshot' : session.count + ' snapshots'
|
|
||||||
};
|
|
||||||
html += pskl.utils.Template.replace(sessionItemTemplate, view);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.container.querySelector('.session-list').innerHTML = html;
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.destroy = function () {
|
|
||||||
pskl.utils.Event.removeAllEventListeners(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectSession.prototype.onContainerClick_ = function (evt) {
|
|
||||||
var sessionId = evt.target.dataset.sessionId;
|
|
||||||
if (!sessionId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var action = evt.target.dataset.action;
|
|
||||||
if (action == 'view') {
|
|
||||||
this.backupsController.backupsData.selectedSession = sessionId;
|
|
||||||
this.backupsController.next();
|
|
||||||
} else if (action == 'delete') {
|
|
||||||
if (window.confirm('Are you sure you want to delete this session?')) {
|
|
||||||
evt.target.closest('.session-item').classList.add('deleting');
|
|
||||||
Q.all([
|
|
||||||
pskl.app.backupService.deleteSession(sessionId),
|
|
||||||
// Wait for 500ms for the .hide opacity transition.
|
|
||||||
wait(DELETE_TRANSITION_DURATION)
|
|
||||||
]).then(function () {
|
|
||||||
// Refresh the list of sessions
|
|
||||||
this.update();
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@@ -1,93 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.backups.steps');
|
|
||||||
|
|
||||||
// Should match the preview dimensions defined in dialogs-browse-backups.css
|
|
||||||
var PREVIEW_SIZE = 60;
|
|
||||||
|
|
||||||
ns.SessionDetails = function (piskelController, backupsController, container) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.backupsController = backupsController;
|
|
||||||
this.container = container;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.init = function () {
|
|
||||||
this.backButton = this.container.querySelector('.back-button');
|
|
||||||
this.addEventListener(this.backButton, 'click', this.onBackClick_);
|
|
||||||
this.addEventListener(this.container, 'click', this.onContainerClick_);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.destroy = function () {
|
|
||||||
pskl.utils.Event.removeAllEventListeners(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.addEventListener = function (el, type, cb) {
|
|
||||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.onShow = function () {
|
|
||||||
var sessionId = this.backupsController.backupsData.selectedSession;
|
|
||||||
pskl.app.backupService.getSnapshotsBySessionId(sessionId).then(function (snapshots) {
|
|
||||||
var html = '';
|
|
||||||
if (snapshots.length === 0) {
|
|
||||||
// This should normally never happen, all sessions have at least one snapshot and snapshots
|
|
||||||
// can not be individually deleted.
|
|
||||||
console.warn('Could not retrieve snapshots for a session');
|
|
||||||
html = pskl.utils.Template.get('snapshot-list-empty');
|
|
||||||
} else {
|
|
||||||
var sessionItemTemplate = pskl.utils.Template.get('snapshot-list-item');
|
|
||||||
var html = '';
|
|
||||||
snapshots.forEach(function (snapshot) {
|
|
||||||
var view = {
|
|
||||||
id: snapshot.id,
|
|
||||||
name: snapshot.name,
|
|
||||||
description: snapshot.description ? '- ' + snapshot.description : '',
|
|
||||||
date: pskl.utils.DateUtils.format(snapshot.date, 'the {{Y}}/{{M}}/{{D}} at {{H}}:{{m}}'),
|
|
||||||
frames: snapshot.frames === 1 ? '1 frame' : snapshot.frames + ' frames',
|
|
||||||
resolution: pskl.utils.StringUtils.formatSize(snapshot.width, snapshot.height),
|
|
||||||
fps: snapshot.fps
|
|
||||||
};
|
|
||||||
html += pskl.utils.Template.replace(sessionItemTemplate, view);
|
|
||||||
this.updateSnapshotPreview_(snapshot);
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
this.container.querySelector('.snapshot-list').innerHTML = html;
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.updateSnapshotPreview_ = function (snapshot) {
|
|
||||||
pskl.utils.serialization.Deserializer.deserialize(
|
|
||||||
JSON.parse(snapshot.serialized),
|
|
||||||
function (piskel) {
|
|
||||||
var selector = '.snapshot-item[data-snapshot-id="' + snapshot.id + '"] .snapshot-preview';
|
|
||||||
var previewContainer = this.container.querySelector(selector);
|
|
||||||
if (!previewContainer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var image = this.getFirstFrameAsImage_(piskel);
|
|
||||||
previewContainer.appendChild(image);
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.getFirstFrameAsImage_ = function (piskel) {
|
|
||||||
var frame = pskl.utils.LayerUtils.mergeFrameAt(piskel.getLayers(), 0);
|
|
||||||
var wZoom = PREVIEW_SIZE / piskel.width;
|
|
||||||
var hZoom = PREVIEW_SIZE / piskel.height;
|
|
||||||
var zoom = Math.min(hZoom, wZoom);
|
|
||||||
return pskl.utils.FrameUtils.toImage(frame, zoom);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.onBackClick_ = function () {
|
|
||||||
this.backupsController.back(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SessionDetails.prototype.onContainerClick_ = function (evt) {
|
|
||||||
var action = evt.target.dataset.action;
|
|
||||||
if (action == 'load' && window.confirm(Constants.CONFIRM_OVERWRITE)) {
|
|
||||||
var snapshotId = evt.target.dataset.snapshotId * 1;
|
|
||||||
pskl.app.backupService.loadSnapshotById(snapshotId).then(function () {
|
|
||||||
$.publish(Events.DIALOG_HIDE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,196 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard');
|
|
||||||
|
|
||||||
var stepDefinitions = {
|
|
||||||
'IMAGE_IMPORT' : {
|
|
||||||
controller : ns.steps.ImageImport,
|
|
||||||
template : 'import-image-import'
|
|
||||||
},
|
|
||||||
'ADJUST_SIZE' : {
|
|
||||||
controller : ns.steps.AdjustSize,
|
|
||||||
template : 'import-adjust-size'
|
|
||||||
},
|
|
||||||
'INSERT_LOCATION' : {
|
|
||||||
controller : ns.steps.InsertLocation,
|
|
||||||
template : 'import-insert-location'
|
|
||||||
},
|
|
||||||
'SELECT_MODE' : {
|
|
||||||
controller : ns.steps.SelectMode,
|
|
||||||
template : 'import-select-mode'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard = function (piskelController, args) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
|
|
||||||
// Merge data object used by steps to communicate and share their
|
|
||||||
// results.
|
|
||||||
this.mergeData = {
|
|
||||||
rawFiles : [],
|
|
||||||
mergePiskel: null,
|
|
||||||
origin: null,
|
|
||||||
resize: null,
|
|
||||||
insertIndex: null,
|
|
||||||
insertMode: null
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.ImportWizard, pskl.controller.dialogs.AbstractDialogController);
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.init = function (initArgs) {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
|
|
||||||
// Prepare mergeData object and wizard steps.
|
|
||||||
this.mergeData.rawFiles = initArgs.rawFiles;
|
|
||||||
this.steps = this.createSteps_();
|
|
||||||
|
|
||||||
// Start wizard widget.
|
|
||||||
var wizardContainer = document.querySelector('.import-wizard-container');
|
|
||||||
this.wizard = new pskl.widgets.Wizard(this.steps, wizardContainer);
|
|
||||||
this.wizard.init();
|
|
||||||
|
|
||||||
if (this.hasSingleImage_()) {
|
|
||||||
this.wizard.goTo('IMAGE_IMPORT');
|
|
||||||
} else if (this.hasSinglePiskelFile_()) {
|
|
||||||
// If a piskel file was provided we can directly go to
|
|
||||||
pskl.utils.PiskelFileUtils.loadFromFile(this.mergeData.rawFiles[0],
|
|
||||||
// onSuccess
|
|
||||||
function (piskel) {
|
|
||||||
this.mergeData.mergePiskel = piskel;
|
|
||||||
this.wizard.goTo('SELECT_MODE');
|
|
||||||
}.bind(this),
|
|
||||||
// onError
|
|
||||||
function (reason) {
|
|
||||||
this.closeDialog();
|
|
||||||
$.publish(Events.PISKEL_FILE_IMPORT_FAILED, [reason]);
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.error('Unsupported import. Only single piskel or single image are supported at the moment.');
|
|
||||||
this.closeDialog();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.back = function () {
|
|
||||||
this.wizard.back();
|
|
||||||
this.wizard.getCurrentStep().instance.onShow();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.next = function () {
|
|
||||||
var step = this.wizard.getCurrentStep();
|
|
||||||
|
|
||||||
if (step.name === 'IMAGE_IMPORT') {
|
|
||||||
this.wizard.goTo('SELECT_MODE');
|
|
||||||
} else if (step.name === 'SELECT_MODE') {
|
|
||||||
if (this.mergeData.importMode === ns.steps.SelectMode.MODES.REPLACE) {
|
|
||||||
this.finalizeImport_();
|
|
||||||
} else if (this.hasSameSize_()) {
|
|
||||||
this.wizard.goTo('INSERT_LOCATION');
|
|
||||||
} else {
|
|
||||||
this.wizard.goTo('ADJUST_SIZE');
|
|
||||||
}
|
|
||||||
} else if (step.name === 'ADJUST_SIZE') {
|
|
||||||
this.wizard.goTo('INSERT_LOCATION');
|
|
||||||
} else if (step.name === 'INSERT_LOCATION') {
|
|
||||||
this.finalizeImport_();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.destroy = function (file) {
|
|
||||||
Object.keys(this.steps).forEach(function (stepName) {
|
|
||||||
var step = this.steps[stepName];
|
|
||||||
step.instance.destroy();
|
|
||||||
step.instance = null;
|
|
||||||
step.el = null;
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.createSteps_ = function () {
|
|
||||||
// The IMAGE_IMPORT step is used only if there is a single image file
|
|
||||||
// being imported.
|
|
||||||
var hasSingleImage = this.hasSingleImage_();
|
|
||||||
|
|
||||||
var steps = {};
|
|
||||||
Object.keys(stepDefinitions).forEach(function (stepName) {
|
|
||||||
if (stepName === 'IMAGE_IMPORT' && !hasSingleImage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var definition = stepDefinitions[stepName];
|
|
||||||
var el = pskl.utils.Template.getAsHTML(definition.template);
|
|
||||||
var instance = new definition.controller(this.piskelController, this, el);
|
|
||||||
instance.init();
|
|
||||||
steps[stepName] = {
|
|
||||||
name: stepName,
|
|
||||||
el: el,
|
|
||||||
instance: instance
|
|
||||||
};
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
if (hasSingleImage) {
|
|
||||||
steps.IMAGE_IMPORT.el.classList.add('import-first-step');
|
|
||||||
} else {
|
|
||||||
steps.SELECT_MODE.el.classList.add('import-first-step');
|
|
||||||
}
|
|
||||||
|
|
||||||
return steps;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.finalizeImport_ = function () {
|
|
||||||
var piskel = this.mergeData.mergePiskel;
|
|
||||||
var mode = this.mergeData.importMode;
|
|
||||||
|
|
||||||
if (mode === ns.steps.SelectMode.MODES.REPLACE) {
|
|
||||||
// Replace the current piskel and close the dialog.
|
|
||||||
if (window.confirm(Constants.CONFIRM_OVERWRITE)) {
|
|
||||||
this.piskelController.setPiskel(piskel);
|
|
||||||
this.closeDialog();
|
|
||||||
}
|
|
||||||
} else if (mode === ns.steps.SelectMode.MODES.MERGE) {
|
|
||||||
var merge = pskl.utils.MergeUtils.merge(this.piskelController.getPiskel(), piskel, {
|
|
||||||
insertIndex: this.mergeData.insertIndex,
|
|
||||||
insertMode: this.mergeData.insertMode,
|
|
||||||
origin: this.mergeData.origin,
|
|
||||||
resize: this.mergeData.resize
|
|
||||||
});
|
|
||||||
this.piskelController.setPiskel(merge);
|
|
||||||
|
|
||||||
// Set the first imported layer as selected.
|
|
||||||
var importedLayers = piskel.getLayers().length;
|
|
||||||
var currentLayers = this.piskelController.getLayers().length;
|
|
||||||
this.piskelController.setCurrentLayerIndex(currentLayers - importedLayers);
|
|
||||||
|
|
||||||
this.closeDialog();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.hasSameSize_ = function () {
|
|
||||||
var piskel = this.mergeData.mergePiskel;
|
|
||||||
if (!piskel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return piskel.width === this.piskelController.getWidth() &&
|
|
||||||
piskel.height === this.piskelController.getHeight();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.hasSingleImage_ = function () {
|
|
||||||
if (this.mergeData.rawFiles.length !== 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var file = this.mergeData.rawFiles[0];
|
|
||||||
return file.type.indexOf('image') === 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportWizard.prototype.hasSinglePiskelFile_ = function () {
|
|
||||||
if (this.mergeData.rawFiles.length !== 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var file = this.mergeData.rawFiles[0];
|
|
||||||
return (/\.piskel$/).test(file.name);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,65 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
|
||||||
|
|
||||||
ns.AbstractImportStep = function (piskelController, importController, container) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.container = container;
|
|
||||||
this.importController = importController;
|
|
||||||
this.mergeData = this.importController.mergeData;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.init = function () {
|
|
||||||
this.nextButton = this.container.querySelector('.import-next-button');
|
|
||||||
this.backButton = this.container.querySelector('.import-back-button');
|
|
||||||
|
|
||||||
this.addEventListener(this.nextButton, 'click', this.onNextClick);
|
|
||||||
this.addEventListener(this.backButton, 'click', this.onBackClick);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.addEventListener = function (el, type, cb) {
|
|
||||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.destroy = function () {
|
|
||||||
if (this.framePickerWidget) {
|
|
||||||
this.framePickerWidget.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
pskl.utils.Event.removeAllEventListeners(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.onNextClick = function () {
|
|
||||||
this.importController.next(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.onBackClick = function () {
|
|
||||||
this.importController.back(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AbstractImportStep.prototype.onShow = function () {
|
|
||||||
var mergePiskel = this.mergeData.mergePiskel;
|
|
||||||
if (!mergePiskel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.framePickerWidget) {
|
|
||||||
var framePickerContainer = this.container.querySelector('.import-preview');
|
|
||||||
this.framePickerWidget = new pskl.widgets.FramePicker(mergePiskel, framePickerContainer);
|
|
||||||
this.framePickerWidget.init();
|
|
||||||
} else if (this.framePickerWidget.piskel != mergePiskel) {
|
|
||||||
// If the piskel displayed by the frame picker is different from the previous one,
|
|
||||||
// refresh the widget.
|
|
||||||
this.framePickerWidget.piskel = mergePiskel;
|
|
||||||
this.framePickerWidget.setFrameIndex(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var metaHtml = pskl.utils.Template.getAndReplace('import-meta-content', {
|
|
||||||
name : mergePiskel.getDescriptor().name,
|
|
||||||
dimensions : pskl.utils.StringUtils.formatSize(mergePiskel.getWidth(), mergePiskel.getHeight()),
|
|
||||||
frames : mergePiskel.getFrameCount(),
|
|
||||||
layers : mergePiskel.getLayers().length
|
|
||||||
});
|
|
||||||
this.container.querySelector('.import-meta').innerHTML = metaHtml;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@@ -1,110 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
|
||||||
|
|
||||||
ns.AdjustSize = function (piskelController, importController, container) {
|
|
||||||
this.superclass.constructor.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.OPTIONS = {
|
|
||||||
KEEP: 'keep',
|
|
||||||
EXPAND: 'expand'
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.AdjustSize, ns.AbstractImportStep);
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.init = function () {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
|
|
||||||
// Create anchor widget
|
|
||||||
var anchorContainer = this.container.querySelector('.import-resize-anchor-container');
|
|
||||||
this.anchorWidget = new pskl.widgets.AnchorWidget(anchorContainer, this.onAnchorChange_.bind(this));
|
|
||||||
this.anchorWidget.setOrigin('TOPLEFT');
|
|
||||||
|
|
||||||
this.resizeInfoContainer = this.container.querySelector('.import-resize-info');
|
|
||||||
this.addEventListener(this.resizeInfoContainer, 'change', this.onResizeOptionChange_);
|
|
||||||
|
|
||||||
// By default, set the mode to expand to avoid losing any image content.
|
|
||||||
this.mergeData.resize = ns.AdjustSize.OPTIONS.EXPAND;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.destroy = function () {
|
|
||||||
this.anchorWidget.destroy();
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.onShow = function () {
|
|
||||||
this.refresh_();
|
|
||||||
this.superclass.onShow.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.refresh_ = function () {
|
|
||||||
var isBigger = this.isImportedPiskelBigger_();
|
|
||||||
var keep = this.mergeData.resize === ns.AdjustSize.OPTIONS.KEEP;
|
|
||||||
|
|
||||||
// Refresh resize partial
|
|
||||||
var size = this.formatPiskelSize_(this.piskelController.getPiskel());
|
|
||||||
var newSize = this.formatPiskelSize_(this.mergeData.mergePiskel);
|
|
||||||
var markup;
|
|
||||||
if (isBigger) {
|
|
||||||
markup = pskl.utils.Template.getAndReplace('import-resize-bigger-partial', {
|
|
||||||
size : size,
|
|
||||||
newSize : newSize,
|
|
||||||
keepChecked : keep ? 'checked="checked"' : '',
|
|
||||||
expandChecked : keep ? '' : 'checked="checked"'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
markup = pskl.utils.Template.getAndReplace('import-resize-smaller-partial', {
|
|
||||||
size : size,
|
|
||||||
newSize : newSize
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.resizeInfoContainer.innerHTML = markup;
|
|
||||||
|
|
||||||
// Update anchor widget
|
|
||||||
if (this.mergeData.origin) {
|
|
||||||
this.anchorWidget.setOrigin(this.mergeData.origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update anchor widget info
|
|
||||||
var anchorInfo = this.container.querySelector('.import-resize-anchor-info');
|
|
||||||
if (isBigger && keep) {
|
|
||||||
anchorInfo.innerHTML = [
|
|
||||||
'<span class="import-resize-warning">',
|
|
||||||
' Imported content will be cropped!',
|
|
||||||
'</span>',
|
|
||||||
' ',
|
|
||||||
'Select crop origin'
|
|
||||||
].join('');
|
|
||||||
} else if (isBigger) {
|
|
||||||
anchorInfo.innerHTML = 'Select the anchor for resizing the canvas';
|
|
||||||
} else {
|
|
||||||
anchorInfo.innerHTML = 'Select where the import should be positioned';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.onAnchorChange_ = function (origin) {
|
|
||||||
this.mergeData.origin = origin;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.onResizeOptionChange_ = function () {
|
|
||||||
var value = this.resizeInfoContainer.querySelector(':checked').value;
|
|
||||||
if (this.mergeData.resize != value) {
|
|
||||||
this.mergeData.resize = value;
|
|
||||||
this.refresh_();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.isImportedPiskelBigger_ = function () {
|
|
||||||
var piskel = this.mergeData.mergePiskel;
|
|
||||||
if (!piskel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return piskel.width > this.piskelController.getWidth() ||
|
|
||||||
piskel.height > this.piskelController.getHeight();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.AdjustSize.prototype.formatPiskelSize_ = function (piskel) {
|
|
||||||
return pskl.utils.StringUtils.formatSize(piskel.width, piskel.height);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,279 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
|
||||||
|
|
||||||
ns.ImageImport = function (piskelController, importController, container) {
|
|
||||||
this.superclass.constructor.apply(this, arguments);
|
|
||||||
this.importedImage_ = null;
|
|
||||||
this.file_ = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.ImageImport, ns.AbstractImportStep);
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.init = function (file) {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
|
|
||||||
// This step is only used if rawFiles contains a single image.
|
|
||||||
this.file_ = this.mergeData.rawFiles[0];
|
|
||||||
|
|
||||||
this.importPreview = this.container.querySelector('.import-section-preview');
|
|
||||||
|
|
||||||
this.fileNameContainer = this.container.querySelector('.import-image-file-name');
|
|
||||||
|
|
||||||
this.singleImportType = this.container.querySelector('[name=import-type][value=single]');
|
|
||||||
this.sheetImportType = this.container.querySelector('[name=import-type][value=sheet]');
|
|
||||||
|
|
||||||
this.resizeWidth = this.container.querySelector('[name=resize-width]');
|
|
||||||
this.resizeHeight = this.container.querySelector('[name=resize-height]');
|
|
||||||
this.smoothResize = this.container.querySelector('[name=smooth-resize-checkbox]');
|
|
||||||
|
|
||||||
this.frameSizeX = this.container.querySelector('[name=frame-size-x]');
|
|
||||||
this.frameSizeY = this.container.querySelector('[name=frame-size-y]');
|
|
||||||
this.frameOffsetX = this.container.querySelector('[name=frame-offset-x]');
|
|
||||||
this.frameOffsetY = this.container.querySelector('[name=frame-offset-y]');
|
|
||||||
|
|
||||||
this.addEventListener(this.singleImportType, 'change', this.onImportTypeChange_);
|
|
||||||
this.addEventListener(this.sheetImportType, 'change', this.onImportTypeChange_);
|
|
||||||
|
|
||||||
this.addEventListener(this.resizeWidth, 'keyup', this.onResizeInputKeyUp_);
|
|
||||||
this.addEventListener(this.resizeHeight, 'keyup', this.onResizeInputKeyUp_);
|
|
||||||
this.addEventListener(this.frameSizeX, 'keyup', this.onFrameInputKeyUp_);
|
|
||||||
this.addEventListener(this.frameSizeY, 'keyup', this.onFrameInputKeyUp_);
|
|
||||||
this.addEventListener(this.frameOffsetX, 'keyup', this.onFrameInputKeyUp_);
|
|
||||||
this.addEventListener(this.frameOffsetY, 'keyup', this.onFrameInputKeyUp_);
|
|
||||||
|
|
||||||
pskl.utils.FileUtils.readImageFile(this.file_, this.onImageLoaded_.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onNextClick = function () {
|
|
||||||
this.container.classList.add('import-image-loading');
|
|
||||||
this.createPiskelFromImage().then(function (piskel) {
|
|
||||||
this.mergeData.mergePiskel = piskel;
|
|
||||||
this.superclass.onNextClick.call(this);
|
|
||||||
}.bind(this)).catch(function (e) {
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onShow = function () {
|
|
||||||
this.container.classList.remove('import-image-loading');
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.createPiskelFromImage = function () {
|
|
||||||
var name = this.extractFileNameFromPath_(this.file_.name);
|
|
||||||
// Remove extension from filename.
|
|
||||||
name = name.replace(/\.[a-zA-Z]+$/, '');
|
|
||||||
|
|
||||||
var deferred = Q.defer();
|
|
||||||
pskl.app.importService.newPiskelFromImage(
|
|
||||||
this.importedImage_,
|
|
||||||
{
|
|
||||||
importType: this.getImportType_(),
|
|
||||||
frameSizeX: this.getImportType_() === 'single' ?
|
|
||||||
this.resizeWidth.value : this.sanitizeInputValue_(this.frameSizeX, 1),
|
|
||||||
frameSizeY: this.getImportType_() === 'single' ?
|
|
||||||
this.resizeHeight.value : this.sanitizeInputValue_(this.frameSizeY, 1),
|
|
||||||
frameOffsetX: this.sanitizeInputValue_(this.frameOffsetX, 0),
|
|
||||||
frameOffsetY: this.sanitizeInputValue_(this.frameOffsetY, 0),
|
|
||||||
smoothing: !!this.smoothResize.checked,
|
|
||||||
name: name
|
|
||||||
},
|
|
||||||
deferred.resolve
|
|
||||||
);
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onImportTypeChange_ = function (evt) {
|
|
||||||
if (this.getImportType_() === 'single') {
|
|
||||||
// Using single image, so remove the frame grid
|
|
||||||
this.hideFrameGrid_();
|
|
||||||
} else {
|
|
||||||
// Using spritesheet import, so draw the frame grid in the preview
|
|
||||||
var x = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
|
||||||
var y = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
|
||||||
var w = this.sanitizeInputValue_(this.frameSizeX, 1);
|
|
||||||
var h = this.sanitizeInputValue_(this.frameSizeY, 1);
|
|
||||||
this.drawFrameGrid_(x, y, w, h);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onResizeInputKeyUp_ = function (evt) {
|
|
||||||
var from = evt.target.getAttribute('name');
|
|
||||||
if (this.importedImage_) {
|
|
||||||
this.synchronizeResizeFields_(evt.target.value, from);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onFrameInputKeyUp_ = function (evt) {
|
|
||||||
if (this.importedImage_) {
|
|
||||||
this.synchronizeFrameFields_(evt.target.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.synchronizeResizeFields_ = function (value, from) {
|
|
||||||
value = parseInt(value, 10);
|
|
||||||
if (isNaN(value)) {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
var height = this.importedImage_.height;
|
|
||||||
var width = this.importedImage_.width;
|
|
||||||
|
|
||||||
// Select single image import type since the user changed a value here
|
|
||||||
this.singleImportType.checked = true;
|
|
||||||
|
|
||||||
if (from === 'resize-width') {
|
|
||||||
this.resizeHeight.value = Math.round(value * height / width);
|
|
||||||
} else {
|
|
||||||
this.resizeWidth.value = Math.round(value * width / height);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.synchronizeFrameFields_ = function (value) {
|
|
||||||
value = parseInt(value, 10);
|
|
||||||
if (isNaN(value)) {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the frame input values
|
|
||||||
var frameSizeX = this.sanitizeInputValue_(this.frameSizeX, 1);
|
|
||||||
var frameSizeY = this.sanitizeInputValue_(this.frameSizeY, 1);
|
|
||||||
var frameOffsetX = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
|
||||||
var frameOffsetY = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
|
||||||
|
|
||||||
// Select spritesheet import type since the user changed a value here
|
|
||||||
this.sheetImportType.checked = true;
|
|
||||||
|
|
||||||
// Draw the grid
|
|
||||||
this.drawFrameGrid_(frameOffsetX, frameOffsetY, frameSizeX, frameSizeY);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.sanitizeInputValue_ = function(input, minValue) {
|
|
||||||
var value = parseInt(input.value, 10);
|
|
||||||
if (value <= minValue || isNaN(value)) {
|
|
||||||
input.value = minValue;
|
|
||||||
value = minValue;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.getImportType_ = function () {
|
|
||||||
if (this.singleImportType.checked) {
|
|
||||||
return this.singleImportType.value;
|
|
||||||
} else if (this.sheetImportType.checked) {
|
|
||||||
return this.sheetImportType.value;
|
|
||||||
} else {
|
|
||||||
throw 'Could not find the currently selected import type';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.onImageLoaded_ = function (image) {
|
|
||||||
this.importedImage_ = image;
|
|
||||||
|
|
||||||
var w = this.importedImage_.width;
|
|
||||||
var h = this.importedImage_.height;
|
|
||||||
|
|
||||||
// FIXME : We remove the onload callback here because JsGif will insert
|
|
||||||
// the image again and we want to avoid retriggering the image onload
|
|
||||||
this.importedImage_.onload = function () {};
|
|
||||||
|
|
||||||
var fileName = this.extractFileNameFromPath_(this.file_.name);
|
|
||||||
this.fileNameContainer.textContent = fileName;
|
|
||||||
this.fileNameContainer.setAttribute('title', fileName);
|
|
||||||
|
|
||||||
this.resizeWidth.value = w;
|
|
||||||
this.resizeHeight.value = h;
|
|
||||||
|
|
||||||
this.frameSizeX.value = w;
|
|
||||||
this.frameSizeY.value = h;
|
|
||||||
this.frameOffsetX.value = 0;
|
|
||||||
this.frameOffsetY.value = 0;
|
|
||||||
|
|
||||||
this.importPreview.innerHTML = '';
|
|
||||||
this.importPreview.appendChild(this.createImagePreview_());
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.createImagePreview_ = function () {
|
|
||||||
var image = document.createElement('IMG');
|
|
||||||
image.src = this.importedImage_.src;
|
|
||||||
return image;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.extractFileNameFromPath_ = function (path) {
|
|
||||||
var parts = [];
|
|
||||||
if (path.indexOf('/') !== -1) {
|
|
||||||
parts = path.split('/');
|
|
||||||
} else if (path.indexOf('\\') !== -1) {
|
|
||||||
parts = path.split('\\');
|
|
||||||
} else {
|
|
||||||
parts = [path];
|
|
||||||
}
|
|
||||||
return parts[parts.length - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.drawFrameGrid_ = function (frameX, frameY, frameW, frameH) {
|
|
||||||
if (!this.importedImage_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the sizes of the source and preview images
|
|
||||||
var width = this.importedImage_.width;
|
|
||||||
var height = this.importedImage_.height;
|
|
||||||
|
|
||||||
var image = this.importPreview.querySelector('img');
|
|
||||||
var previewWidth = image.offsetWidth;
|
|
||||||
var previewHeight = image.offsetHeight;
|
|
||||||
|
|
||||||
var canvas = this.importPreview.querySelector('canvas');
|
|
||||||
if (!canvas) {
|
|
||||||
// Create a new canvas for the grid
|
|
||||||
canvas = pskl.utils.CanvasUtils.createCanvas(
|
|
||||||
previewWidth + 1,
|
|
||||||
previewHeight + 1);
|
|
||||||
this.importPreview.appendChild(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = canvas.getContext('2d');
|
|
||||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
context.beginPath();
|
|
||||||
|
|
||||||
// Calculate the number of whole frames
|
|
||||||
var countX = Math.floor((width - frameX) / frameW);
|
|
||||||
var countY = Math.floor((height - frameY) / frameH);
|
|
||||||
|
|
||||||
if (countX > 0 && countY > 0) {
|
|
||||||
var scaleX = previewWidth / width;
|
|
||||||
var scaleY = previewHeight / height;
|
|
||||||
var maxWidth = countX * frameW + frameX;
|
|
||||||
var maxHeight = countY * frameH + frameY;
|
|
||||||
|
|
||||||
// Draw the vertical lines
|
|
||||||
for (var x = frameX + 0.5; x < maxWidth + 1 && x < width + 1; x += frameW) {
|
|
||||||
context.moveTo(x * scaleX, frameY * scaleY);
|
|
||||||
context.lineTo(x * scaleX, maxHeight * scaleY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the horizontal lines
|
|
||||||
for (var y = frameY + 0.5; y < maxHeight + 1 && y < height + 1; y += frameH) {
|
|
||||||
context.moveTo(frameX * scaleX, y * scaleY);
|
|
||||||
context.lineTo(maxWidth * scaleX, y * scaleY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the line style to dashed
|
|
||||||
context.lineWidth = 1;
|
|
||||||
// context.setLineDash([2, 1]);
|
|
||||||
context.strokeStyle = 'gold';
|
|
||||||
context.stroke();
|
|
||||||
|
|
||||||
// Show the canvas
|
|
||||||
canvas.style.display = 'block';
|
|
||||||
} else {
|
|
||||||
this.hideFrameGrid_();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImageImport.prototype.hideFrameGrid_ = function() {
|
|
||||||
var canvas = this.importPreview.querySelector('canvas');
|
|
||||||
if (canvas) {
|
|
||||||
canvas.style.display = 'none';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,59 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
|
||||||
|
|
||||||
ns.InsertLocation = function () {
|
|
||||||
this.superclass.constructor.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InsertLocation.MODES = {
|
|
||||||
ADD : 'add',
|
|
||||||
INSERT : 'insert'
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.InsertLocation, ns.AbstractImportStep);
|
|
||||||
|
|
||||||
ns.InsertLocation.prototype.init = function () {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
this.framePreview = this.container.querySelector('.insert-frame-preview');
|
|
||||||
this.currentPiskelFramePickerWidget = new pskl.widgets.FramePicker(
|
|
||||||
this.piskelController.getPiskel(), this.framePreview);
|
|
||||||
|
|
||||||
this.insertModeContainer = this.container.querySelector('.insert-mode-container');
|
|
||||||
this.addEventListener(this.insertModeContainer, 'change', this.onInsertModeChange_);
|
|
||||||
this.mergeData.insertMode = ns.InsertLocation.MODES.ADD;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InsertLocation.prototype.onInsertModeChange_ = function () {
|
|
||||||
var value = this.insertModeContainer.querySelector(':checked').value;
|
|
||||||
this.mergeData.insertMode = value;
|
|
||||||
|
|
||||||
if (this.mergeData.insertMode === ns.InsertLocation.MODES.ADD) {
|
|
||||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
|
|
||||||
} else {
|
|
||||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InsertLocation.prototype.onShow = function () {
|
|
||||||
// Initialize the frame picker on show, to be able to calculate correctly the
|
|
||||||
// container's offsetWidth and offsetHeight.
|
|
||||||
this.currentPiskelFramePickerWidget.init();
|
|
||||||
|
|
||||||
var currentFrameIndex = this.piskelController.getCurrentFrameIndex();
|
|
||||||
this.currentPiskelFramePickerWidget.setFrameIndex(currentFrameIndex + 1);
|
|
||||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
|
|
||||||
|
|
||||||
this.superclass.onShow.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InsertLocation.prototype.onNextClick = function () {
|
|
||||||
var insertIndex = this.currentPiskelFramePickerWidget.getFrameIndex();
|
|
||||||
this.mergeData.insertIndex = insertIndex;
|
|
||||||
this.superclass.onNextClick.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InsertLocation.prototype.destroy = function () {
|
|
||||||
this.currentPiskelFramePickerWidget.destroy();
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,42 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
|
||||||
|
|
||||||
ns.SelectMode = function (piskelController, importController, container) {
|
|
||||||
this.superclass.constructor.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectMode.MODES = {
|
|
||||||
REPLACE : 'replace',
|
|
||||||
MERGE : 'merge'
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.SelectMode, ns.AbstractImportStep);
|
|
||||||
|
|
||||||
ns.SelectMode.prototype.init = function () {
|
|
||||||
this.superclass.init.call(this);
|
|
||||||
|
|
||||||
var replaceButton = this.container.querySelector('.import-mode-replace-button');
|
|
||||||
var mergeButton = this.container.querySelector('.import-mode-merge-button');
|
|
||||||
|
|
||||||
this.addEventListener(replaceButton, 'click', this.onReplaceButtonClick_);
|
|
||||||
this.addEventListener(mergeButton, 'click', this.onMergeButtonClick_);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectMode.prototype.onShow = function () {
|
|
||||||
this.superclass.onShow.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectMode.prototype.destroy = function () {
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectMode.prototype.onReplaceButtonClick_ = function () {
|
|
||||||
this.mergeData.importMode = ns.SelectMode.MODES.REPLACE;
|
|
||||||
this.onNextClick();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectMode.prototype.onMergeButtonClick_ = function () {
|
|
||||||
this.mergeData.importMode = ns.SelectMode.MODES.MERGE;
|
|
||||||
this.onNextClick();
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -12,15 +12,11 @@
|
|||||||
/**
|
/**
|
||||||
* Set the current piskel. Will reset the selected frame and layer unless specified
|
* Set the current piskel. Will reset the selected frame and layer unless specified
|
||||||
* @param {Object} piskel
|
* @param {Object} piskel
|
||||||
* @param {Object} options:
|
* @param {Boolean} preserveState if true, keep the selected frame and layer
|
||||||
* preserveState {Boolean} if true, keep the selected frame and layer
|
|
||||||
* noSnapshot {Boolean} if true, do not save a snapshot in the piskel
|
|
||||||
* history for this call to setPiskel
|
|
||||||
*/
|
*/
|
||||||
ns.PiskelController.prototype.setPiskel = function (piskel, options) {
|
ns.PiskelController.prototype.setPiskel = function (piskel, preserveState) {
|
||||||
this.piskel = piskel;
|
this.piskel = piskel;
|
||||||
options = options || {};
|
if (!preserveState) {
|
||||||
if (!options.preserveState) {
|
|
||||||
this.currentLayerIndex = 0;
|
this.currentLayerIndex = 0;
|
||||||
this.currentFrameIndex = 0;
|
this.currentFrameIndex = 0;
|
||||||
}
|
}
|
||||||
@@ -159,7 +155,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.getFrameCount = function () {
|
ns.PiskelController.prototype.getFrameCount = function () {
|
||||||
return this.piskel.getFrameCount();
|
var layer = this.piskel.getLayerAt(0);
|
||||||
|
return layer.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.setCurrentFrameIndex = function (index) {
|
ns.PiskelController.prototype.setCurrentFrameIndex = function (index) {
|
||||||
@@ -234,14 +231,6 @@
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.duplicateCurrentLayer = function () {
|
|
||||||
var layer = this.getCurrentLayer();
|
|
||||||
var clone = pskl.utils.LayerUtils.clone(layer);
|
|
||||||
var currentLayerIndex = this.getCurrentLayerIndex();
|
|
||||||
this.piskel.addLayerAt(clone, currentLayerIndex + 1);
|
|
||||||
this.setCurrentLayerIndex(currentLayerIndex + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PiskelController.prototype.createLayer = function (name) {
|
ns.PiskelController.prototype.createLayer = function (name) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = this.generateLayerName_();
|
name = this.generateLayerName_();
|
||||||
@@ -251,9 +240,9 @@
|
|||||||
for (var i = 0 ; i < this.getFrameCount() ; i++) {
|
for (var i = 0 ; i < this.getFrameCount() ; i++) {
|
||||||
layer.addFrame(this.createEmptyFrame_());
|
layer.addFrame(this.createEmptyFrame_());
|
||||||
}
|
}
|
||||||
var currentLayerIndex = this.getCurrentLayerIndex();
|
this.piskel.addLayer(layer);
|
||||||
this.piskel.addLayerAt(layer, currentLayerIndex + 1);
|
this.setCurrentLayerIndex(this.piskel.getLayers().length - 1);
|
||||||
this.setCurrentLayerIndex(currentLayerIndex + 1);
|
|
||||||
} else {
|
} else {
|
||||||
throw 'Layer name should be unique';
|
throw 'Layer name should be unique';
|
||||||
}
|
}
|
||||||
@@ -263,15 +252,15 @@
|
|||||||
return this.piskel.getLayersByName(name).length > 0;
|
return this.piskel.getLayersByName(name).length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.moveLayerUp = function (toTop) {
|
ns.PiskelController.prototype.moveLayerUp = function () {
|
||||||
var layer = this.getCurrentLayer();
|
var layer = this.getCurrentLayer();
|
||||||
this.piskel.moveLayerUp(layer, toTop);
|
this.piskel.moveLayerUp(layer);
|
||||||
this.selectLayer(layer);
|
this.selectLayer(layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.moveLayerDown = function (toBottom) {
|
ns.PiskelController.prototype.moveLayerDown = function () {
|
||||||
var layer = this.getCurrentLayer();
|
var layer = this.getCurrentLayer();
|
||||||
this.piskel.moveLayerDown(layer, toBottom);
|
this.piskel.moveLayerDown(layer);
|
||||||
this.selectLayer(layer);
|
this.selectLayer(layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
this.saveWrap_('duplicateFrameAt', true);
|
this.saveWrap_('duplicateFrameAt', true);
|
||||||
this.saveWrap_('moveFrame', true);
|
this.saveWrap_('moveFrame', true);
|
||||||
this.saveWrap_('createLayer', true);
|
this.saveWrap_('createLayer', true);
|
||||||
this.saveWrap_('duplicateCurrentLayer', true);
|
|
||||||
this.saveWrap_('mergeDownLayerAt', true);
|
this.saveWrap_('mergeDownLayerAt', true);
|
||||||
this.saveWrap_('moveLayerUp', true);
|
this.saveWrap_('moveLayerUp', true);
|
||||||
this.saveWrap_('moveLayerDown', true);
|
this.saveWrap_('moveLayerDown', true);
|
||||||
@@ -49,25 +48,14 @@
|
|||||||
return this.piskelController;
|
return this.piskelController;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
ns.PublicPiskelController.prototype.setPiskel = function (piskel, preserveState) {
|
||||||
* Set the current piskel. Will reset the selected frame and layer unless specified
|
this.piskelController.setPiskel(piskel, preserveState);
|
||||||
* @param {Object} piskel
|
|
||||||
* @param {Object} options:
|
|
||||||
* preserveState {Boolean} if true, keep the selected frame and layer
|
|
||||||
* noSnapshot {Boolean} if true, do not save a snapshot in the piskel
|
|
||||||
* history for this call to setPiskel
|
|
||||||
*/
|
|
||||||
ns.PublicPiskelController.prototype.setPiskel = function (piskel, options) {
|
|
||||||
this.piskelController.setPiskel(piskel, options);
|
|
||||||
|
|
||||||
$.publish(Events.FRAME_SIZE_CHANGED);
|
$.publish(Events.FRAME_SIZE_CHANGED);
|
||||||
$.publish(Events.PISKEL_RESET);
|
$.publish(Events.PISKEL_RESET);
|
||||||
|
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||||
if (!options || !options.noSnapshot) {
|
type : pskl.service.HistoryService.SNAPSHOT
|
||||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
});
|
||||||
type : pskl.service.HistoryService.SNAPSHOT
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PublicPiskelController.prototype.resetWrap_ = function (methodName) {
|
ns.PublicPiskelController.prototype.resetWrap_ = function (methodName) {
|
||||||
|
@@ -102,7 +102,7 @@
|
|||||||
this.disablePreviewSizeWidget_('No other option available');
|
this.disablePreviewSizeWidget_('No other option available');
|
||||||
validSizes = ['original'];
|
validSizes = ['original'];
|
||||||
} else if (seamlessModeEnabled) {
|
} else if (seamlessModeEnabled) {
|
||||||
this.disablePreviewSizeWidget_('Disabled in tile mode');
|
this.disablePreviewSizeWidget_('Disabled in seamless mode');
|
||||||
validSizes = ['original'];
|
validSizes = ['original'];
|
||||||
} else {
|
} else {
|
||||||
this.enablePreviewSizeWidget_();
|
this.enablePreviewSizeWidget_();
|
||||||
@@ -309,8 +309,7 @@
|
|||||||
var isSeamless = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
|
var isSeamless = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
|
||||||
this.renderer.setRepeated(isSeamless);
|
this.renderer.setRepeated(isSeamless);
|
||||||
|
|
||||||
var width;
|
var height, width;
|
||||||
var height;
|
|
||||||
|
|
||||||
if (isSeamless) {
|
if (isSeamless) {
|
||||||
height = PREVIEW_SIZE;
|
height = PREVIEW_SIZE;
|
||||||
|
144
src/js/controller/settings/ApplicationSettingsController.js
Normal file
144
src/js/controller/settings/ApplicationSettingsController.js
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.controller.settings');
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController = function () {};
|
||||||
|
|
||||||
|
pskl.utils.inherit(ns.ApplicationSettingsController, pskl.controller.settings.AbstractSettingController);
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.init = function() {
|
||||||
|
this.backgroundContainer = document.querySelector('.background-picker-wrapper');
|
||||||
|
this.addEventListener(this.backgroundContainer, 'click', this.onBackgroundClick_);
|
||||||
|
|
||||||
|
// Highlight selected background :
|
||||||
|
var background = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);
|
||||||
|
var selectedBackground = this.backgroundContainer.querySelector('[data-background=' + background + ']');
|
||||||
|
if (selectedBackground) {
|
||||||
|
selectedBackground.classList.add('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grid display and size
|
||||||
|
var gridWidth = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH);
|
||||||
|
var gridSelect = document.querySelector('.grid-width-select');
|
||||||
|
var selectedOption = gridSelect.querySelector('option[value="' + gridWidth + '"]');
|
||||||
|
if (selectedOption) {
|
||||||
|
selectedOption.setAttribute('selected', 'selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addEventListener(gridSelect, 'change', this.onGridWidthChange_);
|
||||||
|
|
||||||
|
// Seamless mode
|
||||||
|
var seamlessMode = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
|
||||||
|
var seamlessModeCheckbox = document.querySelector('.seamless-mode-checkbox');
|
||||||
|
if (seamlessMode) {
|
||||||
|
seamlessModeCheckbox.setAttribute('checked', seamlessMode);
|
||||||
|
}
|
||||||
|
this.addEventListener(seamlessModeCheckbox, 'change', this.onSeamlessModeChange_);
|
||||||
|
|
||||||
|
// Max FPS
|
||||||
|
var maxFpsInput = document.querySelector('.max-fps-input');
|
||||||
|
maxFpsInput.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS);
|
||||||
|
this.addEventListener(maxFpsInput, 'change', this.onMaxFpsChange_);
|
||||||
|
|
||||||
|
// Color format
|
||||||
|
var colorFormat = pskl.UserSettings.get(pskl.UserSettings.COLOR_FORMAT);
|
||||||
|
var colorFormatSelect = document.querySelector('.color-format-select');
|
||||||
|
var selectedColorFormatOption = colorFormatSelect.querySelector('option[value="' + colorFormat + '"]');
|
||||||
|
if (selectedColorFormatOption) {
|
||||||
|
selectedColorFormatOption.setAttribute('selected', 'selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addEventListener(colorFormatSelect, 'change', this.onColorFormatChange_);
|
||||||
|
|
||||||
|
// Layer preview opacity
|
||||||
|
var layerOpacityInput = document.querySelector('.layer-opacity-input');
|
||||||
|
layerOpacityInput.value = pskl.UserSettings.get(pskl.UserSettings.LAYER_OPACITY);
|
||||||
|
this.addEventListener(layerOpacityInput, 'change', this.onLayerOpacityChange_);
|
||||||
|
this.addEventListener(layerOpacityInput, 'input', this.onLayerOpacityChange_);
|
||||||
|
this.updateLayerOpacityText_(layerOpacityInput.value);
|
||||||
|
|
||||||
|
// Seamless mask opacity
|
||||||
|
var seamlessOpacityInput = document.querySelector('.seamless-opacity-input');
|
||||||
|
seamlessOpacityInput.value = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_OPACITY);
|
||||||
|
this.addEventListener(seamlessOpacityInput, 'change', this.onSeamlessOpacityChange_);
|
||||||
|
this.addEventListener(seamlessOpacityInput, 'input', this.onSeamlessOpacityChange_);
|
||||||
|
this.updateSeamlessOpacityText_(seamlessOpacityInput.value);
|
||||||
|
|
||||||
|
// Form
|
||||||
|
this.applicationSettingsForm = document.querySelector('[name="application-settings-form"]');
|
||||||
|
this.addEventListener(this.applicationSettingsForm, 'submit', this.onFormSubmit_);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onGridWidthChange_ = function (evt) {
|
||||||
|
var width = parseInt(evt.target.value, 10);
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, width);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onColorFormatChange_ = function (evt) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.COLOR_FORMAT, evt.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onSeamlessModeChange_ = function (evt) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.SEAMLESS_MODE, evt.currentTarget.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onBackgroundClick_ = function (evt) {
|
||||||
|
var target = evt.target;
|
||||||
|
var background = target.dataset.background;
|
||||||
|
if (background) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, background);
|
||||||
|
var selected = this.backgroundContainer.querySelector('.selected');
|
||||||
|
if (selected) {
|
||||||
|
selected.classList.remove('selected');
|
||||||
|
}
|
||||||
|
target.classList.add('selected');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onMaxFpsChange_ = function (evt) {
|
||||||
|
var target = evt.target;
|
||||||
|
var fps = parseInt(target.value, 10);
|
||||||
|
if (fps && !isNaN(fps)) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.MAX_FPS, fps);
|
||||||
|
} else {
|
||||||
|
target.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onLayerOpacityChange_ = function (evt) {
|
||||||
|
var target = evt.target;
|
||||||
|
var opacity = parseFloat(target.value);
|
||||||
|
if (!isNaN(opacity)) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.LAYER_OPACITY, opacity);
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.LAYER_PREVIEW, opacity !== 0);
|
||||||
|
this.updateLayerOpacityText_(opacity);
|
||||||
|
} else {
|
||||||
|
target.value = pskl.UserSettings.get(pskl.UserSettings.LAYER_OPACITY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onSeamlessOpacityChange_ = function (evt) {
|
||||||
|
var target = evt.target;
|
||||||
|
var opacity = parseFloat(target.value);
|
||||||
|
if (!isNaN(opacity)) {
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.SEAMLESS_OPACITY, opacity);
|
||||||
|
this.updateSeamlessOpacityText_(opacity);
|
||||||
|
} else {
|
||||||
|
target.value = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_OPACITY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.updateLayerOpacityText_ = function (opacity) {
|
||||||
|
var layerOpacityText = document.querySelector('.layer-opacity-text');
|
||||||
|
layerOpacityText.innerHTML = opacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.updateSeamlessOpacityText_ = function (opacity) {
|
||||||
|
var seamlessOpacityText = document.querySelector('.seamless-opacity-text');
|
||||||
|
seamlessOpacityText.innerHTML = opacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ApplicationSettingsController.prototype.onFormSubmit_ = function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
$.publish(Events.CLOSE_SETTINGS_DRAWER);
|
||||||
|
};
|
||||||
|
})();
|
@@ -14,7 +14,6 @@
|
|||||||
this.hiddenOpenPiskelInput = document.querySelector('[name="open-piskel-input"]');
|
this.hiddenOpenPiskelInput = document.querySelector('[name="open-piskel-input"]');
|
||||||
|
|
||||||
this.addEventListener('.browse-local-button', 'click', this.onBrowseLocalClick_);
|
this.addEventListener('.browse-local-button', 'click', this.onBrowseLocalClick_);
|
||||||
this.addEventListener('.browse-backups-button', 'click', this.onBrowseBackupsClick_);
|
|
||||||
this.addEventListener('.file-input-button', 'click', this.onFileInputClick_);
|
this.addEventListener('.file-input-button', 'click', this.onFileInputClick_);
|
||||||
|
|
||||||
// different handlers, depending on the Environment
|
// different handlers, depending on the Environment
|
||||||
@@ -24,6 +23,24 @@
|
|||||||
this.addEventListener(this.hiddenOpenPiskelInput, 'change', this.onOpenPiskelChange_);
|
this.addEventListener(this.hiddenOpenPiskelInput, 'change', this.onOpenPiskelChange_);
|
||||||
this.addEventListener('.open-piskel-button', 'click', this.onOpenPiskelClick_);
|
this.addEventListener('.open-piskel-button', 'click', this.onOpenPiskelClick_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.initRestoreSession_();
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ImportController.prototype.initRestoreSession_ = function () {
|
||||||
|
var previousSessionContainer = document.querySelector('.previous-session');
|
||||||
|
var previousInfo = pskl.app.backupService.getPreviousPiskelInfo();
|
||||||
|
if (previousInfo) {
|
||||||
|
var previousSessionTemplate_ = pskl.utils.Template.get('previous-session-info-template');
|
||||||
|
var date = pskl.utils.DateUtils.format(previousInfo.date, '{{H}}:{{m}} - {{Y}}/{{M}}/{{D}}');
|
||||||
|
previousSessionContainer.innerHTML = pskl.utils.Template.replace(previousSessionTemplate_, {
|
||||||
|
name : previousInfo.name,
|
||||||
|
date : date
|
||||||
|
});
|
||||||
|
this.addEventListener('.restore-session-button', 'click', this.onRestorePreviousSessionClick_);
|
||||||
|
} else {
|
||||||
|
previousSessionContainer.innerHTML = 'No piskel backup was found on this browser.';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.ImportController.prototype.closeDrawer_ = function () {
|
ns.ImportController.prototype.closeDrawer_ = function () {
|
||||||
@@ -54,54 +71,48 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.ImportController.prototype.onBrowseLocalClick_ = function (evt) {
|
ns.ImportController.prototype.onBrowseLocalClick_ = function (evt) {
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
dialogId : 'browse-local'
|
dialogId : 'browse-local'
|
||||||
});
|
});
|
||||||
this.closeDrawer_();
|
this.closeDrawer_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.ImportController.prototype.onBrowseBackupsClick_ = function (evt) {
|
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
|
||||||
dialogId : 'browse-backups'
|
|
||||||
});
|
|
||||||
this.closeDrawer_();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportController.prototype.openPiskelFile_ = function (file) {
|
ns.ImportController.prototype.openPiskelFile_ = function (file) {
|
||||||
if (this.isPiskel_(file)) {
|
if (this.isPiskel_(file)) {
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
pskl.utils.PiskelFileUtils.loadFromFile(file,
|
||||||
dialogId : 'import',
|
// onSuccess
|
||||||
initArgs : {
|
function (piskel) {
|
||||||
rawFiles: [file]
|
pskl.app.piskelController.setPiskel(piskel);
|
||||||
}
|
},
|
||||||
});
|
// onError
|
||||||
|
function (reason) {
|
||||||
|
$.publish(Events.PISKEL_FILE_IMPORT_FAILED, [reason]);
|
||||||
|
});
|
||||||
this.closeDrawer_();
|
this.closeDrawer_();
|
||||||
} else {
|
|
||||||
this.closeDrawer_();
|
|
||||||
console.error('The selected file is not a piskel file');
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.ImportController.prototype.importPictureFromFile_ = function () {
|
ns.ImportController.prototype.importPictureFromFile_ = function () {
|
||||||
var files = this.hiddenFileInput.files;
|
var files = this.hiddenFileInput.files;
|
||||||
// TODO : Simply filter and remove stuff
|
if (files.length == 1) {
|
||||||
var areImages = Array.prototype.every.call(files, function (file) {
|
var file = files[0];
|
||||||
return file.type.indexOf('image') === 0;
|
if (this.isImage_(file)) {
|
||||||
});
|
$.publish(Events.DIALOG_DISPLAY, {
|
||||||
if (areImages) {
|
dialogId : 'import-image',
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
initArgs : file
|
||||||
dialogId : 'import',
|
});
|
||||||
initArgs : {
|
this.closeDrawer_();
|
||||||
rawFiles: files
|
} else {
|
||||||
}
|
this.closeDrawer_();
|
||||||
});
|
console.error('File is not an image : ' + file.type);
|
||||||
this.closeDrawer_();
|
}
|
||||||
} else {
|
|
||||||
this.closeDrawer_();
|
|
||||||
console.error('Some files are not images');
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.ImportController.prototype.isImage_ = function (file) {
|
||||||
|
return file.type.indexOf('image') === 0;
|
||||||
|
};
|
||||||
|
|
||||||
ns.ImportController.prototype.isPiskel_ = function (file) {
|
ns.ImportController.prototype.isPiskel_ = function (file) {
|
||||||
return (/\.piskel$/).test(file.name);
|
return (/\.piskel$/).test(file.name);
|
||||||
};
|
};
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.settings');
|
|
||||||
|
|
||||||
var tabs = {
|
|
||||||
'misc' : {
|
|
||||||
template : 'templates/settings/preferences/misc.html',
|
|
||||||
controller : ns.preferences.MiscPreferencesController
|
|
||||||
},
|
|
||||||
'grid' : {
|
|
||||||
template : 'templates/settings/preferences/grid.html',
|
|
||||||
controller : ns.preferences.GridPreferencesController
|
|
||||||
},
|
|
||||||
'tile' : {
|
|
||||||
template : 'templates/settings/preferences/tile.html',
|
|
||||||
controller : ns.preferences.TilePreferencesController
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PreferencesController = function () {
|
|
||||||
this.tabsWidget = new pskl.widgets.Tabs(tabs, this, pskl.UserSettings.PREFERENCES_TAB);
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.PreferencesController, pskl.controller.settings.AbstractSettingController);
|
|
||||||
|
|
||||||
ns.PreferencesController.prototype.init = function() {
|
|
||||||
var container = document.querySelector('.settings-section-preferences');
|
|
||||||
this.tabsWidget.init(container);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PreferencesController.prototype.destroy = function () {
|
|
||||||
this.tabsWidget.destroy();
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@@ -34,7 +34,7 @@
|
|||||||
this.saveDesktopAsNewButton = document.querySelector('#save-desktop-as-new-button');
|
this.saveDesktopAsNewButton = document.querySelector('#save-desktop-as-new-button');
|
||||||
this.saveFileDownloadButton = document.querySelector('#save-file-download-button');
|
this.saveFileDownloadButton = document.querySelector('#save-file-download-button');
|
||||||
|
|
||||||
this.safeAddEventListener_(this.saveLocalStorageButton, 'click', this.saveToIndexedDb_);
|
this.safeAddEventListener_(this.saveLocalStorageButton, 'click', this.saveToLocalStorage_);
|
||||||
this.safeAddEventListener_(this.saveGalleryButton, 'click', this.saveToGallery_);
|
this.safeAddEventListener_(this.saveGalleryButton, 'click', this.saveToGallery_);
|
||||||
this.safeAddEventListener_(this.saveDesktopButton, 'click', this.saveToDesktop_);
|
this.safeAddEventListener_(this.saveDesktopButton, 'click', this.saveToDesktop_);
|
||||||
this.safeAddEventListener_(this.saveDesktopAsNewButton, 'click', this.saveToDesktopAsNew_);
|
this.safeAddEventListener_(this.saveDesktopAsNewButton, 'click', this.saveToDesktopAsNew_);
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
if (pskl.app.isLoggedIn()) {
|
if (pskl.app.isLoggedIn()) {
|
||||||
this.saveToGallery_();
|
this.saveToGallery_();
|
||||||
} else {
|
} else {
|
||||||
this.saveToIndexedDb_();
|
this.saveToLocalStorage_();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,8 +111,8 @@
|
|||||||
this.saveTo_('saveToGallery', false);
|
this.saveTo_('saveToGallery', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SaveController.prototype.saveToIndexedDb_ = function () {
|
ns.SaveController.prototype.saveToLocalStorage_ = function () {
|
||||||
this.saveTo_('saveToIndexedDb', false);
|
this.saveTo_('saveToLocalStorage', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SaveController.prototype.saveToDesktop_ = function () {
|
ns.SaveController.prototype.saveToDesktop_ = function () {
|
||||||
|
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
var settings = {
|
var settings = {
|
||||||
'user' : {
|
'user' : {
|
||||||
template : 'templates/settings/preferences.html',
|
template : 'templates/settings/application.html',
|
||||||
controller : ns.PreferencesController
|
controller : ns.ApplicationSettingsController
|
||||||
},
|
},
|
||||||
'resize' : {
|
'resize' : {
|
||||||
template : 'templates/settings/resize.html',
|
template : 'templates/settings/resize.html',
|
||||||
|
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
ns.ExportController = function (piskelController) {
|
ns.ExportController = function (piskelController) {
|
||||||
this.piskelController = piskelController;
|
this.piskelController = piskelController;
|
||||||
this.tabsWidget = new pskl.widgets.Tabs(tabs, this, pskl.UserSettings.EXPORT_TAB);
|
|
||||||
this.onSizeInputChange_ = this.onSizeInputChange_.bind(this);
|
this.onSizeInputChange_ = this.onSizeInputChange_.bind(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,16 +47,47 @@
|
|||||||
this.onSizeInputChange_();
|
this.onSizeInputChange_();
|
||||||
|
|
||||||
// Initialize tabs and panel
|
// Initialize tabs and panel
|
||||||
var container = document.querySelector('.settings-section-export');
|
this.exportPanel = document.querySelector('.export-panel');
|
||||||
this.tabsWidget.init(container);
|
this.exportTabs = document.querySelector('.export-tabs');
|
||||||
|
this.addEventListener(this.exportTabs, 'click', this.onTabsClicked_);
|
||||||
|
|
||||||
|
var tab = pskl.UserSettings.get(pskl.UserSettings.EXPORT_TAB);
|
||||||
|
this.selectTab(tab);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.ExportController.prototype.destroy = function () {
|
ns.ExportController.prototype.destroy = function () {
|
||||||
this.sizeInputWidget.destroy();
|
this.sizeInputWidget.destroy();
|
||||||
this.tabsWidget.destroy();
|
this.currentController.destroy();
|
||||||
this.superclass.destroy.call(this);
|
this.superclass.destroy.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.ExportController.prototype.selectTab = function (tabId) {
|
||||||
|
if (!tabs[tabId] || this.currentTab == tabId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentController) {
|
||||||
|
this.currentController.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.exportPanel.innerHTML = pskl.utils.Template.get(tabs[tabId].template);
|
||||||
|
this.currentController = new tabs[tabId].controller(this.piskelController, this);
|
||||||
|
this.currentController.init();
|
||||||
|
this.currentTab = tabId;
|
||||||
|
pskl.UserSettings.set(pskl.UserSettings.EXPORT_TAB, tabId);
|
||||||
|
|
||||||
|
var selectedTab = this.exportTabs.querySelector('.selected');
|
||||||
|
if (selectedTab) {
|
||||||
|
selectedTab.classList.remove('selected');
|
||||||
|
}
|
||||||
|
this.exportTabs.querySelector('[data-tab-id="' + tabId + '"]').classList.add('selected');
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ExportController.prototype.onTabsClicked_ = function (e) {
|
||||||
|
var tabId = pskl.utils.Dom.getData(e.target, 'tabId');
|
||||||
|
this.selectTab(tabId);
|
||||||
|
};
|
||||||
|
|
||||||
ns.ExportController.prototype.onScaleChange_ = function () {
|
ns.ExportController.prototype.onScaleChange_ = function () {
|
||||||
var value = parseFloat(this.scaleInput.value);
|
var value = parseFloat(this.scaleInput.value);
|
||||||
if (!isNaN(value)) {
|
if (!isNaN(value)) {
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
pskl.utils.inherit(ns.GifExportController, pskl.controller.settings.AbstractSettingController);
|
pskl.utils.inherit(ns.GifExportController, pskl.controller.settings.AbstractSettingController);
|
||||||
|
|
||||||
ns.GifExportController.prototype.init = function () {
|
ns.GifExportController.prototype.init = function () {
|
||||||
|
|
||||||
this.uploadStatusContainerEl = document.querySelector('.gif-upload-status');
|
this.uploadStatusContainerEl = document.querySelector('.gif-upload-status');
|
||||||
this.previewContainerEl = document.querySelector('.gif-export-preview');
|
this.previewContainerEl = document.querySelector('.gif-export-preview');
|
||||||
this.uploadButton = document.querySelector('.gif-upload-button');
|
this.uploadButton = document.querySelector('.gif-upload-button');
|
||||||
@@ -21,10 +22,6 @@
|
|||||||
|
|
||||||
this.addEventListener(this.uploadButton, 'click', this.onUploadButtonClick_);
|
this.addEventListener(this.uploadButton, 'click', this.onUploadButtonClick_);
|
||||||
this.addEventListener(this.downloadButton, 'click', this.onDownloadButtonClick_);
|
this.addEventListener(this.downloadButton, 'click', this.onDownloadButtonClick_);
|
||||||
|
|
||||||
var currentColors = pskl.app.currentColorsService.getCurrentColors();
|
|
||||||
var tooManyColors = currentColors.length >= MAX_GIF_COLORS;
|
|
||||||
document.querySelector('.gif-export-warning').classList.toggle('visible', tooManyColors);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.GifExportController.prototype.getZoom_ = function () {
|
ns.GifExportController.prototype.getZoom_ = function () {
|
||||||
@@ -88,8 +85,7 @@
|
|||||||
var isTransparent = layers.some(function (l) {return l.isTransparent();});
|
var isTransparent = layers.some(function (l) {return l.isTransparent();});
|
||||||
var preserveColors = !isTransparent && currentColors.length < MAX_GIF_COLORS;
|
var preserveColors = !isTransparent && currentColors.length < MAX_GIF_COLORS;
|
||||||
|
|
||||||
var transparentColor;
|
var transparentColor, transparent;
|
||||||
var transparent;
|
|
||||||
// transparency only supported if preserveColors is true, see Issue #357
|
// transparency only supported if preserveColors is true, see Issue #357
|
||||||
if (preserveColors) {
|
if (preserveColors) {
|
||||||
transparentColor = this.getTransparentColor(currentColors);
|
transparentColor = this.getTransparentColor(currentColors);
|
||||||
|
@@ -190,7 +190,7 @@
|
|||||||
var json = {
|
var json = {
|
||||||
'frames': frames,
|
'frames': frames,
|
||||||
'meta': {
|
'meta': {
|
||||||
'app': 'https://github.com/piskelapp/piskel/',
|
'app': 'https://github.com/juliandescottes/piskel/',
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
'image': name + '.png',
|
'image': name + '.png',
|
||||||
'format': 'RGBA8888',
|
'format': 'RGBA8888',
|
||||||
@@ -207,14 +207,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PngExportController.prototype.onDataUriClick_ = function (evt) {
|
ns.PngExportController.prototype.onDataUriClick_ = function (evt) {
|
||||||
var popup = window.open('about:blank');
|
window.open(this.createPngSpritesheet_().toDataURL('image/png'));
|
||||||
var dataUri = this.createPngSpritesheet_().toDataURL('image/png');
|
|
||||||
window.setTimeout(function () {
|
|
||||||
var html = pskl.utils.Template.getAndReplace('data-uri-export-partial', {
|
|
||||||
src: dataUri
|
|
||||||
});
|
|
||||||
popup.document.title = dataUri;
|
|
||||||
popup.document.body.innerHTML = html;
|
|
||||||
}.bind(this), 500);
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -1,90 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.settings.preferences');
|
|
||||||
|
|
||||||
var colorsMap = {
|
|
||||||
'transparent': Constants.TRANSPARENT_COLOR,
|
|
||||||
'white': '#FFF1E8',
|
|
||||||
'light-gray': '#C2C3C7',
|
|
||||||
'dark-gray': '#5F574F',
|
|
||||||
'black': '#000000',
|
|
||||||
'blue': '#29ADFF',
|
|
||||||
'dark-blue': '#1D2B53',
|
|
||||||
'green': '#00E436',
|
|
||||||
'dark-green': '#008751',
|
|
||||||
'peach': '#FFCCAA',
|
|
||||||
'pink': '#FF77A8',
|
|
||||||
'yellow': '#FFEC27',
|
|
||||||
'orange': '#FFA300',
|
|
||||||
'red': '#FF004D',
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.GridPreferencesController = function (piskelController, preferencesController) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.preferencesController = preferencesController;
|
|
||||||
this.sizePicker = new pskl.widgets.SizePicker(this.onSizePickerChanged_.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.GridPreferencesController, pskl.controller.settings.AbstractSettingController);
|
|
||||||
|
|
||||||
ns.GridPreferencesController.prototype.init = function () {
|
|
||||||
// Grid enabled
|
|
||||||
var isEnabled = pskl.UserSettings.get(pskl.UserSettings.GRID_ENABLED);
|
|
||||||
var enableGridCheckbox = document.querySelector('.enable-grid-checkbox');
|
|
||||||
if (isEnabled) {
|
|
||||||
enableGridCheckbox.setAttribute('checked', 'true');
|
|
||||||
}
|
|
||||||
this.addEventListener(enableGridCheckbox, 'change', this.onEnableGridChange_);
|
|
||||||
|
|
||||||
// Grid size
|
|
||||||
var gridWidth = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH);
|
|
||||||
this.sizePicker.init(document.querySelector('.grid-size-container'));
|
|
||||||
this.sizePicker.setSize(gridWidth);
|
|
||||||
|
|
||||||
// Grid color
|
|
||||||
var colorListItemTemplate = pskl.utils.Template.get('color-list-item-template');
|
|
||||||
|
|
||||||
var gridColor = pskl.UserSettings.get(pskl.UserSettings.GRID_COLOR);
|
|
||||||
var gridColorSelect = document.querySelector('#grid-color');
|
|
||||||
|
|
||||||
var markup = '';
|
|
||||||
Object.keys(colorsMap).forEach(function (key, index) {
|
|
||||||
var background = colorsMap[key];
|
|
||||||
if (key === 'transparent') {
|
|
||||||
background = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZ' +
|
|
||||||
'F8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)';
|
|
||||||
}
|
|
||||||
markup += pskl.utils.Template.replace(colorListItemTemplate, {
|
|
||||||
color: colorsMap[key],
|
|
||||||
title: key,
|
|
||||||
background: background,
|
|
||||||
':selected': gridColor === colorsMap[key]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.gridColorList = document.querySelector('.grid-colors-list');
|
|
||||||
this.gridColorList.innerHTML = markup;
|
|
||||||
|
|
||||||
this.addEventListener(this.gridColorList, 'click', this.onGridColorClicked_.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.GridPreferencesController.prototype.destroy = function () {
|
|
||||||
this.sizePicker.destroy();
|
|
||||||
this.superclass.destroy.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.GridPreferencesController.prototype.onSizePickerChanged_ = function (size) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.GRID_WIDTH, size);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.GridPreferencesController.prototype.onEnableGridChange_ = function (evt) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.GRID_ENABLED, evt.currentTarget.checked);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.GridPreferencesController.prototype.onGridColorClicked_ = function (evt) {
|
|
||||||
var color = evt.target.dataset.color;
|
|
||||||
if (color) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.GRID_COLOR, color);
|
|
||||||
this.gridColorList.querySelector('.selected').classList.remove('selected');
|
|
||||||
evt.target.classList.add('selected');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,88 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.settings.preferences');
|
|
||||||
|
|
||||||
ns.MiscPreferencesController = function (piskelController, preferencesController) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.preferencesController = preferencesController;
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.MiscPreferencesController, pskl.controller.settings.AbstractSettingController);
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.init = function () {
|
|
||||||
|
|
||||||
this.backgroundContainer = document.querySelector('.background-picker-wrapper');
|
|
||||||
this.addEventListener(this.backgroundContainer, 'click', this.onBackgroundClick_);
|
|
||||||
|
|
||||||
// Highlight selected background :
|
|
||||||
var background = pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);
|
|
||||||
var selectedBackground = this.backgroundContainer.querySelector('[data-background=' + background + ']');
|
|
||||||
if (selectedBackground) {
|
|
||||||
selectedBackground.classList.add('selected');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max FPS
|
|
||||||
var maxFpsInput = document.querySelector('.max-fps-input');
|
|
||||||
maxFpsInput.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS);
|
|
||||||
this.addEventListener(maxFpsInput, 'change', this.onMaxFpsChange_);
|
|
||||||
|
|
||||||
// Color format
|
|
||||||
var colorFormat = pskl.UserSettings.get(pskl.UserSettings.COLOR_FORMAT);
|
|
||||||
var colorFormatSelect = document.querySelector('.color-format-select');
|
|
||||||
var selectedColorFormatOption = colorFormatSelect.querySelector('option[value="' + colorFormat + '"]');
|
|
||||||
if (selectedColorFormatOption) {
|
|
||||||
selectedColorFormatOption.setAttribute('selected', 'selected');
|
|
||||||
}
|
|
||||||
this.addEventListener(colorFormatSelect, 'change', this.onColorFormatChange_);
|
|
||||||
|
|
||||||
// Layer preview opacity
|
|
||||||
var layerOpacityInput = document.querySelector('.layer-opacity-input');
|
|
||||||
layerOpacityInput.value = pskl.UserSettings.get(pskl.UserSettings.LAYER_OPACITY);
|
|
||||||
this.addEventListener(layerOpacityInput, 'change', this.onLayerOpacityChange_);
|
|
||||||
this.addEventListener(layerOpacityInput, 'input', this.onLayerOpacityChange_);
|
|
||||||
this.updateLayerOpacityText_(layerOpacityInput.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.onBackgroundClick_ = function (evt) {
|
|
||||||
var target = evt.target;
|
|
||||||
var background = target.dataset.background;
|
|
||||||
if (background) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, background);
|
|
||||||
var selected = this.backgroundContainer.querySelector('.selected');
|
|
||||||
if (selected) {
|
|
||||||
selected.classList.remove('selected');
|
|
||||||
}
|
|
||||||
target.classList.add('selected');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.onColorFormatChange_ = function (evt) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.COLOR_FORMAT, evt.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.onMaxFpsChange_ = function (evt) {
|
|
||||||
var target = evt.target;
|
|
||||||
var fps = parseInt(target.value, 10);
|
|
||||||
if (fps && !isNaN(fps)) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.MAX_FPS, fps);
|
|
||||||
} else {
|
|
||||||
target.value = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.onLayerOpacityChange_ = function (evt) {
|
|
||||||
var target = evt.target;
|
|
||||||
var opacity = parseFloat(target.value);
|
|
||||||
if (!isNaN(opacity)) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.LAYER_OPACITY, opacity);
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.LAYER_PREVIEW, opacity !== 0);
|
|
||||||
this.updateLayerOpacityText_(opacity);
|
|
||||||
} else {
|
|
||||||
target.value = pskl.UserSettings.get(pskl.UserSettings.LAYER_OPACITY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MiscPreferencesController.prototype.updateLayerOpacityText_ = function (opacity) {
|
|
||||||
var layerOpacityText = document.querySelector('.layer-opacity-text');
|
|
||||||
layerOpacityText.innerHTML = (opacity * 1).toFixed(2);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,47 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.controller.settings.preferences');
|
|
||||||
|
|
||||||
ns.TilePreferencesController = function (piskelController, preferencesController) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.preferencesController = preferencesController;
|
|
||||||
};
|
|
||||||
|
|
||||||
pskl.utils.inherit(ns.TilePreferencesController, pskl.controller.settings.AbstractSettingController);
|
|
||||||
|
|
||||||
ns.TilePreferencesController.prototype.init = function () {
|
|
||||||
// Tile mode
|
|
||||||
var tileMode = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_MODE);
|
|
||||||
var tileModeCheckbox = document.querySelector('.tile-mode-checkbox');
|
|
||||||
if (tileMode) {
|
|
||||||
tileModeCheckbox.setAttribute('checked', tileMode);
|
|
||||||
}
|
|
||||||
this.addEventListener(tileModeCheckbox, 'change', this.onTileModeChange_);
|
|
||||||
|
|
||||||
// Tile mask opacity
|
|
||||||
var tileMaskOpacityInput = document.querySelector('.tile-mask-opacity-input');
|
|
||||||
tileMaskOpacityInput.value = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_OPACITY);
|
|
||||||
this.addEventListener(tileMaskOpacityInput, 'change', this.onTileMaskOpacityChange_);
|
|
||||||
this.addEventListener(tileMaskOpacityInput, 'input', this.onTileMaskOpacityChange_);
|
|
||||||
this.updateTileMaskOpacityText_(tileMaskOpacityInput.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.TilePreferencesController.prototype.onTileModeChange_ = function (evt) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.SEAMLESS_MODE, evt.currentTarget.checked);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.TilePreferencesController.prototype.onTileMaskOpacityChange_ = function (evt) {
|
|
||||||
var target = evt.target;
|
|
||||||
var opacity = parseFloat(target.value);
|
|
||||||
if (!isNaN(opacity)) {
|
|
||||||
pskl.UserSettings.set(pskl.UserSettings.SEAMLESS_OPACITY, opacity);
|
|
||||||
this.updateTileMaskOpacityText_(opacity);
|
|
||||||
} else {
|
|
||||||
target.value = pskl.UserSettings.get(pskl.UserSettings.SEAMLESS_OPACITY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.TilePreferencesController.prototype.updateTileMaskOpacityText_ = function (opacity) {
|
|
||||||
var seamlessOpacityText = document.querySelector('.tile-mask-opacity-text');
|
|
||||||
seamlessOpacityText.innerHTML = (opacity * 1).toFixed(2);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,31 +1,12 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.widgets');
|
var ns = $.namespace('pskl.controller.settings.resize');
|
||||||
|
|
||||||
var OPTION_CLASSNAME = 'anchor-option';
|
var OPTION_CLASSNAME = 'resize-origin-option';
|
||||||
// Maybe move to HTML ...
|
|
||||||
var WIDGET_TEMPLATE =
|
|
||||||
'<div class="anchor-option" title="top left" data-origin="TOPLEFT"></div>' +
|
|
||||||
'<div class="anchor-option" title="top" data-origin="TOP"></div>' +
|
|
||||||
'<div class="anchor-option" title="top right" data-origin="TOPRIGHT"></div>' +
|
|
||||||
'<div class="anchor-option" title="middle left" data-origin="MIDDLELEFT"></div>' +
|
|
||||||
'<div class="anchor-option" title="middle" data-origin="MIDDLE"></div>' +
|
|
||||||
'<div class="anchor-option" title="middle right" data-origin="MIDDLERIGHT"></div>' +
|
|
||||||
'<div class="anchor-option" title="bottom left" data-origin="BOTTOMLEFT"></div>' +
|
|
||||||
'<div class="anchor-option" title="bottom" data-origin="BOTTOM"></div>' +
|
|
||||||
'<div class="anchor-option" title="bottom right" data-origin="BOTTOMRIGHT"></div>';
|
|
||||||
|
|
||||||
ns.AnchorWidget = function (container, onChangeCallback) {
|
|
||||||
this.onChangeCallback = onChangeCallback;
|
|
||||||
|
|
||||||
this.wrapper = document.createElement('div');
|
|
||||||
this.wrapper.classList.add('anchor-wrapper');
|
|
||||||
this.wrapper.innerHTML = WIDGET_TEMPLATE;
|
|
||||||
|
|
||||||
container.innerHTML = '';
|
|
||||||
container.appendChild(this.wrapper);
|
|
||||||
|
|
||||||
|
ns.AnchorWidget = function (container) {
|
||||||
|
this.container = container;
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
pskl.utils.Event.addEventListener(this.wrapper, 'click', this.onResizeOriginClick_, this);
|
pskl.utils.Event.addEventListener(this.container, 'click', this.onResizeOriginClick_, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnchorWidget.ORIGIN = {
|
ns.AnchorWidget.ORIGIN = {
|
||||||
@@ -42,7 +23,7 @@
|
|||||||
|
|
||||||
ns.AnchorWidget.prototype.destroy = function (evt) {
|
ns.AnchorWidget.prototype.destroy = function (evt) {
|
||||||
pskl.utils.Event.removeAllEventListeners(this);
|
pskl.utils.Event.removeAllEventListeners(this);
|
||||||
this.wrapper = null;
|
this.container = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnchorWidget.prototype.onResizeOriginClick_ = function (evt) {
|
ns.AnchorWidget.prototype.onResizeOriginClick_ = function (evt) {
|
||||||
@@ -54,20 +35,16 @@
|
|||||||
|
|
||||||
ns.AnchorWidget.prototype.setOrigin = function (origin) {
|
ns.AnchorWidget.prototype.setOrigin = function (origin) {
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
var previous = this.wrapper.querySelector('.' + OPTION_CLASSNAME + '.selected');
|
var previous = document.querySelector('.' + OPTION_CLASSNAME + '.selected');
|
||||||
if (previous) {
|
if (previous) {
|
||||||
previous.classList.remove('selected');
|
previous.classList.remove('selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
var selected = this.wrapper.querySelector('.' + OPTION_CLASSNAME + '[data-origin="' + origin + '"]');
|
var selected = document.querySelector('.' + OPTION_CLASSNAME + '[data-origin="' + origin + '"]');
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selected.classList.add('selected');
|
selected.classList.add('selected');
|
||||||
this.refreshNeighbors_(selected);
|
this.refreshNeighbors_(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this.onChangeCallback === 'function') {
|
|
||||||
this.onChangeCallback(origin);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnchorWidget.prototype.getOrigin = function () {
|
ns.AnchorWidget.prototype.getOrigin = function () {
|
||||||
@@ -76,18 +53,18 @@
|
|||||||
|
|
||||||
ns.AnchorWidget.prototype.disable = function () {
|
ns.AnchorWidget.prototype.disable = function () {
|
||||||
this.disabled = true;
|
this.disabled = true;
|
||||||
this.wrapper.classList.add('transition');
|
this.container.classList.add('transition');
|
||||||
this.wrapper.classList.add('disabled');
|
this.container.classList.add('disabled');
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnchorWidget.prototype.enable = function () {
|
ns.AnchorWidget.prototype.enable = function () {
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
this.wrapper.classList.remove('disabled');
|
this.container.classList.remove('disabled');
|
||||||
window.setTimeout(this.wrapper.classList.remove.bind(this.wrapper.classList, 'transition'), 250);
|
window.setTimeout(this.container.classList.remove.bind(this.container.classList, 'transition'), 250);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.AnchorWidget.prototype.refreshNeighbors_ = function (selected) {
|
ns.AnchorWidget.prototype.refreshNeighbors_ = function (selected) {
|
||||||
var options = this.wrapper.querySelectorAll('.' + OPTION_CLASSNAME);
|
var options = document.querySelectorAll('.' + OPTION_CLASSNAME);
|
||||||
for (var i = 0 ; i < options.length ; i++) {
|
for (var i = 0 ; i < options.length ; i++) {
|
||||||
options[i].removeAttribute('data-neighbor');
|
options[i].removeAttribute('data-neighbor');
|
||||||
}
|
}
|
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
this.container = document.querySelector('.resize-canvas');
|
this.container = document.querySelector('.resize-canvas');
|
||||||
|
|
||||||
var anchorWidgetContainer = this.container.querySelector('.resize-anchor-container');
|
var anchorWidgetContainer = this.container.querySelector('.resize-origin-container');
|
||||||
this.anchorWidget = new pskl.widgets.AnchorWidget(anchorWidgetContainer);
|
this.anchorWidget = new ns.AnchorWidget(anchorWidgetContainer);
|
||||||
this.defaultSizeController = new ns.DefaultSizeController(piskelController);
|
this.defaultSizeController = new ns.DefaultSizeController(piskelController);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
var settings = pskl.UserSettings.get('RESIZE_SETTINGS');
|
var settings = pskl.UserSettings.get('RESIZE_SETTINGS');
|
||||||
var origin = pskl.widgets.AnchorWidget.ORIGIN[settings.origin] || 'TOPLEFT';
|
var origin = ns.AnchorWidget.ORIGIN[settings.origin] || ns.AnchorWidget.ORIGIN.TOPLEFT;
|
||||||
this.anchorWidget.setOrigin(origin);
|
this.anchorWidget.setOrigin(origin);
|
||||||
|
|
||||||
if (settings.resizeContent) {
|
if (settings.resizeContent) {
|
||||||
@@ -61,21 +61,27 @@
|
|||||||
ns.ResizeController.prototype.onResizeFormSubmit_ = function (evt) {
|
ns.ResizeController.prototype.onResizeFormSubmit_ = function (evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
var currentPiskel = this.piskelController.getPiskel();
|
var resizedLayers = this.piskelController.getLayers().map(this.resizeLayer_.bind(this));
|
||||||
var piskel = pskl.utils.ResizeUtils.resizePiskel(currentPiskel, {
|
|
||||||
width : parseInt(this.widthInput.value, 10),
|
|
||||||
height : parseInt(this.heightInput.value, 10),
|
|
||||||
origin: this.anchorWidget.getOrigin(),
|
|
||||||
resizeContent: this.resizeContentCheckbox.checked
|
|
||||||
});
|
|
||||||
|
|
||||||
pskl.app.piskelController.setPiskel(piskel, {
|
var currentPiskel = this.piskelController.getPiskel();
|
||||||
preserveState: true
|
var fps = this.piskelController.getFPS();
|
||||||
});
|
var piskel = pskl.model.Piskel.fromLayers(resizedLayers, fps, currentPiskel.getDescriptor());
|
||||||
|
// propagate savepath to new Piskel
|
||||||
|
piskel.savePath = currentPiskel.savePath;
|
||||||
|
|
||||||
|
pskl.app.piskelController.setPiskel(piskel, true);
|
||||||
|
|
||||||
$.publish(Events.CLOSE_SETTINGS_DRAWER);
|
$.publish(Events.CLOSE_SETTINGS_DRAWER);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.ResizeController.prototype.resizeLayer_ = function (layer) {
|
||||||
|
var opacity = layer.getOpacity();
|
||||||
|
var resizedFrames = layer.getFrames().map(this.resizeFrame_.bind(this));
|
||||||
|
var resizedLayer = pskl.model.Layer.fromFrames(layer.getName(), resizedFrames);
|
||||||
|
resizedLayer.setOpacity(opacity);
|
||||||
|
return resizedLayer;
|
||||||
|
};
|
||||||
|
|
||||||
ns.ResizeController.prototype.onResizeContentChange_ = function (evt) {
|
ns.ResizeController.prototype.onResizeContentChange_ = function (evt) {
|
||||||
var target = evt.target;
|
var target = evt.target;
|
||||||
if (target.checked) {
|
if (target.checked) {
|
||||||
@@ -101,4 +107,55 @@
|
|||||||
maintainRatio : !!this.maintainRatioCheckbox.checked
|
maintainRatio : !!this.maintainRatioCheckbox.checked
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* RESIZE LOGIC */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
ns.ResizeController.prototype.resizeFrame_ = function (frame) {
|
||||||
|
var width = parseInt(this.widthInput.value, 10);
|
||||||
|
var height = parseInt(this.heightInput.value, 10);
|
||||||
|
if (this.resizeContentCheckbox.checked) {
|
||||||
|
return pskl.utils.FrameUtils.resize(frame, width, height, false);
|
||||||
|
} else {
|
||||||
|
var resizedFrame = new pskl.model.Frame(width, height);
|
||||||
|
frame.forEachPixel(function (color, x, y) {
|
||||||
|
var translated = this.translateCoordinates_(x, y, frame, resizedFrame);
|
||||||
|
if (resizedFrame.containsPixel(translated.x, translated.y)) {
|
||||||
|
resizedFrame.setPixel(translated.x, translated.y, color);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
return resizedFrame;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ResizeController.prototype.translateCoordinates_ = function (x, y, frame, resizedFrame) {
|
||||||
|
return {
|
||||||
|
x : this.translateX_(x, frame.width, resizedFrame.width),
|
||||||
|
y : this.translateY_(y, frame.height, resizedFrame.height)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ResizeController.prototype.translateX_ = function (x, width, resizedWidth) {
|
||||||
|
var origin = this.anchorWidget.getOrigin();
|
||||||
|
if (origin.indexOf('LEFT') != -1) {
|
||||||
|
return x;
|
||||||
|
} else if (origin.indexOf('RIGHT') != -1) {
|
||||||
|
return x - (width - resizedWidth);
|
||||||
|
} else {
|
||||||
|
return x - Math.round((width - resizedWidth) / 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.ResizeController.prototype.translateY_ = function (y, height, resizedHeight) {
|
||||||
|
var origin = this.anchorWidget.getOrigin();
|
||||||
|
if (origin.indexOf('TOP') != -1) {
|
||||||
|
return y;
|
||||||
|
} else if (origin.indexOf('BOTTOM') != -1) {
|
||||||
|
return y - (height - resizedHeight);
|
||||||
|
} else {
|
||||||
|
return y - Math.round((height - resizedHeight) / 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -1,258 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.database');
|
|
||||||
|
|
||||||
var DB_NAME = 'PiskelSessionsDatabase';
|
|
||||||
var DB_VERSION = 1;
|
|
||||||
|
|
||||||
// Simple wrapper to promisify a request.
|
|
||||||
var _requestPromise = function (req) {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
req.onsuccess = deferred.resolve.bind(deferred);
|
|
||||||
req.onerror = deferred.reject.bind(deferred);
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The BackupDatabase handles all the database interactions related
|
|
||||||
* to piskel snapshots continuously saved while during the usage of
|
|
||||||
* Piskel.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase = function () {
|
|
||||||
this.db = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupDatabase.DB_NAME = DB_NAME;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open and initialize the database.
|
|
||||||
* Returns a promise that resolves when the databse is opened.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.init = function () {
|
|
||||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
|
||||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
|
||||||
|
|
||||||
return _requestPromise(request).then(function (event) {
|
|
||||||
this.db = event.target.result;
|
|
||||||
return this.db;
|
|
||||||
}.bind(this)).catch(function (e) {
|
|
||||||
console.log('Could not initialize the piskel backup database');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupDatabase.prototype.onUpgradeNeeded_ = function (event) {
|
|
||||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
|
||||||
this.db = event.target.result;
|
|
||||||
|
|
||||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
|
||||||
var objectStore = this.db.createObjectStore('snapshots', { keyPath: 'id', autoIncrement : true });
|
|
||||||
|
|
||||||
objectStore.createIndex('session_id', 'session_id', { unique: false });
|
|
||||||
objectStore.createIndex('date', 'date', { unique: false });
|
|
||||||
objectStore.createIndex('session_id, date', ['session_id', 'date'], { unique: false });
|
|
||||||
|
|
||||||
objectStore.transaction.oncomplete = function(event) {
|
|
||||||
// Nothing to do at the moment!
|
|
||||||
}.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupDatabase.prototype.openObjectStore_ = function () {
|
|
||||||
return this.db.transaction(['snapshots'], 'readwrite').objectStore('snapshots');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an add request for the provided snapshot.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.createSnapshot = function (snapshot) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
var request = objectStore.add(snapshot);
|
|
||||||
return _requestPromise(request);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a put request for the provided snapshot.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.updateSnapshot = function (snapshot) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
var request = objectStore.put(snapshot);
|
|
||||||
return _requestPromise(request);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a delete request for the provided snapshot.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.deleteSnapshot = function (snapshot) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
var request = objectStore.delete(snapshot.id);
|
|
||||||
return _requestPromise(request);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a get request for the provided snapshotId.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.getSnapshot = function (snapshotId) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
var request = objectStore.get(snapshotId);
|
|
||||||
return _requestPromise(request).then(function (event) {
|
|
||||||
return event.target.result;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the last (most recent) snapshot that satisfies the accept filter provided.
|
|
||||||
* Returns a promise that will resolve with the first matching snapshot (or null
|
|
||||||
* if no valid snapshot is found).
|
|
||||||
*
|
|
||||||
* @param {Function} accept:
|
|
||||||
* Filter method that takes a snapshot as argument and should return true
|
|
||||||
* if the snapshot is valid.
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.findLastSnapshot = function (accept) {
|
|
||||||
// Create the backup promise.
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
// Open a transaction to the snapshots object store.
|
|
||||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
|
||||||
|
|
||||||
var index = objectStore.index('date');
|
|
||||||
var range = IDBKeyRange.upperBound(Infinity);
|
|
||||||
index.openCursor(range, 'prev').onsuccess = function(event) {
|
|
||||||
var cursor = event.target.result;
|
|
||||||
var snapshot = cursor && cursor.value;
|
|
||||||
|
|
||||||
// Resolve null if we couldn't find a matching snapshot.
|
|
||||||
if (!snapshot) {
|
|
||||||
deferred.resolve(null);
|
|
||||||
} else if (accept(snapshot)) {
|
|
||||||
deferred.resolve(snapshot);
|
|
||||||
} else {
|
|
||||||
cursor.continue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve all the snapshots for a given session id, sorted by descending date order.
|
|
||||||
* Returns a promise that resolves with an array of snapshots.
|
|
||||||
*
|
|
||||||
* @param {String} sessionId
|
|
||||||
* The session id
|
|
||||||
*/
|
|
||||||
ns.BackupDatabase.prototype.getSnapshotsBySessionId = function (sessionId) {
|
|
||||||
// Create the backup promise.
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
// Open a transaction to the snapshots object store.
|
|
||||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
|
||||||
|
|
||||||
// Loop on all the saved snapshots for the provided piskel id
|
|
||||||
var index = objectStore.index('session_id, date');
|
|
||||||
var keyRange = IDBKeyRange.bound(
|
|
||||||
[sessionId, 0],
|
|
||||||
[sessionId, Infinity]
|
|
||||||
);
|
|
||||||
|
|
||||||
var snapshots = [];
|
|
||||||
// Ordered by date in descending order.
|
|
||||||
index.openCursor(keyRange, 'prev').onsuccess = function(event) {
|
|
||||||
var cursor = event.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
snapshots.push(cursor.value);
|
|
||||||
cursor.continue();
|
|
||||||
} else {
|
|
||||||
// Consumed all piskel snapshots
|
|
||||||
deferred.resolve(snapshots);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupDatabase.prototype.getSessions = function () {
|
|
||||||
// Create the backup promise.
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
// Open a transaction to the snapshots object store.
|
|
||||||
var objectStore = this.db.transaction(['snapshots']).objectStore('snapshots');
|
|
||||||
|
|
||||||
var sessions = {};
|
|
||||||
|
|
||||||
var _createSession = function (snapshot) {
|
|
||||||
sessions[snapshot.session_id] = {
|
|
||||||
startDate: snapshot.date,
|
|
||||||
endDate: snapshot.date,
|
|
||||||
name: snapshot.name,
|
|
||||||
description: snapshot.description,
|
|
||||||
id: snapshot.session_id,
|
|
||||||
count: 1
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var _updateSession = function (snapshot) {
|
|
||||||
var s = sessions[snapshot.session_id];
|
|
||||||
s.startDate = Math.min(s.startDate, snapshot.date);
|
|
||||||
s.endDate = Math.max(s.endDate, snapshot.date);
|
|
||||||
s.count++;
|
|
||||||
|
|
||||||
if (s.endDate === snapshot.date) {
|
|
||||||
// If the endDate was updated, update also the session metadata to
|
|
||||||
// reflect the latest state.
|
|
||||||
s.name = snapshot.name;
|
|
||||||
s.description = snapshot.description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var index = objectStore.index('date');
|
|
||||||
var range = IDBKeyRange.upperBound(Infinity);
|
|
||||||
index.openCursor(range, 'prev').onsuccess = function(event) {
|
|
||||||
var cursor = event.target.result;
|
|
||||||
var snapshot = cursor && cursor.value;
|
|
||||||
if (!snapshot) {
|
|
||||||
deferred.resolve(sessions);
|
|
||||||
} else {
|
|
||||||
if (sessions[snapshot.session_id]) {
|
|
||||||
_updateSession(snapshot);
|
|
||||||
} else {
|
|
||||||
_createSession(snapshot);
|
|
||||||
}
|
|
||||||
cursor.continue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return deferred.promise.then(function (sessions) {
|
|
||||||
// Convert the sessions map to an array.
|
|
||||||
return Object.keys(sessions).map(function (key) {
|
|
||||||
return sessions[key];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupDatabase.prototype.deleteSnapshotsForSession = function (sessionId) {
|
|
||||||
// Create the backup promise.
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
// Open a transaction to the snapshots object store.
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
|
|
||||||
// Loop on all the saved snapshots for the provided piskel id
|
|
||||||
var index = objectStore.index('session_id');
|
|
||||||
var keyRange = IDBKeyRange.only(sessionId);
|
|
||||||
|
|
||||||
index.openCursor(keyRange).onsuccess = function(event) {
|
|
||||||
var cursor = event.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
cursor.delete();
|
|
||||||
cursor.continue();
|
|
||||||
} else {
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,141 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.database');
|
|
||||||
|
|
||||||
var DB_NAME = 'PiskelDatabase';
|
|
||||||
var DB_VERSION = 1;
|
|
||||||
|
|
||||||
// Simple wrapper to promisify a request.
|
|
||||||
var _requestPromise = function (req) {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
req.onsuccess = deferred.resolve.bind(deferred);
|
|
||||||
req.onerror = deferred.reject.bind(deferred);
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PiskelDatabase handles all the database interactions related
|
|
||||||
* to the local piskel saved that can be performed in-browser.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase = function (options) {
|
|
||||||
this.db = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PiskelDatabase.DB_NAME = DB_NAME;
|
|
||||||
|
|
||||||
ns.PiskelDatabase.prototype.init = function () {
|
|
||||||
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
|
|
||||||
request.onupgradeneeded = this.onUpgradeNeeded_.bind(this);
|
|
||||||
|
|
||||||
return _requestPromise(request).then(function (event) {
|
|
||||||
this.db = event.target.result;
|
|
||||||
return this.db;
|
|
||||||
}.bind(this)).catch(function (e) {
|
|
||||||
console.log('Failed to initialize IndexedDB, local browser saves will be unavailable.');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PiskelDatabase.prototype.onUpgradeNeeded_ = function (event) {
|
|
||||||
// Set this.db early to allow migration scripts to access it in oncomplete.
|
|
||||||
this.db = event.target.result;
|
|
||||||
|
|
||||||
// Create an object store "piskels" with the autoIncrement flag set as true.
|
|
||||||
var objectStore = this.db.createObjectStore('piskels', { keyPath : 'name' });
|
|
||||||
objectStore.transaction.oncomplete = function(event) {
|
|
||||||
pskl.database.migrate.MigrateLocalStorageToIndexedDb.migrate(this);
|
|
||||||
}.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PiskelDatabase.prototype.openObjectStore_ = function () {
|
|
||||||
return this.db.transaction(['piskels'], 'readwrite').objectStore('piskels');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a get request for the provided name.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase.prototype.get = function (name) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
return _requestPromise(objectStore.get(name)).then(function (event) {
|
|
||||||
return event.target.result;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List all locally saved piskels.
|
|
||||||
* Returns a promise that resolves an array of objects:
|
|
||||||
* - name: name of the piskel
|
|
||||||
* - description: description of the piskel
|
|
||||||
* - date: save date
|
|
||||||
*
|
|
||||||
* The sprite content is not contained in the object and
|
|
||||||
* needs to be retrieved with a separate get.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase.prototype.list = function () {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
var piskels = [];
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
var cursor = objectStore.openCursor();
|
|
||||||
cursor.onsuccess = function(event) {
|
|
||||||
var cursor = event.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
piskels.push({
|
|
||||||
name: cursor.value.name,
|
|
||||||
date: cursor.value.date,
|
|
||||||
description: cursor.value.description
|
|
||||||
});
|
|
||||||
cursor.continue();
|
|
||||||
} else {
|
|
||||||
// Cursor consumed all availabled piskels
|
|
||||||
deferred.resolve(piskels);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cursor.onerror = function () {
|
|
||||||
deferred.reject();
|
|
||||||
};
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an put request for the provided args.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase.prototype.update = function (name, description, date, serialized) {
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
data.name = name;
|
|
||||||
data.serialized = serialized;
|
|
||||||
data.date = date;
|
|
||||||
data.description = description;
|
|
||||||
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
return _requestPromise(objectStore.put(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an add request for the provided args.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase.prototype.create = function (name, description, date, serialized) {
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
data.name = name;
|
|
||||||
data.serialized = serialized;
|
|
||||||
data.date = date;
|
|
||||||
data.description = description;
|
|
||||||
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
return _requestPromise(objectStore.add(data));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a saved piskel for the provided name.
|
|
||||||
* Returns a promise that resolves the request event.
|
|
||||||
*/
|
|
||||||
ns.PiskelDatabase.prototype.delete = function (name) {
|
|
||||||
var objectStore = this.openObjectStore_();
|
|
||||||
return _requestPromise(objectStore.delete(name));
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -1,76 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.database.migrate');
|
|
||||||
|
|
||||||
// Simple migration helper to move local storage saves to indexed db.
|
|
||||||
ns.MigrateLocalStorageToIndexedDb = {};
|
|
||||||
|
|
||||||
ns.MigrateLocalStorageToIndexedDb.migrate = function (piskelDatabase) {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
var localStorageService = pskl.app.localStorageService;
|
|
||||||
|
|
||||||
var localStorageKeys = localStorageService.getKeys();
|
|
||||||
var migrationData = localStorageKeys.map(function (key) {
|
|
||||||
return {
|
|
||||||
name: key.name,
|
|
||||||
description: key.description,
|
|
||||||
date: key.date,
|
|
||||||
serialized: localStorageService.getPiskel(key.name)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Define the sequential migration process.
|
|
||||||
// Wait for each sprite to be saved before saving the next one.
|
|
||||||
var success = true;
|
|
||||||
var migrateSprite = function (index) {
|
|
||||||
var data = migrationData[index];
|
|
||||||
if (!data) {
|
|
||||||
console.log('Data migration from local storage to indexed db finished.');
|
|
||||||
if (success) {
|
|
||||||
console.log('Local storage piskels successfully migrated. Old copies will be deleted.');
|
|
||||||
ns.MigrateLocalStorageToIndexedDb.deleteLocalStoragePiskels();
|
|
||||||
}
|
|
||||||
|
|
||||||
deferred.resolve();
|
|
||||||
} else {
|
|
||||||
ns.MigrateLocalStorageToIndexedDb.save_(piskelDatabase, data)
|
|
||||||
.then(function () {
|
|
||||||
migrateSprite(index + 1);
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
var success = false;
|
|
||||||
console.error('Failed to migrate local storage sprite for name: ' + data.name);
|
|
||||||
migrateSprite(index + 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Start the migration.
|
|
||||||
migrateSprite(0);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MigrateLocalStorageToIndexedDb.save_ = function (piskelDatabase, piskelData) {
|
|
||||||
return piskelDatabase.get(piskelData.name).then(function (data) {
|
|
||||||
if (typeof data !== 'undefined') {
|
|
||||||
return piskelDatabase.update(piskelData.name, piskelData.description, piskelData.date, piskelData.serialized);
|
|
||||||
} else {
|
|
||||||
return piskelDatabase.create(piskelData.name, piskelData.description, piskelData.date, piskelData.serialized);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.MigrateLocalStorageToIndexedDb.deleteLocalStoragePiskels = function () {
|
|
||||||
var localStorageKeys = pskl.app.localStorageService.getKeys();
|
|
||||||
|
|
||||||
// Remove all sprites.
|
|
||||||
localStorageKeys.forEach(function (key) {
|
|
||||||
window.localStorage.removeItem('piskel.' + key.name);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove keys.
|
|
||||||
window.localStorage.removeItem('piskel.keys');
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@@ -108,8 +108,6 @@
|
|||||||
this.playTransformToolEvent_(recordEvent);
|
this.playTransformToolEvent_(recordEvent);
|
||||||
} else if (recordEvent.type === 'instrumented-event') {
|
} else if (recordEvent.type === 'instrumented-event') {
|
||||||
this.playInstrumentedEvent_(recordEvent);
|
this.playInstrumentedEvent_(recordEvent);
|
||||||
} else if (recordEvent.type === 'clipboard-event') {
|
|
||||||
this.playClipboardEvent_(recordEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the time spent replaying the event
|
// Record the time spent replaying the event
|
||||||
@@ -171,16 +169,6 @@
|
|||||||
pskl.app.piskelController[recordEvent.methodName].apply(pskl.app.piskelController, recordEvent.args);
|
pskl.app.piskelController[recordEvent.methodName].apply(pskl.app.piskelController, recordEvent.args);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingTestPlayer.prototype.playClipboardEvent_ = function (recordEvent) {
|
|
||||||
$.publish(recordEvent.event.type, {
|
|
||||||
preventDefault: function () {},
|
|
||||||
clipboardData: {
|
|
||||||
items: [],
|
|
||||||
setData: function () {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.DrawingTestPlayer.prototype.onTestEnd_ = function () {
|
ns.DrawingTestPlayer.prototype.onTestEnd_ = function () {
|
||||||
this.removeMouseShim_();
|
this.removeMouseShim_();
|
||||||
// Restore the original drawing loop.
|
// Restore the original drawing loop.
|
||||||
|
@@ -15,10 +15,6 @@
|
|||||||
$.subscribe(Events.TRANSFORMATION_EVENT, this.onTransformationEvent_.bind(this));
|
$.subscribe(Events.TRANSFORMATION_EVENT, this.onTransformationEvent_.bind(this));
|
||||||
$.subscribe(Events.PRIMARY_COLOR_SELECTED, this.onColorEvent_.bind(this, true));
|
$.subscribe(Events.PRIMARY_COLOR_SELECTED, this.onColorEvent_.bind(this, true));
|
||||||
$.subscribe(Events.SECONDARY_COLOR_SELECTED, this.onColorEvent_.bind(this, false));
|
$.subscribe(Events.SECONDARY_COLOR_SELECTED, this.onColorEvent_.bind(this, false));
|
||||||
$.subscribe(Events.CLIPBOARD_COPY, this.onClipboardEvent_.bind(this));
|
|
||||||
$.subscribe(Events.CLIPBOARD_CUT, this.onClipboardEvent_.bind(this));
|
|
||||||
$.subscribe(Events.CLIPBOARD_PASTE, this.onClipboardEvent_.bind(this));
|
|
||||||
|
|
||||||
|
|
||||||
for (var key in this.piskelController) {
|
for (var key in this.piskelController) {
|
||||||
if (typeof this.piskelController[key] == 'function') {
|
if (typeof this.piskelController[key] == 'function') {
|
||||||
@@ -89,7 +85,7 @@
|
|||||||
which : domEvent.which,
|
which : domEvent.which,
|
||||||
shiftKey : domEvent.shiftKey,
|
shiftKey : domEvent.shiftKey,
|
||||||
altKey : domEvent.altKey,
|
altKey : domEvent.altKey,
|
||||||
ctrlKey : domEvent.ctrlKey || domEvent.metaKey,
|
ctrlKey : domEvent.ctrlKey,
|
||||||
target : {
|
target : {
|
||||||
nodeName : domEvent.target.nodeName
|
nodeName : domEvent.target.nodeName
|
||||||
}
|
}
|
||||||
@@ -140,27 +136,12 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.DrawingTestRecorder.prototype.onClipboardEvent_ = function (evt) {
|
|
||||||
if (this.isRecording) {
|
|
||||||
var recordEvent = {};
|
|
||||||
recordEvent.type = 'clipboard-event';
|
|
||||||
recordEvent.event = evt;
|
|
||||||
this.events.push(recordEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.DrawingTestRecorder.prototype.onInstrumentedMethod_ = function (callee, methodName, args) {
|
ns.DrawingTestRecorder.prototype.onInstrumentedMethod_ = function (callee, methodName, args) {
|
||||||
if (this.isRecording) {
|
if (this.isRecording) {
|
||||||
var recordEvent = {};
|
var recordEvent = {};
|
||||||
recordEvent.type = 'instrumented-event';
|
recordEvent.type = 'instrumented-event';
|
||||||
recordEvent.methodName = methodName;
|
recordEvent.methodName = methodName;
|
||||||
recordEvent.args = Array.prototype.slice.call(args, 0);
|
recordEvent.args = Array.prototype.slice.call(args, 0);
|
||||||
|
|
||||||
if (methodName === 'setPiskel' && args[1].noSnapshot) {
|
|
||||||
// Skip recording calls to setPiskel that don't trigger a save.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.events.push(recordEvent);
|
this.events.push(recordEvent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@
|
|||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.savePath = null;
|
this.savePath = null;
|
||||||
this.fps = fps;
|
this.fps = fps;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw 'Missing arguments in Piskel constructor : ' + Array.prototype.join.call(arguments, ',');
|
throw 'Missing arguments in Piskel constructor : ' + Array.prototype.join.call(arguments, ',');
|
||||||
}
|
}
|
||||||
@@ -69,10 +70,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Piskel.prototype.getFrameCount = function () {
|
|
||||||
return this.getLayerAt(0).size();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.Piskel.prototype.addLayer = function (layer) {
|
ns.Piskel.prototype.addLayer = function (layer) {
|
||||||
this.layers.push(layer);
|
this.layers.push(layer);
|
||||||
};
|
};
|
||||||
@@ -81,28 +78,20 @@
|
|||||||
this.layers.splice(index, 0, layer);
|
this.layers.splice(index, 0, layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Piskel.prototype.moveLayerUp = function (layer, toTop) {
|
ns.Piskel.prototype.moveLayerUp = function (layer) {
|
||||||
var index = this.layers.indexOf(layer);
|
var index = this.layers.indexOf(layer);
|
||||||
var toIndex = toTop ? this.layers.length - 1 : index + 1;
|
if (index > -1 && index < this.layers.length - 1) {
|
||||||
this.moveLayer_(index, toIndex);
|
this.layers[index] = this.layers[index + 1];
|
||||||
};
|
this.layers[index + 1] = layer;
|
||||||
|
}
|
||||||
ns.Piskel.prototype.moveLayerDown = function (layer, toBottom) {
|
};
|
||||||
var index = this.layers.indexOf(layer);
|
|
||||||
var toIndex = toBottom ? 0 : index - 1;
|
ns.Piskel.prototype.moveLayerDown = function (layer) {
|
||||||
this.moveLayer_(index, toIndex);
|
var index = this.layers.indexOf(layer);
|
||||||
};
|
if (index > 0) {
|
||||||
|
this.layers[index] = this.layers[index - 1];
|
||||||
/**
|
this.layers[index - 1] = layer;
|
||||||
* Move the layer at the provided index to the provided toIndex.
|
|
||||||
*/
|
|
||||||
ns.Piskel.prototype.moveLayer_ = function (fromIndex, toIndex) {
|
|
||||||
if (fromIndex == -1 || toIndex == -1 || fromIndex == toIndex) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
toIndex = pskl.utils.Math.minmax(toIndex, 0, this.layers.length - 1);
|
|
||||||
var layer = this.layers.splice(fromIndex, 1)[0];
|
|
||||||
this.layers.splice(toIndex, 0, layer);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.Piskel.prototype.removeLayer = function (layer) {
|
ns.Piskel.prototype.removeLayer = function (layer) {
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
var serializedFrame = [
|
var serializedFrame = [
|
||||||
this.getZoom(),
|
this.getZoom(),
|
||||||
this.getGridWidth(),
|
this.getGridWidth(),
|
||||||
this.getGridColor(),
|
|
||||||
pskl.UserSettings.get('SEAMLESS_MODE'),
|
pskl.UserSettings.get('SEAMLESS_MODE'),
|
||||||
pskl.UserSettings.get('SEAMLESS_OPACITY'),
|
pskl.UserSettings.get('SEAMLESS_OPACITY'),
|
||||||
offset.x, offset.y,
|
offset.x, offset.y,
|
||||||
|
@@ -55,7 +55,7 @@
|
|||||||
this.displayCanvas = null;
|
this.displayCanvas = null;
|
||||||
this.setDisplaySize(renderingOptions.width, renderingOptions.height);
|
this.setDisplaySize(renderingOptions.width, renderingOptions.height);
|
||||||
|
|
||||||
this.setGridWidth(this.getUserGridWidth_());
|
this.setGridWidth(pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH));
|
||||||
|
|
||||||
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
|
$.subscribe(Events.USER_SETTINGS_CHANGED, this.onUserSettingsChange_.bind(this));
|
||||||
};
|
};
|
||||||
@@ -138,10 +138,6 @@
|
|||||||
this.offset.y = y;
|
this.offset.y = y;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.getGridColor = function () {
|
|
||||||
return pskl.UserSettings.get(pskl.UserSettings.GRID_COLOR);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.setGridWidth = function (value) {
|
ns.FrameRenderer.prototype.setGridWidth = function (value) {
|
||||||
this.gridWidth_ = value;
|
this.gridWidth_ = value;
|
||||||
};
|
};
|
||||||
@@ -184,18 +180,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) {
|
ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) {
|
||||||
var settings = pskl.UserSettings;
|
if (settingName == pskl.UserSettings.GRID_WIDTH) {
|
||||||
if (settingName == settings.GRID_WIDTH || settingName == settings.GRID_ENABLED) {
|
this.setGridWidth(settingValue);
|
||||||
this.setGridWidth(this.getUserGridWidth_());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FrameRenderer.prototype.getUserGridWidth_ = function () {
|
|
||||||
var gridEnabled = pskl.UserSettings.get(pskl.UserSettings.GRID_ENABLED);
|
|
||||||
var width = pskl.UserSettings.get(pskl.UserSettings.GRID_WIDTH);
|
|
||||||
return gridEnabled ? width : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered
|
* Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered
|
||||||
* frame) into a sprite coordinate in column and row.
|
* frame) into a sprite coordinate in column and row.
|
||||||
@@ -263,24 +252,14 @@
|
|||||||
var displayContext = this.displayCanvas.getContext('2d');
|
var displayContext = this.displayCanvas.getContext('2d');
|
||||||
displayContext.save();
|
displayContext.save();
|
||||||
|
|
||||||
var translateX = this.margin.x - this.offset.x * z;
|
// Draw background
|
||||||
var translateY = this.margin.y - this.offset.y * z;
|
displayContext.fillStyle = Constants.ZOOMED_OUT_BACKGROUND_COLOR;
|
||||||
|
displayContext.fillRect(0, 0, this.displayCanvas.width - 1, this.displayCanvas.height - 1);
|
||||||
|
|
||||||
var isZoomedOut = translateX > 0 || translateY > 0;
|
displayContext.translate(
|
||||||
// Draw the background / zoomed-out color only if needed. Otherwise the clearRect
|
this.margin.x - this.offset.x * z,
|
||||||
// happening after that will clear "out of bounds" and seems to be doing nothing
|
this.margin.y - this.offset.y * z
|
||||||
// on some chromebooks (cf https://github.com/piskelapp/piskel/issues/651)
|
);
|
||||||
if (isZoomedOut) {
|
|
||||||
// Draw background
|
|
||||||
displayContext.fillStyle = Constants.ZOOMED_OUT_BACKGROUND_COLOR;
|
|
||||||
// The -1 on the width and height here is a workaround for a Chrome-only bug
|
|
||||||
// that was potentially fixed, but is very hardware dependant. Seems to be
|
|
||||||
// triggered when doing clear rect or fill rect using the full width & height
|
|
||||||
// of a canvas. (https://bugs.chromium.org/p/chromium/issues/detail?id=469906)
|
|
||||||
displayContext.fillRect(0, 0, this.displayCanvas.width - 1, this.displayCanvas.height - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
displayContext.translate(translateX, translateY);
|
|
||||||
|
|
||||||
// Scale up to draw the canvas content
|
// Scale up to draw the canvas content
|
||||||
displayContext.scale(z, z);
|
displayContext.scale(z, z);
|
||||||
@@ -299,25 +278,15 @@
|
|||||||
// Draw grid.
|
// Draw grid.
|
||||||
var gridWidth = this.computeGridWidthForDisplay_();
|
var gridWidth = this.computeGridWidthForDisplay_();
|
||||||
if (gridWidth > 0) {
|
if (gridWidth > 0) {
|
||||||
var gridColor = this.getGridColor();
|
|
||||||
// Scale out before drawing the grid.
|
// Scale out before drawing the grid.
|
||||||
displayContext.scale(1 / z, 1 / z);
|
displayContext.scale(1 / z, 1 / z);
|
||||||
|
// Clear vertical lines.
|
||||||
var drawOrClear;
|
|
||||||
if (gridColor === Constants.TRANSPARENT_COLOR) {
|
|
||||||
drawOrClear = displayContext.clearRect.bind(displayContext);
|
|
||||||
} else {
|
|
||||||
displayContext.fillStyle = gridColor;
|
|
||||||
drawOrClear = displayContext.fillRect.bind(displayContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw or clear vertical lines.
|
|
||||||
for (var i = 1 ; i < frame.getWidth() ; i++) {
|
for (var i = 1 ; i < frame.getWidth() ; i++) {
|
||||||
drawOrClear((i * z) - (gridWidth / 2), 0, gridWidth, h * z);
|
displayContext.clearRect((i * z) - (gridWidth / 2), 0, gridWidth, h * z);
|
||||||
}
|
}
|
||||||
// Draw or clear horizontal lines.
|
// Clear horizontal lines.
|
||||||
for (var j = 1 ; j < frame.getHeight() ; j++) {
|
for (var j = 1 ; j < frame.getHeight() ; j++) {
|
||||||
drawOrClear(0, (j * z) - (gridWidth / 2), w * z, gridWidth);
|
displayContext.clearRect(0, (j * z) - (gridWidth / 2), w * z, gridWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,23 +5,9 @@
|
|||||||
this.reset();
|
this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseSelection.prototype.stringify = function () {
|
|
||||||
return JSON.stringify({
|
|
||||||
pixels: this.pixels,
|
|
||||||
time: this.time
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BaseSelection.prototype.parse = function (str) {
|
|
||||||
var selectionData = JSON.parse(str);
|
|
||||||
this.pixels = selectionData.pixels;
|
|
||||||
this.time = selectionData.time;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BaseSelection.prototype.reset = function () {
|
ns.BaseSelection.prototype.reset = function () {
|
||||||
this.pixels = [];
|
this.pixels = [];
|
||||||
this.hasPastedContent = false;
|
this.hasPastedContent = false;
|
||||||
this.time = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BaseSelection.prototype.move = function (colDiff, rowDiff) {
|
ns.BaseSelection.prototype.move = function (colDiff, rowDiff) {
|
||||||
@@ -44,8 +30,5 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.hasPastedContent = true;
|
this.hasPastedContent = true;
|
||||||
// Keep track of the selection time to compare between local selection and
|
|
||||||
// paste event selections.
|
|
||||||
this.time = Date.now();
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -17,11 +17,14 @@
|
|||||||
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
|
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
|
||||||
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
|
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
|
||||||
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
|
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
|
||||||
$.subscribe(Events.CLIPBOARD_COPY, this.copy.bind(this));
|
$.subscribe(Events.SELECTION_COPY, this.copy.bind(this));
|
||||||
$.subscribe(Events.CLIPBOARD_CUT, this.copy.bind(this));
|
$.subscribe(Events.SELECTION_CUT, this.cut.bind(this));
|
||||||
$.subscribe(Events.CLIPBOARD_PASTE, this.paste.bind(this));
|
$.subscribe(Events.SELECTION_PASTE, this.paste.bind(this));
|
||||||
|
|
||||||
var shortcuts = pskl.service.keyboard.Shortcuts;
|
var shortcuts = pskl.service.keyboard.Shortcuts;
|
||||||
|
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.PASTE, this.paste.bind(this));
|
||||||
|
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.CUT, this.cut.bind(this));
|
||||||
|
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.COPY, this.copy.bind(this));
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.DELETE, this.onDeleteShortcut_.bind(this));
|
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.DELETE, this.onDeleteShortcut_.bind(this));
|
||||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.COMMIT, this.commit.bind(this));
|
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.COMMIT, this.commit.bind(this));
|
||||||
|
|
||||||
@@ -75,85 +78,29 @@
|
|||||||
scope : this,
|
scope : this,
|
||||||
replay : {
|
replay : {
|
||||||
type : SELECTION_REPLAY.ERASE,
|
type : SELECTION_REPLAY.ERASE,
|
||||||
pixels : JSON.parse(JSON.stringify(pixels))
|
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SelectionManager.prototype.copy = function(event, domEvent) {
|
ns.SelectionManager.prototype.cut = function() {
|
||||||
if (this.currentSelection && this.piskelController.getCurrentFrame()) {
|
if (this.currentSelection) {
|
||||||
|
// Put cut target into the selection:
|
||||||
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||||
if (domEvent) {
|
this.erase();
|
||||||
domEvent.clipboardData.setData('text/plain', this.currentSelection.stringify());
|
|
||||||
domEvent.preventDefault();
|
|
||||||
}
|
|
||||||
if (event.type === Events.CLIPBOARD_CUT) {
|
|
||||||
this.erase();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.SelectionManager.prototype.paste = function(event, domEvent) {
|
ns.SelectionManager.prototype.paste = function() {
|
||||||
var items = domEvent ? domEvent.clipboardData.items : [];
|
if (!this.currentSelection || !this.currentSelection.hasPastedContent) {
|
||||||
|
if (window.localStorage.getItem('piskel.clipboard')) {
|
||||||
try {
|
this.currentSelection = JSON.parse(window.localStorage.getItem('piskel.clipboard'));
|
||||||
for (var i = 0 ; i < items.length ; i++) {
|
} else {
|
||||||
var item = items[i];
|
return;
|
||||||
|
|
||||||
if (/^image/i.test(item.type)) {
|
|
||||||
this.pasteImage_(item);
|
|
||||||
event.stopPropagation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/^text\/plain/i.test(item.type)) {
|
|
||||||
this.pasteText_(item);
|
|
||||||
event.stopPropagation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
// Some of the clipboard APIs are not available on Safari/IE
|
|
||||||
// Allow Piskel to fallback on local currentSelection pasting.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporarily keeping this code path for tests and fallbacks.
|
var pixels = this.currentSelection.pixels;
|
||||||
if (this.currentSelection && this.currentSelection.hasPastedContent) {
|
|
||||||
this.pastePixelsOnCurrentFrame_(this.currentSelection.pixels);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectionManager.prototype.pasteImage_ = function(clipboardItem) {
|
|
||||||
var blob = clipboardItem.getAsFile();
|
|
||||||
pskl.utils.FileUtils.readImageFile(blob, function (image) {
|
|
||||||
pskl.app.fileDropperService.dropPosition_ = {x: 0, y: 0};
|
|
||||||
pskl.app.fileDropperService.onImageLoaded_(image, blob);
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectionManager.prototype.pasteText_ = function(clipboardItem) {
|
|
||||||
var blob = clipboardItem.getAsString(function (selectionString) {
|
|
||||||
var selectionData = JSON.parse(selectionString);
|
|
||||||
var time = selectionData.time;
|
|
||||||
var pixels = selectionData.pixels;
|
|
||||||
|
|
||||||
if (this.currentSelection && this.currentSelection.time >= time) {
|
|
||||||
// If the local selection is newer or equal to the one coming from the clipboard event
|
|
||||||
// use the local one. The reason is that the "move" information is only updated locally
|
|
||||||
// without synchronizing it to the clipboard.
|
|
||||||
// TODO: the selection should store the origin of the selection and the selection itself
|
|
||||||
// separately.
|
|
||||||
pixels = this.currentSelection.pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixels) {
|
|
||||||
// If the current clipboard data is some random text, pixels will not be defined.
|
|
||||||
this.pastePixelsOnCurrentFrame_(pixels);
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.SelectionManager.prototype.pastePixelsOnCurrentFrame_ = function (pixels) {
|
|
||||||
var frame = this.piskelController.getCurrentFrame();
|
var frame = this.piskelController.getCurrentFrame();
|
||||||
|
|
||||||
this.pastePixels_(frame, pixels);
|
this.pastePixels_(frame, pixels);
|
||||||
@@ -176,7 +123,8 @@
|
|||||||
var tool = pskl.app.drawingController.currentToolBehavior;
|
var tool = pskl.app.drawingController.currentToolBehavior;
|
||||||
var isSelectionTool = tool instanceof pskl.tools.drawing.selection.BaseSelect;
|
var isSelectionTool = tool instanceof pskl.tools.drawing.selection.BaseSelect;
|
||||||
if (isSelectionTool) {
|
if (isSelectionTool) {
|
||||||
tool.commitSelection();
|
var overlay = pskl.app.drawingController.overlayFrame;
|
||||||
|
tool.commitSelection(overlay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,6 +147,13 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.SelectionManager.prototype.copy = function() {
|
||||||
|
if (this.currentSelection && this.piskelController.getCurrentFrame()) {
|
||||||
|
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||||
|
window.localStorage.setItem('piskel.clipboard', JSON.stringify(this.currentSelection));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
@@ -1,161 +1,65 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.service');
|
var ns = $.namespace('pskl.service');
|
||||||
|
|
||||||
var ONE_SECOND = 1000;
|
// 1 minute = 1000 * 60
|
||||||
var ONE_MINUTE = 60 * ONE_SECOND;
|
var BACKUP_INTERVAL = 1000 * 60;
|
||||||
|
|
||||||
// Save every minute = 1000 * 60
|
ns.BackupService = function (piskelController) {
|
||||||
var BACKUP_INTERVAL = ONE_MINUTE;
|
|
||||||
// Store a new snapshot every 5 minutes.
|
|
||||||
var SNAPSHOT_INTERVAL = ONE_MINUTE * 5;
|
|
||||||
// Store up to 12 snapshots for a piskel session, min. 1 hour of work
|
|
||||||
var MAX_SNAPSHOTS_PER_SESSION = 12;
|
|
||||||
var MAX_SESSIONS = 10;
|
|
||||||
|
|
||||||
ns.BackupService = function (piskelController, backupDatabase) {
|
|
||||||
this.piskelController = piskelController;
|
this.piskelController = piskelController;
|
||||||
// Immediately store the current when initializing the Service to avoid storing
|
this.lastHash = null;
|
||||||
// empty sessions.
|
|
||||||
this.lastHash = this.piskelController.getPiskel().getHash();
|
|
||||||
this.nextSnapshotDate = -1;
|
|
||||||
|
|
||||||
// backupDatabase can be provided for testing purposes.
|
|
||||||
this.backupDatabase = backupDatabase || new pskl.database.BackupDatabase();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BackupService.prototype.init = function () {
|
ns.BackupService.prototype.init = function () {
|
||||||
this.backupDatabase.init().then(function () {
|
var previousPiskel = window.localStorage.getItem('bkp.next.piskel');
|
||||||
window.setInterval(this.backup.bind(this), BACKUP_INTERVAL);
|
var previousInfo = window.localStorage.getItem('bkp.next.info');
|
||||||
}.bind(this));
|
if (previousPiskel && previousInfo) {
|
||||||
};
|
this.savePiskel_('prev', previousPiskel, previousInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// This is purely exposed for testing, so that backup dates can be set programmatically.
|
window.setInterval(this.backup.bind(this), BACKUP_INTERVAL);
|
||||||
ns.BackupService.prototype.currentDate_ = function () {
|
|
||||||
return Date.now();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BackupService.prototype.backup = function () {
|
ns.BackupService.prototype.backup = function () {
|
||||||
var piskel = this.piskelController.getPiskel();
|
var piskel = this.piskelController.getPiskel();
|
||||||
var hash = piskel.getHash();
|
|
||||||
|
|
||||||
// Do not save an unchanged piskel
|
|
||||||
if (hash === this.lastHash) {
|
|
||||||
return Q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the hash
|
|
||||||
// TODO: should only be done after a successful save.
|
|
||||||
this.lastHash = hash;
|
|
||||||
|
|
||||||
// Prepare the backup snapshot.
|
|
||||||
var descriptor = piskel.getDescriptor();
|
var descriptor = piskel.getDescriptor();
|
||||||
var date = this.currentDate_();
|
var hash = piskel.getHash();
|
||||||
var snapshot = {
|
var info = {
|
||||||
session_id: pskl.app.sessionId,
|
name : descriptor.name,
|
||||||
date: date,
|
description : descriptor.info,
|
||||||
name: descriptor.name,
|
date : Date.now(),
|
||||||
description: descriptor.description,
|
hash : hash
|
||||||
frames: piskel.getFrameCount(),
|
|
||||||
width: piskel.getWidth(),
|
|
||||||
height: piskel.getHeight(),
|
|
||||||
fps: piskel.getFPS(),
|
|
||||||
serialized: pskl.utils.serialization.Serializer.serialize(piskel)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.getSnapshotsBySessionId(pskl.app.sessionId).then(function (snapshots) {
|
// Do not save an unchanged piskel
|
||||||
var latest = snapshots[0];
|
if (hash !== this.lastHash) {
|
||||||
|
this.lastHash = hash;
|
||||||
if (latest && date < this.nextSnapshotDate) {
|
var serializedPiskel = pskl.utils.serialization.Serializer.serialize(piskel);
|
||||||
// update the latest snapshot
|
this.savePiskel_('next', serializedPiskel, JSON.stringify(info));
|
||||||
snapshot.id = latest.id;
|
}
|
||||||
return this.backupDatabase.updateSnapshot(snapshot);
|
|
||||||
} else {
|
|
||||||
// add a new snapshot
|
|
||||||
this.nextSnapshotDate = date + SNAPSHOT_INTERVAL;
|
|
||||||
return this.backupDatabase.createSnapshot(snapshot).then(function () {
|
|
||||||
if (snapshots.length >= MAX_SNAPSHOTS_PER_SESSION) {
|
|
||||||
// remove oldest snapshot
|
|
||||||
return this.backupDatabase.deleteSnapshot(snapshots[snapshots.length - 1]);
|
|
||||||
}
|
|
||||||
}.bind(this)).then(function () {
|
|
||||||
var isNewSession = !latest;
|
|
||||||
if (!isNewSession) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return this.backupDatabase.getSessions().then(function (sessions) {
|
|
||||||
if (sessions.length <= MAX_SESSIONS) {
|
|
||||||
// If MAX_SESSIONS has not been reached, no need to delete
|
|
||||||
// previous sessions.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare an array containing all the ids of the sessions to be deleted.
|
|
||||||
var sessionIdsToDelete = sessions.sort(function (s1, s2) {
|
|
||||||
return s1.startDate - s2.startDate;
|
|
||||||
}).map(function (s) {
|
|
||||||
return s.id;
|
|
||||||
}).slice(0, sessions.length - MAX_SESSIONS);
|
|
||||||
|
|
||||||
// Delete all the extra sessions.
|
|
||||||
return Q.all(sessionIdsToDelete.map(function (id) {
|
|
||||||
return this.deleteSession(id);
|
|
||||||
}.bind(this)));
|
|
||||||
}.bind(this));
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
}.bind(this)).catch(function (e) {
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupService.prototype.getSnapshotsBySessionId = function (sessionId) {
|
|
||||||
return this.backupDatabase.getSnapshotsBySessionId(sessionId);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupService.prototype.deleteSession = function (sessionId) {
|
|
||||||
return this.backupDatabase.deleteSnapshotsForSession(sessionId);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BackupService.prototype.getPreviousPiskelInfo = function () {
|
ns.BackupService.prototype.getPreviousPiskelInfo = function () {
|
||||||
return this.backupDatabase.findLastSnapshot(function (snapshot) {
|
var previousInfo = window.localStorage.getItem('bkp.prev.info');
|
||||||
return snapshot.session_id !== pskl.app.sessionId;
|
if (previousInfo) {
|
||||||
});
|
return JSON.parse(previousInfo);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.BackupService.prototype.list = function() {
|
|
||||||
return this.backupDatabase.getSessions();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.BackupService.prototype.loadSnapshotById = function(snapshotId) {
|
|
||||||
var deferred = Q.defer();
|
|
||||||
|
|
||||||
this.backupDatabase.getSnapshot(snapshotId).then(function (snapshot) {
|
|
||||||
pskl.utils.serialization.Deserializer.deserialize(
|
|
||||||
JSON.parse(snapshot.serialized),
|
|
||||||
function (piskel) {
|
|
||||||
pskl.app.piskelController.setPiskel(piskel);
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load "latest" backup snapshot.
|
|
||||||
ns.BackupService.prototype.load = function() {
|
ns.BackupService.prototype.load = function() {
|
||||||
var deferred = Q.defer();
|
var previousPiskel = window.localStorage.getItem('bkp.prev.piskel');
|
||||||
|
previousPiskel = JSON.parse(previousPiskel);
|
||||||
|
|
||||||
this.getPreviousPiskelInfo().then(function (snapshot) {
|
pskl.utils.serialization.Deserializer.deserialize(previousPiskel, function (piskel) {
|
||||||
pskl.utils.serialization.Deserializer.deserialize(
|
pskl.app.piskelController.setPiskel(piskel);
|
||||||
JSON.parse(snapshot.serialized),
|
|
||||||
function (piskel) {
|
|
||||||
pskl.app.piskelController.setPiskel(piskel);
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return deferred.promise;
|
ns.BackupService.prototype.savePiskel_ = function (type, piskel, info) {
|
||||||
|
try {
|
||||||
|
window.localStorage.setItem('bkp.' + type + '.piskel', piskel);
|
||||||
|
window.localStorage.setItem('bkp.' + type + '.info', info);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not save piskel backup in localStorage.', e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -30,11 +30,9 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.BeforeUnloadService.prototype.onBeforeUnload = function (evt) {
|
ns.BeforeUnloadService.prototype.onBeforeUnload = function (evt) {
|
||||||
// Attempt one last backup. Some of it may fail due to the asynchronous
|
|
||||||
// nature of IndexedDB.
|
|
||||||
pskl.app.backupService.backup();
|
pskl.app.backupService.backup();
|
||||||
if (pskl.app.savedStatusService.isDirty()) {
|
if (pskl.app.savedStatusService.isDirty()) {
|
||||||
var confirmationMessage = 'Your current sprite has unsaved changes. Are you sure you want to quit?';
|
var confirmationMessage = 'Your Piskel seems to have unsaved changes';
|
||||||
|
|
||||||
evt = evt || window.event;
|
evt = evt || window.event;
|
||||||
if (evt) {
|
if (evt) {
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.service');
|
|
||||||
|
|
||||||
ns.ClipboardService = function (piskelController) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ClipboardService.prototype.init = function () {
|
|
||||||
window.addEventListener('copy', this._onCopy.bind(this), true);
|
|
||||||
window.addEventListener('cut', this._onCut.bind(this), true);
|
|
||||||
window.addEventListener('paste', this._onPaste.bind(this), true);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ClipboardService.prototype._onCut = function (event) {
|
|
||||||
$.publish(Events.CLIPBOARD_CUT, event);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ClipboardService.prototype._onCopy = function (event) {
|
|
||||||
$.publish(Events.CLIPBOARD_COPY, event);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ClipboardService.prototype._onPaste = function (event) {
|
|
||||||
$.publish(Events.CLIPBOARD_PASTE, event);
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -35,9 +35,7 @@
|
|||||||
var isPiskel = /\.piskel$/i.test(file.name);
|
var isPiskel = /\.piskel$/i.test(file.name);
|
||||||
var isPalette = /\.(gpl|txt|pal)$/i.test(file.name);
|
var isPalette = /\.(gpl|txt|pal)$/i.test(file.name);
|
||||||
if (isImage) {
|
if (isImage) {
|
||||||
pskl.utils.FileUtils.readImageFile(file, function (image) {
|
this.readImageFile_(file);
|
||||||
this.onImageLoaded_(image, file);
|
|
||||||
}.bind(this));
|
|
||||||
} else if (isPiskel) {
|
} else if (isPiskel) {
|
||||||
pskl.utils.PiskelFileUtils.loadFromFile(file, this.onPiskelFileLoaded_, this.onPiskelFileError_);
|
pskl.utils.PiskelFileUtils.loadFromFile(file, this.onPiskelFileLoaded_, this.onPiskelFileError_);
|
||||||
} else if (isPalette) {
|
} else if (isPalette) {
|
||||||
@@ -46,13 +44,17 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.FileDropperService.prototype.readImageFile_ = function (imageFile) {
|
||||||
|
pskl.utils.FileUtils.readFile(imageFile, this.processImageSource_.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
ns.FileDropperService.prototype.onPaletteLoaded_ = function (palette) {
|
ns.FileDropperService.prototype.onPaletteLoaded_ = function (palette) {
|
||||||
pskl.app.paletteService.savePalette(palette);
|
pskl.app.paletteService.savePalette(palette);
|
||||||
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, palette.id);
|
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, palette.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FileDropperService.prototype.onPiskelFileLoaded_ = function (piskel) {
|
ns.FileDropperService.prototype.onPiskelFileLoaded_ = function (piskel) {
|
||||||
if (window.confirm(Constants.CONFIRM_OVERWRITE)) {
|
if (window.confirm('This will replace your current animation')) {
|
||||||
pskl.app.piskelController.setPiskel(piskel);
|
pskl.app.piskelController.setPiskel(piskel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -61,23 +63,16 @@
|
|||||||
$.publish(Events.PISKEL_FILE_IMPORT_FAILED, [reason]);
|
$.publish(Events.PISKEL_FILE_IMPORT_FAILED, [reason]);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.FileDropperService.prototype.onImageLoaded_ = function (importedImage, file) {
|
ns.FileDropperService.prototype.processImageSource_ = function (imageSource) {
|
||||||
var piskelWidth = pskl.app.piskelController.getWidth();
|
var importedImage = new Image();
|
||||||
var piskelHeight = pskl.app.piskelController.getHeight();
|
importedImage.onload = this.onImageLoaded_.bind(this, importedImage);
|
||||||
|
importedImage.src = imageSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.FileDropperService.prototype.onImageLoaded_ = function (importedImage) {
|
||||||
if (this.isMultipleFiles_) {
|
if (this.isMultipleFiles_) {
|
||||||
this.piskelController.addFrameAtCurrentIndex();
|
this.piskelController.addFrameAtCurrentIndex();
|
||||||
this.piskelController.selectNextFrame();
|
this.piskelController.selectNextFrame();
|
||||||
} else if (importedImage.width > piskelWidth || importedImage.height > piskelHeight) {
|
|
||||||
// For single file imports, if the file is too big, trigger the import wizard.
|
|
||||||
$.publish(Events.DIALOG_SHOW, {
|
|
||||||
dialogId : 'import',
|
|
||||||
initArgs : {
|
|
||||||
rawFiles: [file]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentFrame = this.piskelController.getCurrentFrame();
|
var currentFrame = this.piskelController.getCurrentFrame();
|
||||||
|
@@ -15,17 +15,10 @@
|
|||||||
data : imageData
|
data : imageData
|
||||||
};
|
};
|
||||||
|
|
||||||
var protocol = pskl.utils.Environment.isHttps() ? 'https' : 'http';
|
|
||||||
var wrappedSuccess = function (response) {
|
var wrappedSuccess = function (response) {
|
||||||
var getUrl = pskl.utils.Template.replace(Constants.IMAGE_SERVICE_GET_URL, {
|
success(Constants.IMAGE_SERVICE_GET_URL + response.responseText);
|
||||||
protocol: protocol
|
|
||||||
});
|
|
||||||
success(getUrl + response.responseText);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var uploadUrl = pskl.utils.Template.replace(Constants.IMAGE_SERVICE_UPLOAD_URL, {
|
pskl.utils.Xhr.post(Constants.IMAGE_SERVICE_UPLOAD_URL, data, wrappedSuccess, error);
|
||||||
protocol: protocol
|
|
||||||
});
|
|
||||||
pskl.utils.Xhr.post(uploadUrl, data, wrappedSuccess, error);
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -28,24 +28,19 @@
|
|||||||
/**
|
/**
|
||||||
* Given an image object and some options, create a new Piskel and open it
|
* Given an image object and some options, create a new Piskel and open it
|
||||||
* for editing.
|
* for editing.
|
||||||
* @param {Image} image
|
* @param {!Image} image
|
||||||
* @param {Object} options
|
* @param {!Object} options
|
||||||
* - {String} importType 'single' if not spritesheet
|
* @param {!string} options.importType - 'single' if not spritesheet
|
||||||
* - {String} name
|
* @param {!number} options.frameSizeX
|
||||||
* - {Boolean} smoothing
|
* @param {!number} options.frameSizeY
|
||||||
* - {Number} frameSizeX
|
* @param {number} [options.frameOffsetX] only used in spritesheet imports.
|
||||||
* - {Number} frameSizeY
|
* @param {number} [options.frameOffsetY] only used in spritesheet imports.
|
||||||
* - {Number} frameOffsetX (only used in spritesheet imports)
|
* @param {!boolean} options.smoothing
|
||||||
* - {Number} frameOffsetY (only used in spritesheet imports)
|
* @param {function} [onComplete]
|
||||||
* @param {Function} onComplete
|
|
||||||
* Callback called when the new piskel has been created, with the new piskel
|
|
||||||
* as single argument.
|
|
||||||
*/
|
*/
|
||||||
ns.ImportService.prototype.newPiskelFromImage = function (image, options, onComplete) {
|
ns.ImportService.prototype.newPiskelFromImage = function (image, options, onComplete) {
|
||||||
onComplete = onComplete || Constants.EMPTY_FUNCTION;
|
onComplete = onComplete || Constants.EMPTY_FUNCTION;
|
||||||
var importType = options.importType;
|
var importType = options.importType;
|
||||||
var name = options.name;
|
|
||||||
var smoothing = options.smoothing;
|
|
||||||
var frameSizeX = options.frameSizeX;
|
var frameSizeX = options.frameSizeX;
|
||||||
var frameSizeY = options.frameSizeY;
|
var frameSizeY = options.frameSizeY;
|
||||||
var frameOffsetX = options.frameOffsetX;
|
var frameOffsetX = options.frameOffsetX;
|
||||||
@@ -61,28 +56,26 @@
|
|||||||
return pskl.utils.CanvasUtils.createFromImageData(frame.data);
|
return pskl.utils.CanvasUtils.createFromImageData(frame.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
var piskel;
|
|
||||||
if (importType === 'single' || images.length > 1) {
|
if (importType === 'single' || images.length > 1) {
|
||||||
// Single image import or animated gif
|
// Single image import or animated gif
|
||||||
piskel = this.createPiskelFromImages_(images, name, frameSizeX, frameSizeY, smoothing);
|
this.createPiskelFromImages_(images, frameSizeX, frameSizeY, options.smoothing);
|
||||||
} else {
|
} else {
|
||||||
// Spritesheet
|
// Spritesheet
|
||||||
var frameImages = this.createImagesFromSheet_(images[0], frameSizeX, frameSizeY, frameOffsetX, frameOffsetY);
|
var frameImages = this.createImagesFromSheet_(images[0]);
|
||||||
piskel = this.createPiskelFromImages_(frameImages, name, frameSizeX, frameSizeY, smoothing);
|
this.createPiskelFromImages_(frameImages, frameSizeX, frameSizeY, options.smoothing);
|
||||||
}
|
}
|
||||||
onComplete(piskel);
|
onComplete();
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
error: function () {
|
error: function () {
|
||||||
var piskel;
|
|
||||||
if (importType === 'single') {
|
if (importType === 'single') {
|
||||||
// Single image
|
// Single image
|
||||||
piskel = this.createPiskelFromImages_([image], name, frameSizeX, frameSizeY, smoothing);
|
this.createPiskelFromImages_([image], frameSizeX, frameSizeY, options.smoothing);
|
||||||
} else {
|
} else {
|
||||||
// Spritesheet
|
// Spritesheet
|
||||||
var frameImages = this.createImagesFromSheet_(image, frameSizeX, frameSizeY, frameOffsetX, frameOffsetY);
|
var frameImages = this.createImagesFromSheet_(image, frameSizeX, frameSizeY, frameOffsetX, frameOffsetY);
|
||||||
piskel = this.createPiskelFromImages_(frameImages, name, frameSizeX, frameSizeY, smoothing);
|
this.createPiskelFromImages_(frameImages, frameSizeX, frameSizeY, options.smoothing);
|
||||||
}
|
}
|
||||||
onComplete(piskel);
|
onComplete();
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -115,13 +108,14 @@
|
|||||||
* @param {!boolean} smoothing
|
* @param {!boolean} smoothing
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ns.ImportService.prototype.createPiskelFromImages_ = function (images, name,
|
ns.ImportService.prototype.createPiskelFromImages_ = function (images,
|
||||||
frameSizeX, frameSizeY, smoothing) {
|
frameSizeX, frameSizeY, smoothing) {
|
||||||
name = name || 'Imported piskel';
|
|
||||||
var frames = this.createFramesFromImages_(images, frameSizeX, frameSizeY, smoothing);
|
var frames = this.createFramesFromImages_(images, frameSizeX, frameSizeY, smoothing);
|
||||||
var layer = pskl.model.Layer.fromFrames('Layer 1', frames);
|
var layer = pskl.model.Layer.fromFrames('Layer 1', frames);
|
||||||
var descriptor = new pskl.model.piskel.Descriptor(name, '');
|
var descriptor = new pskl.model.piskel.Descriptor('Imported piskel', '');
|
||||||
return pskl.model.Piskel.fromLayers([layer], Constants.DEFAULT.FPS, descriptor);
|
var piskel = pskl.model.Piskel.fromLayers([layer], Constants.DEFAULT.FPS, descriptor);
|
||||||
|
|
||||||
|
this.piskelController_.setPiskel(piskel);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.service.keyboard');
|
|
||||||
|
|
||||||
ns.InputService = function () {
|
|
||||||
this.activeShortcuts_ = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
ns.InputService.prototype.init = function() {
|
|
||||||
$(document.body).keydown($.proxy(this.onKeyDown_, this));
|
|
||||||
$(document.body).keyup($.proxy(this.onKeyUp_, this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InputService.prototype.isKeyPressed = function (shortcut) {
|
|
||||||
return shortcut.getKeys().some(function (key) {
|
|
||||||
return this.activeShortcuts_[key];
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ns.InputService.prototype.onKeyDown_ = function(evt) {
|
|
||||||
var eventKey = ns.KeyUtils.createKeyFromEvent(evt);
|
|
||||||
if (this.isInInput_(evt) || !eventKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.activeShortcuts_[ns.KeyUtils.stringify(eventKey)] = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InputService.prototype.onKeyUp_ = function(evt) {
|
|
||||||
var eventKey = ns.KeyUtils.createKeyFromEvent(evt);
|
|
||||||
if (this.isInInput_(evt) || !eventKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.activeShortcuts_[ns.KeyUtils.stringify(eventKey)] = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.InputService.prototype.isInInput_ = function (evt) {
|
|
||||||
var targetTagName = evt.target.nodeName.toUpperCase();
|
|
||||||
return targetTagName === 'INPUT' || targetTagName === 'TEXTAREA';
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@@ -3,7 +3,6 @@
|
|||||||
8 : 'back',
|
8 : 'back',
|
||||||
13 : 'enter',
|
13 : 'enter',
|
||||||
27 : 'esc',
|
27 : 'esc',
|
||||||
32 : 'space',
|
|
||||||
37 : 'left',
|
37 : 'left',
|
||||||
38 : 'up',
|
38 : 'up',
|
||||||
39 : 'right',
|
39 : 'right',
|
||||||
|
@@ -60,17 +60,7 @@
|
|||||||
FULL_PREVIEW : createShortcut('full-preview', 'Select full size preview', 'alt+3'),
|
FULL_PREVIEW : createShortcut('full-preview', 'Select full size preview', 'alt+3'),
|
||||||
ONION_SKIN : createShortcut('onion-skin', 'Toggle onion skin', 'alt+O'),
|
ONION_SKIN : createShortcut('onion-skin', 'Toggle onion skin', 'alt+O'),
|
||||||
LAYER_PREVIEW : createShortcut('layer-preview', 'Toggle layer preview', 'alt+L'),
|
LAYER_PREVIEW : createShortcut('layer-preview', 'Toggle layer preview', 'alt+L'),
|
||||||
MERGE_ANIMATION : createShortcut('import-animation', 'Open merge animation popup', 'ctrl+shift+M'),
|
CLOSE_POPUP : createShortcut('close-popup', 'Close an opened popup', 'ESC')
|
||||||
CLOSE_POPUP : createShortcut('close-popup', 'Close an opened popup', 'ESC'),
|
|
||||||
OFFSET_UP : createShortcut('move-up', 'Move viewport up', 'shift+up'),
|
|
||||||
OFFSET_RIGHT : createShortcut('move-right', 'Move viewport right', 'shift+right'),
|
|
||||||
OFFSET_DOWN : createShortcut('move-down', 'Move viewport down', 'shift+down'),
|
|
||||||
OFFSET_LEFT : createShortcut('move-left', 'Move viewport left', 'shift+left'),
|
|
||||||
CURSOR_UP : createShortcut('cursor-up', 'Move cursor up', 'alt+up'),
|
|
||||||
CURSOR_RIGHT : createShortcut('cursor-right', 'Move cursor right', 'alt+right'),
|
|
||||||
CURSOR_DOWN : createShortcut('cursor-down', 'Move cursor down', 'alt+down'),
|
|
||||||
CURSOR_LEFT : createShortcut('cursor-left', 'Move cursor left', 'alt+left'),
|
|
||||||
CURSOR_CLICK : createShortcut('cursor-click', 'Click cursor', 'SPACE'),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
STORAGE : {
|
STORAGE : {
|
||||||
@@ -89,10 +79,6 @@
|
|||||||
'123456789'.split(''), '1 to 9')
|
'123456789'.split(''), '1 to 9')
|
||||||
},
|
},
|
||||||
|
|
||||||
DEBUG : {
|
|
||||||
RELOAD_STYLES : createShortcut('move-left', 'Move viewport left', 'ctrl+alt+R'),
|
|
||||||
},
|
|
||||||
|
|
||||||
CATEGORIES : ['TOOL', 'SELECTION', 'MISC', 'STORAGE', 'COLOR']
|
CATEGORIES : ['TOOL', 'SELECTION', 'MISC', 'STORAGE', 'COLOR']
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
ns.PaletteService = function () {
|
ns.PaletteService = function () {
|
||||||
this.dynamicPalettes = [];
|
this.dynamicPalettes = [];
|
||||||
// Exposed for tests.
|
this.localStorageService = window.localStorage;
|
||||||
this.localStorageGlobal = window.localStorage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PaletteService.prototype.getPalettes = function () {
|
ns.PaletteService.prototype.getPalettes = function () {
|
||||||
var palettesString = this.localStorageGlobal.getItem('piskel.palettes');
|
var palettesString = this.localStorageService.getItem('piskel.palettes');
|
||||||
var palettes = JSON.parse(palettesString) || [];
|
var palettes = JSON.parse(palettesString) || [];
|
||||||
palettes = palettes.map(function (palette) {
|
palettes = palettes.map(function (palette) {
|
||||||
return pskl.model.Palette.fromObject(palette);
|
return pskl.model.Palette.fromObject(palette);
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
palettes = palettes.filter(function (palette) {
|
palettes = palettes.filter(function (palette) {
|
||||||
return this.dynamicPalettes.indexOf(palette) === -1;
|
return this.dynamicPalettes.indexOf(palette) === -1;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
this.localStorageGlobal.setItem('piskel.palettes', JSON.stringify(palettes));
|
this.localStorageService.setItem('piskel.palettes', JSON.stringify(palettes));
|
||||||
$.publish(Events.PALETTE_LIST_UPDATED);
|
$.publish(Events.PALETTE_LIST_UPDATED);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.service.storage');
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService = function (piskelController) {
|
|
||||||
this.piskelController = piskelController;
|
|
||||||
this.piskelDatabase = new pskl.database.PiskelDatabase();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.init = function () {
|
|
||||||
this.piskelDatabase.init();
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.save = function (piskel) {
|
|
||||||
var name = piskel.getDescriptor().name;
|
|
||||||
var description = piskel.getDescriptor().description;
|
|
||||||
var date = Date.now();
|
|
||||||
var serialized = pskl.utils.serialization.Serializer.serialize(piskel);
|
|
||||||
|
|
||||||
return this.save_(name, description, date, serialized);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.save_ = function (name, description, date, serialized) {
|
|
||||||
return this.piskelDatabase.get(name).then(function (piskelData) {
|
|
||||||
if (typeof piskelData !== 'undefined') {
|
|
||||||
return this.piskelDatabase.update(name, description, date, serialized);
|
|
||||||
} else {
|
|
||||||
return this.piskelDatabase.create(name, description, date, serialized);
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.load = function (name) {
|
|
||||||
this.piskelDatabase.get(name).then(function (piskelData) {
|
|
||||||
if (typeof piskelData !== 'undefined') {
|
|
||||||
var serialized = piskelData.serialized;
|
|
||||||
pskl.utils.serialization.Deserializer.deserialize(
|
|
||||||
JSON.parse(serialized),
|
|
||||||
function (piskel) {
|
|
||||||
pskl.app.piskelController.setPiskel(piskel);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log('no local browser save found for name: ' + name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.remove = function (name) {
|
|
||||||
this.piskelDatabase.delete(name);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.IndexedDbStorageService.prototype.getKeys = function () {
|
|
||||||
return this.piskelDatabase.list();
|
|
||||||
};
|
|
||||||
})();
|
|
@@ -27,15 +27,10 @@
|
|||||||
return this.delegateSave_(pskl.app.galleryStorageService, piskel);
|
return this.delegateSave_(pskl.app.galleryStorageService, piskel);
|
||||||
};
|
};
|
||||||
|
|
||||||
// @deprecated, use saveToIndexedDb unless indexedDb is not available.
|
|
||||||
ns.StorageService.prototype.saveToLocalStorage = function (piskel) {
|
ns.StorageService.prototype.saveToLocalStorage = function (piskel) {
|
||||||
return this.delegateSave_(pskl.app.localStorageService, piskel);
|
return this.delegateSave_(pskl.app.localStorageService, piskel);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.StorageService.prototype.saveToIndexedDb = function (piskel) {
|
|
||||||
return this.delegateSave_(pskl.app.indexedDbStorageService, piskel);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.StorageService.prototype.saveToFileDownload = function (piskel) {
|
ns.StorageService.prototype.saveToFileDownload = function (piskel) {
|
||||||
return this.delegateSave_(pskl.app.fileDownloadStorageService, piskel);
|
return this.delegateSave_(pskl.app.fileDownloadStorageService, piskel);
|
||||||
};
|
};
|
||||||
@@ -72,7 +67,7 @@
|
|||||||
// wrap in timeout in order to start saving only after event.preventDefault
|
// wrap in timeout in order to start saving only after event.preventDefault
|
||||||
// has been done
|
// has been done
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
this.saveToIndexedDb(this.piskelController.getPiskel());
|
this.saveToLocalStorage(this.piskelController.getPiskel());
|
||||||
}.bind(this), 0);
|
}.bind(this), 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -35,11 +35,7 @@
|
|||||||
var evenY = (coords.y0 + coords.y1) % 2;
|
var evenY = (coords.y0 + coords.y1) % 2;
|
||||||
var rX = coords.x1 - xC;
|
var rX = coords.x1 - xC;
|
||||||
var rY = coords.y1 - yC;
|
var rY = coords.y1 - yC;
|
||||||
|
var x, y, angle, r;
|
||||||
var x;
|
|
||||||
var y;
|
|
||||||
var angle;
|
|
||||||
var r;
|
|
||||||
|
|
||||||
if (penSize == 1) {
|
if (penSize == 1) {
|
||||||
for (x = coords.x0 ; x <= xC ; x++) {
|
for (x = coords.x0 ; x <= xC ; x++) {
|
||||||
|
@@ -97,31 +97,8 @@
|
|||||||
linePixels = pskl.PixelUtils.getLinePixels(col, this.startCol, row, this.startRow);
|
linePixels = pskl.PixelUtils.getLinePixels(col, this.startCol, row, this.startRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw the square ends of the line
|
pskl.PixelUtils.resizePixels(linePixels, penSize).forEach(function (point) {
|
||||||
pskl.PixelUtils.resizePixel(linePixels[0].col, linePixels[0].row, penSize)
|
targetFrame.setPixel(point[0], point[1], color);
|
||||||
.forEach(function (point) {targetFrame.setPixel(point[0], point[1], color);});
|
|
||||||
pskl.PixelUtils.resizePixel(linePixels[linePixels.length - 1].col, linePixels[linePixels.length - 1].row, penSize)
|
|
||||||
.forEach(function (point) {targetFrame.setPixel(point[0], point[1],color);});
|
|
||||||
|
|
||||||
//for each step along the line, draw an x centered on that pixel of size penSize
|
|
||||||
linePixels.forEach(function (point) {
|
|
||||||
for (var i = 0; i < penSize; i++) {
|
|
||||||
targetFrame.setPixel(
|
|
||||||
point.col - Math.floor(penSize / 2) + i, point.row - Math.floor(penSize / 2) + i, color
|
|
||||||
);
|
|
||||||
targetFrame.setPixel(
|
|
||||||
point.col - Math.floor(penSize / 2) + i, point.row + Math.ceil(penSize / 2) - i - 1, color
|
|
||||||
);
|
|
||||||
//draw an additional x directly next to the first to prevent unwanted dithering
|
|
||||||
if (i !== 0) {
|
|
||||||
targetFrame.setPixel(
|
|
||||||
point.col - Math.floor(penSize / 2) + i, point.row - Math.floor(penSize / 2) + i - 1, color
|
|
||||||
);
|
|
||||||
targetFrame.setPixel(
|
|
||||||
point.col - Math.floor(penSize / 2) + i, point.row + Math.ceil(penSize / 2) - i, color
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
ns.AbstractDragSelect.prototype.onSelectStart_ = function (col, row, frame, overlay) {
|
ns.AbstractDragSelect.prototype.onSelectStart_ = function (col, row, frame, overlay) {
|
||||||
if (this.hasSelection) {
|
if (this.hasSelection) {
|
||||||
this.hasSelection = false;
|
this.hasSelection = false;
|
||||||
this.commitSelection();
|
this.commitSelection(overlay);
|
||||||
} else {
|
} else {
|
||||||
this.hasSelection = true;
|
this.hasSelection = true;
|
||||||
this.onDragSelectStart_(col, row);
|
this.onDragSelectStart_(col, row);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user