diff --git a/.gitignore b/.gitignore index e0e9510..b4a3d3f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ routes build node_modules -.idea \ No newline at end of file +.idea +.history \ No newline at end of file diff --git a/Model.drawio b/Model.drawio deleted file mode 100644 index 629b961..0000000 --- a/Model.drawio +++ /dev/null @@ -1 +0,0 @@ -7V1bc+K4Ev41VOU8kPI98BjIZGb3MHuyk9nM7KOCBWhiWxxZBJhfv5ItG2zJxgSMsx5XpSq4Jd/0tVqfultyzxz7m48ELBefsQu9nqG5m5551zMMfWAN2D8u2QqJMxSSOUGukO0Ej+gnFEJNSFfIhWGmIsXYo2iZFU5xEMApzcgAIXidrTbDXvauSzCHkuBxCjxZ+g25dBFLB8bNTv4JovkiuTN7wbjEB0ll8SbhArh4vScyP/TMMcGYxr/8zRh6vPWSdvn22/abN3lxPv7+Z/h/8Nfov1//eOrHF7s/5pT0FQgM6Jsv3X+6tz5PHp5mqz/+fnn83+Oy/xX3LUe8G90mDQZd1n7iEBO6wHMcAO/DTjoieBW4kF9WY0e7OhOMl0yoM+EPSOlWKANYUcxEC+p7opS9Btl+Zwd97VpLBX/zC15rw1RwtxG3iI+2+0cPkCAfUkiEMH4N/uw52A+0magX4hWZilN/vszuPz1ZP74vH+7/XGsfb59/74u21Sggc0hLGnRPM1ifgpg9I9myEwn0AEWv2acDQrfnab0dfuyHgFANZ9lTvgJvJe70lfW18DMMVhLO4Rr5Hgg4oDMc0ARy9vAj4KF5wH5PWdvxFh69QkIR61O3ooByoEfTBfLcCdjiFW+RkILpS3I0WmCCfrLLggRzVkyo0AjDydR45GcKHAkMWZ2HBDY9FU1ASEWdKfY8sAzRc/TAvIrPYEHBCFOK/eRCGSVN+250QAl+Sa2BnmpPVWXhrQE3e0jKcItSJ7GCifU0xfF6Z4p0R8gW+2bI0opVRNzuCzOXIJizRkjvZ5i5+1kV72c42dsBjwEfAApHvBlDSTHTV327rpqSrvbF2BBKusqam+7ppQdntFArwyWYomA+iercWTvJF/G6XITZuTMv0ogFcl0YRBpDAQWxUnE1WWIU0Kg97BH7Y6021q7tns0eaMyO9d0x++PVCR3jgCkXQJEWQaaxa8i1tkwZhVnUlFpY2skPa+E2C+6xSnA2s2RJUEsIeyiyRHuDhNxLD8DvMyCj8Ung/TUajfq6pBOmrBOmAn8PPEPvAYeIIsyvT+K6Ob04BH1doNpGNVAHNWFqKzAdcUyhx+wSH3aukPufHtcpU4+1mxczLpir0LKuXhfeTkVLPigZOKoCrqaKg0apIm//faJ4gCSekQ8qW6MqH9SdC/FB5d1tu1HMctTesP8loJlmo6DdNAHae2l7Y9hk2zuNzIffS9s7dpNtL09eH9AGspZGFBMJlm76mp++SlyiqgYVTl9T11fJ9NVQziTMEtr5r5u+qgd2SVv59NXD83CP8/YjQkwpo6R58ZLpBaRhhiBnKsyQB/MngSnvhveIN1rZebHDJyOmO0dQ9jmAxx5QdYYHtpCoTnERYO+5go/bkEK/+Elipg9dRpUpV8O2Uf1jZvUHOmexQTxmVq/ui5pVk8E2pC4gQdzyaX0NqFY1sWeY16vZpwziLzzNsyoyJ91okjnJ/rV4iOgo08UpUz/lLMe6/NOIaXs5k+wz7Ee9lxN8HnrO8QcU3kZ8p5hhxBSluDzmSxNeS8lN2AigKnydbVTi6QJOXyB5xoC4orxjNEeNfdaxjEYdHDPrYjROx2jOjqpe2XNdE6g3ClB5KAIHkXlhFu9KjlPggLXNXnHLOnp9YA+qgW0aNaE9kND+8MreaLSSo8odH6qfDzk5OmQZFa2BrrWeDg2VdIgpmffM1OHXzoJ4i2kanIVdnCMLQj1HlB3cHbs4FdULpkGoQZX9wAmBuIKvkddzvNepZaIBfUTjmh3LqAp6VUZZlkR3Guqy61M9IewoxiVcLo59kGOk3pWMqW9VlqVaU9VplgHwJW+Le9j9EoufUKwWefkET19g/irTJPhT5KNxCVgzMzUGwStQBMleEVwnZS0zj3XzoSKndEkASdVL6nO36F1iaA24qhwuSmBr40RFuaEUz5khjc0HoluF2yWuERsSRfFq6TJr+bBvFXK1WmYialQS2VGjVJKbuhw1tiWhddHcxGtNy4Yar7Ubo9fs0qOSFNJ3H4TUZed5xIm7xUdNZW+92fV20/7sLTkooIwnciG3Hh886HcpTG8YhQrS34/0ydXHQOVwQcdAT4a16YifLnvWY/4I3Dhwr6CWBPpYpAqoFy6tlh6DlJZU8SEboEeQ9V5l8YyNwmwqfOt5ituLQjG1Vj4fn7OnT98yO1SfKlaMR+pl2TenZUmqF2V3lKgBSjSwsxSlqqHSh613FBpyIKPIURg+isTuNs+862ZGRRtFHMmMrNqSu+UQR8eMTob1pmFmZMjhALFsmw8HKo9bqCIjIeu3qsooJ5SSqmLLUZBvFaaFLbMl9alTZXZTlxfPkF34Xzg/4A3Z0ZyGaI6uDd/Ic8z28xx1Evp0RXiTR5rSNvNTO5U5T1p3bU4eQ/ZMd1TmZFibdvIYRXndKJgS1gCQ92UF03BhaXEIIyNwxY1/x0Sqa0NFJuLURkRkn9/D/tLmjoZcnIbktw/op5sT7WvJQMULjNbzkORR8zwEe7iLQJ2TnBTsJ1NCTlQaWZufxVQlEHfk5ERYVX4WFax1kZNkeZMqAjWOuvhV3NOLAlEllXL1uXIA8pEAF7Emi8/QRdY5/20oOA6DZLSdrHwUcARViVhxlTtAXgIY5pOsdhUeAV0RwHWgsMoY+0scxI/mLxW1fD40YtI5fo7RbwXdUum3btXFt0zZk3if7jzTka2Lk61+nmylC+gO6kj7V9qZqozUbpA9ZISK9kE8kjvVNsiq/Dp8SAngmtsiVZhhCYOCohC8wgeCf6jjE3DDm3ivvBupqilJ4tU7pCSOU5OW2LoE1q+8B6op3GYHs4mtgvHmMtnEpuzd+4RCisWlO3ZxYXZh5iJK1b9k0P5tjUw5iTTaiJEAH3ar1o4eT26OJh1KPajNYaNKLu245Imw2hW7d11c0pLdsSKnJXCxMh1XKeYkUoxTHUk8Av2K0aNkt4fzwy97YQWM9yTKgOw4x+U5h2O/kXO0P1s3ceup1i/dse6v2idRbMOcDy5No2W0XeLLW/ZCO893l+y6qIqlyvbsqMqJsKqC2BelKs181GWD6Pe937E7wxZHO2cGP8gsl/6+fxCfpVvmAS9IMwute5JnpPjbTU05RqxGvg5T9sVOXXPeI5pJqvvhL84UZDZdCM9ho3jqDE4ni6c2OOSjfC+985gNSi/07SatUTS16+FwkOud9rvc1MKuiGbRxPFCn4OSafZd7uMn3cQwObjYxNDOfVVXHepWOqPbn1foqDd8E+sbEu2V9Lab6pXPCWJLcLpXuq4op9NtpVYDrE3vLusUfmV3gddJX77ia7RlVzTrdfBAlamHQ3jreUm1sPNZV9eNqutfnJIhp0A52CHBmO4PDAQsF/wTKbzGPw== \ No newline at end of file diff --git a/build.js b/build.js index 47444a8..607a923 100644 --- a/build.js +++ b/build.js @@ -2,57 +2,58 @@ const fs = require('fs'); const path = require('path'); const gulp = require('gulp'); const include = require('gulp-include'); -const hb = require('gulp-hb'); +const handlebars = require('gulp-hb'); const sass = require('gulp-sass'); const rename = require('gulp-rename'); -const hb_svg = require('handlebars-helper-svg'); +//const hb_svg = require('handlebars-helper-svg'); const BUILDDIR = process.argv[2] || './build/'; -const SLUG = 'pixel-editor'; + console.log('Building Pixel Editor'); function copy_images(){ // Icons - gulp.src('./images/*.png').pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + gulp.src('./images/*.png').pipe(gulp.dest(BUILDDIR)); // Splash images - gulp.src('./images/Splash images/*.png').pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + gulp.src('./images/Splash images/*.png').pipe(gulp.dest(BUILDDIR)); // Logs images - gulp.src('./images/Logs/*.gif').pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + gulp.src('./images/Logs/*.gif').pipe(gulp.dest(BUILDDIR)); } function copy_logs() { - gulp.src('logs/*.html').pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + gulp.src('logs/*.html').pipe(gulp.dest(BUILDDIR)); } function render_js(){ gulp.src('./js/*.js') .pipe(include({includePaths: [ - '_ext/scripts', 'js', '!js/_*.js', ]})) .on('error', console.log) - .pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + .pipe(gulp.dest(BUILDDIR)); } function render_css(){ gulp.src('css/*.scss') - .pipe(sass({includePaths: ['css', '_ext/sass', '_ext/modules/css']})) - .pipe(gulp.dest(path.join(BUILDDIR, SLUG))); + .pipe(sass({includePaths: ['css']})) + .pipe(gulp.dest(BUILDDIR)); } function compile_page(){ - gulp.src(path.join('./views/', SLUG + '.hbs')) - .pipe(hb({encoding: 'utf8'}) - .partials('./_ext/modules/_*.hbs') - .helpers({ svg: hb_svg }) - .helpers('./_ext/modules/hbs/helpers/**/*.js') + gulp.src(path.join('./views/index.hbs')) + .pipe(include({includePaths: ['/svg']})) + + .pipe(handlebars({encoding: 'utf8', debug: true, bustCache: true}) + .partials('./views/[!index]*.hbs') + //.helpers({ svg: hb_svg }) + .helpers('./helpers/**/*.js') .data({ - projectSlug: SLUG, + projectSlug: 'pixel-editor', title: 'Lospec Pixel Editor', layout: false, })) diff --git a/css/_canvas.scss b/css/_canvas.scss new file mode 100644 index 0000000..40633fb --- /dev/null +++ b/css/_canvas.scss @@ -0,0 +1,103 @@ + + +.drawingCanvas { + cursor: url('/pixel-editor/pencil-tool-cursor.png'); + + border: solid 1px #fff; + image-rendering: optimizeSpeed; + /* Legal fallback */ + image-rendering: -moz-crisp-edges; + /* Firefox */ + image-rendering: -o-crisp-edges; + /* Opera */ + image-rendering: -webkit-optimize-contrast; + /* Safari */ + image-rendering: optimize-contrast; + /* CSS3 Proposed */ + image-rendering: crisp-edges; + /* CSS4 Proposed */ + image-rendering: pixelated; + /* CSS4 Proposed */ + -ms-interpolation-mode: nearest-neighbor; + /* IE8+ */ + width: 400px; + height: 400px; + position: fixed; + display: none; + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.64); + background-color: transparent; +} + +#checkerboard { + z-index: 1; +} + +#pixel-canvas { + z-index: 3; + background: transparent; +} + +#pixel-grid { + z-index: 5000; + background: transparent; +} + +#tmp-canvas { + z-index: 5; + background: transparent; +} + + +#vfx-canvas { + z-index: -5000; + background: transparent; +} + +#eyedropper-preview { + position: absolute; + width: 45px; + height: 45px; + border-radius: 30px; + border: solid 10px red; + z-index: 1200; + display: none; + box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.25), inset 0 0 6px 0 rgba(0, 0, 0, 0.2); + pointer-events: none; + &.dark { + box-shadow: 0 0 8px 0 rgba(255, 255, 255, 0.5), inset 0 0 6px 0 rgba(255, 255, 255, 0.5); + } +} + +#brush-preview { + position: absolute; + border: solid 1px #fff; + z-index: 1200; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5), inset 0 0 2px 0 rgba(0, 0, 0, 0.5); + pointer-events: none; + left: -500px; + &.dark { + border: solid 1px #000; + box-shadow: 0 0 3px 0 rgba(255, 255, 255, 0.8), inset 0 0 3px 0 rgba(255, 255, 255, 0.8); + } +} + +#canvas-view { + bottom: 0px; + left: 64px; + right: 48px; + top: 48px; + cursor: default; + position: fixed; + display: block; +} + +#canvas-view-shadow { + box-shadow: inset 0px 0px 4px 0px rgba(0, 0, 0, 0.4); + position: fixed; + bottom: 0px; + left: 64px; + right: 48px; + top: 48px; + display: block; + pointer-events: none; +} \ No newline at end of file diff --git a/css/_colors-menu.scss b/css/_colors-menu.scss new file mode 100644 index 0000000..ec70b43 --- /dev/null +++ b/css/_colors-menu.scss @@ -0,0 +1,196 @@ + +#colors-menu { + right: 200px; + width: 48px; + display: flex; + justify-content: flex-start; + flex-direction: column; + list-style-type: none; + top: 48px; + bottom: 0; + padding: 0; + margin: 0; + background-color: $basecolor; + box-sizing: border-box; + position: fixed; + z-index: 1120; + + li { + width: 48px; + flex-basis: 48px; + + &:not(.noshrink) { + flex-grow: 1; + } + &.noshrink { + flex-grow: 0; + flex-shrink: 0; + } + } +} + + + +//added when the color is a duplicate of another +#duplicate-color-warning { + display: inline-block; + visibility: hidden; + margin-left: 5px; + opacity: 0.75; + cursor: help; + &:hover { + opacity: 0.9; + } +} + + + +//floating button to open jscolor picker +.color-edit-button { + position: absolute; + top: 3px; + left: 0px; + background: $basecolor; + padding: 6px 10px 3px 6px; + border-radius: 4px 0 0 4px; + cursor: pointer; + transition: left 0.25s; + z-index: -1; + box-shadow: 0px 15px 15px 0px rgba(0, 0, 0, 0.2); + path { + fill: $baseicon; + } + &:hover { + background: $basehover; + path { + fill: $basehovericon; + } + } //class added when jscolor is opened + &.hidden { + left: 0px !important; + } +} + + + +#colors-menu li { + position: relative; +} + + +#colors-menu li:hover .color-edit-button { + display: block; + left: -32px; +} + +#colors-menu li.selected:hover .color-edit-button { + display: block; + left: -35px; +} + + +#colors-menu li button { + height: 100%; + display: block; +} + + +.color-value { + display: none; +} + +#add-color-button { + background: $basecolor; + + path { + fill: #6f6873; + } +} + + +#colors-menu li { + button { + border: none; + width: 100%; + cursor: url('/pixel-editor/eyedropper.png'), auto; + } //white outline + &.selected button::before { + content: ""; + display: block; + position: absolute; + top: -3px; + left: -3px; + border: solid 3px #fff; + width: 100%; + height: 100%; + border-radius: 4px; + box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.15); + z-index: 10; + } //inner outline + &.selected button::after { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + border: solid 1px rgba(0, 0, 0, 0.15); + width: 100%; + height: 100%; + box-sizing: border-box; + } +} + +#colors-menu li.noshrink button { + cursor: pointer; +} + + +#add-color-button:hover { + background: $basehover; +} + + + +.jscolor-picker-bottom { + display: none; + position: absolute; + left: -4px; + right: -4px; + bottom: -7px; + color: $basetext; + span { + margin-left: 5px; + } + input { + width: 64px; + background: $indent; + color: $indenttext; + border-radius: 4px; + border: none; + margin: 0; + padding: 3px 12px; + margin-left: 5px; + } +} + + +.delete-color-button { + background: none; + padding: 0px; + border: none; + text-align: center; + cursor: pointer; + float: right; + path { + fill: $baseicon; + } + &:hover path { + fill: $basehovericon; + } + &.disabled { + cursor: not-allowed; + & path { + fill: lighten($basecolor, 10%) !important; + } + } +} \ No newline at end of file diff --git a/css/_compatibility.scss b/css/_compatibility.scss new file mode 100644 index 0000000..33b85c6 --- /dev/null +++ b/css/_compatibility.scss @@ -0,0 +1,59 @@ + +#compatibility-warning { + display: flex; + justify-content: center; + align-items: center; + visibility: hidden; + z-index: 3000; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(35, 32, 36, 0.92); + color: $basetext; + div { + position: relative; + width: 100%; + height: 100%; + + div { + width: 400px; + background-color: $basecolor; + padding: 20px; + width: 400px; + height: 200px; + + position: absolute; + top: 50%; + left: 50%; + + margin: -120px 0 0 -220px; + } + } + a { + color: $baselink; + border-bottom: dotted 1px transparent; + text-decoration: none; + &:hover { + border-bottom: dotted 1px $basetext; + } + } + button { + background: $basehover; + border: none; + border-radius: 4px; + color: $basehovertext; + padding: 10px 20px; + cursor: pointer; + margin: 0 auto; + display: block; + &:hover { + background: $baseselected; + } + } +} + +#cookies-disabled-warning { + display: none; + color: $basetextweak; + font-style: italic; +} \ No newline at end of file diff --git a/css/_general.scss b/css/_general.scss new file mode 100644 index 0000000..e4ad7a4 --- /dev/null +++ b/css/_general.scss @@ -0,0 +1,46 @@ + +body { + background: darken($basecolor, 6%); + font-family: 'Roboto', sans-serif; + margin: 0; + padding: 0; + color: #fff; + font-size: 14px; + width: 100%; + height: 100%; + overflow: hidden; + -moz-user-select: none; + /* Firefox */ + -ms-user-select: none; + /* Internet Explorer */ + -khtml-user-select: none; + /* KHTML browsers (e.g. Konqueror) */ + -webkit-user-select: none; + /* Chrome, Safari, and Opera */ + -webkit-touch-callout: none; + /* Disable Android and iOS callouts*/ +} + + + +//don't let svg handle click events, just send to parents +svg { + pointer-events: none; + path { + pointer-events: none; + } +} + +//remove blue outline in chrome +*:focus { + outline: 0 !important; +} + +.weak { + font-size: 0.8em; + color: $basetextweak; +} + +#data-holders, .preload { + display: none; +} \ No newline at end of file diff --git a/css/_help.scss b/css/_help.scss new file mode 100644 index 0000000..4959708 --- /dev/null +++ b/css/_help.scss @@ -0,0 +1,39 @@ + +#help { + max-height: 500px; + overflow-y:scroll; + + li { + margin-top:5px; + } + + // Fancy scrollbar + &::-webkit-scrollbar { + background: #232125; + width: 0.5em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 0.5em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } +} + + + +.keyboard-key { + background: lighten($basecolor, 20%); + box-shadow: 0 3px 0 2px lighten($basecolor, 12%); + padding: 0 4px; + border-radius: 2px; + margin: 6px; + display: inline-block; + color: #c0bfc1; +} diff --git a/css/_layers.scss b/css/_layers.scss new file mode 100644 index 0000000..5a505e4 --- /dev/null +++ b/css/_layers.scss @@ -0,0 +1,210 @@ + +#layer-properties-menu { + visibility: hidden; + margin: 0; + padding: 0; + top: 0; + right: 0; + width: 120px; + text-align: center; + + margin-right: 200px; + /*border:1px solid $basetext;*/ + list-style: none; + position: relative; + z-index: 1200; + list-style-type: none; + + background-color: $basecolor; + position: fixed; + overflow: visible; + + li button { + color: $basetext; + height: 100%; + padding: 10px; + background: none; + border: none; + cursor: pointer; + width: 100%; + } + + li button:hover { + background-color: $basehover; + } +} + +.preview-canvas { + image-rendering: optimizeSpeed; + /* Legal fallback */ + image-rendering: -moz-crisp-edges; + /* Firefox */ + image-rendering: -o-crisp-edges; + /* Opera */ + image-rendering: -webkit-optimize-contrast; + /* Safari */ + image-rendering: optimize-contrast; + /* CSS3 Proposed */ + image-rendering: crisp-edges; + /* CSS4 Proposed */ + image-rendering: pixelated; + /* CSS4 Proposed */ + -ms-interpolation-mode: nearest-neighbor; + /* IE8+ */ +} + +#layers-menu { + &::-webkit-scrollbar { + background: #232125; + width: 1em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 1em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } + scrollbar-color: #332f35 #232125; + scroll-behavior: smooth; + width:200px; + top: 48px; + bottom: 0; + right:0; + padding: 0; + margin: 0; + background-color: $basecolor; + box-sizing: border-box; + position: fixed; + z-index: 1120; + list-style-type: none; + overflow-y:scroll; + overflow-x:hidden; + #add-layer-button { + path { + fill: $baseicon; + } + svg { + position: relative; + margin-right: 10px; + } + position:relative; + justify-content: center; + display:flex; + align-items:center; + margin-top:2px; + font-size: 1.2em; + color: $basetext; + height: 100%; + width: 100%; + padding: 17px; + background: none; + border: none; + cursor: pointer; + } + + #add-layer-button:hover { + color: $basehovertext; + background-color: $basehover; + } +} + +.selected-layer { + ul.layer-buttons li.layer-button { + visibility: visible; + button svg path { + fill: $baseselectedicon; + } + + &:hover button svg path { + fill: $baseselectediconhover; + } + } + + color: $baseselectedtext; + background-color: $baseselected !important; +} + +.layerdragover { + margin-top: 5px; + border-top: 3px solid $basehovertext; +} + +.layers-menu-entry { + cursor: pointer; + margin-bottom: 2px; + font-size: 1em; + color: $basetext; + background-color: lighten($basecolor, 4%); + display: inline-block; + height: 50px; + width: 100%; + display: flex; + align-items: center; + + ul.layer-buttons { + top: 0; + left: 0; + margin: 0; + padding: 0; + box-sizing: border-box; + position: relative; + height: 100%; + list-style: none; + + path { + fill: $basehovericon; + } + li:hover { + path { + fill: $basehovericonhover; + } + } + + .layer-button { + visibility: hidden; + height: 50%; + } + } + + .lock-layer-button, + .hide-layer-button { + background: none; + border: none; + cursor: pointer; + height: 100%; + position: relative; + } + + canvas { + display: inline-block; + height: 50px; + width: 50px; + background-color: lightgrey; + left: 4px; + } + + p { + right: 0; + display: inline-block; + padding-left: 10px; + height: 18px; + overflow: hidden; + position: relative; + } + +} + +.layers-menu-entry:hover { + ul.layer-buttons li { + visibility: visible !important; + } + + color: $basehovertext; + background-color: $basehover; +} diff --git a/css/_main-menu.scss b/css/_main-menu.scss new file mode 100644 index 0000000..06453d8 --- /dev/null +++ b/css/_main-menu.scss @@ -0,0 +1,85 @@ + +#main-menu { + height: 48px; + left: 0; + right: 0; + list-style-type: none; + margin: 0; + padding: 0; + background-color: $basecolor; + position: fixed; + z-index: 1110; + overflow: visible; + &>li { + float: left; + height: 100%; + } + li button, + li a { + color: $basetext; + height: 100%; + padding: 17px; + background: none; + border: none; + cursor: pointer; + } + li.selected { + background-color: $basehover; + &>button { + color: $basehovertext; + } + ul { + display: block; + } + } + li ul { + display: none; + position: absolute; + top: 48px; + list-style-type: none; + padding: 0; + margin: 0; + background-color: $basehover; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5); + padding-bottom: 2px; + li { + width: 100%; + button, + a { + width: 100%; + text-align: left; + padding: 8px 32px 8px 16px; + font-size: 1em; + &:hover { + background-color: $baseselected; + color: $baseselectedtext; + } + } + a { + display: block; + text-decoration: none; + box-sizing: border-box; + } + } + } + .disabled { + color: #6f6e70 !important; + } +} + + + +/*app title*/ + +.logo { + color: lighten($basecolor, 20%); + text-transform: uppercase; + font-weight: bold; + padding: 17px 10px 0; + cursor: default; + box-sizing: border-box; +} + +#main-menu li.open, #main-menu li button:hover { + background: $basehover; +} diff --git a/css/_new-pixel.scss b/css/_new-pixel.scss new file mode 100644 index 0000000..cdbdbfe --- /dev/null +++ b/css/_new-pixel.scss @@ -0,0 +1,28 @@ + +#new-pixel-warning { + display: none; + text-align: center; + margin: 20px 0 0; + font-style: italic; +} + +.dimentions-x { + margin: -2px 7px; + path { + fill: $baseicon + } +} + + +#no-palette-button { + display: none; +} + + +#editor-mode-info { + font-style: italic; +} + +#editor-mode { + display: none; +} \ No newline at end of file diff --git a/css/_palette-editor.scss b/css/_palette-editor.scss new file mode 100644 index 0000000..8460b51 --- /dev/null +++ b/css/_palette-editor.scss @@ -0,0 +1,315 @@ + + + +/***********************COLOUR PICKER*****************************/ +#colour-picker { + background-color:$basecolor; + width:250px; + height:350px; + position:absolute; + display:inline-block; + + input[type=text] { + background-color:$basetext; + color:$basecolor; + box-shadow:none; + border:none; + } + + input[type=range] { + width: 100%; + margin: 2.2px 0; + background-color: transparent; + -webkit-appearance: none; + } + input[type=range]::-webkit-slider-runnable-track { + background: #484d4d; + border: 0; + width: 100%; + height: 25.6px; + cursor: pointer; + } + input[type=range]::-webkit-slider-thumb { + margin-top: -2.2px; + width: 18px; + height: 30px; + background: $basetext; + border: 0; + cursor: pointer; + -webkit-appearance: none; + } + input[type=range]::-moz-range-track { + background: #484d4d; + border: 0; + width: 100%; + height: 25.6px; + cursor: pointer; + } + input[type=range]::-moz-range-thumb { + width: 18px; + height: 30px; + background: $basetextweak; + border: 0; + cursor: pointer; + } + + /*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out + how to remove the vertical space around the range input in IE*/ + @supports (-ms-ime-align:auto) { + /* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */ + input[type=range].slider { + margin: 0; + /*Edge starts the margin from the thumb, not the track as other browsers do*/ + } + } +} + +#cp-modes { + margin: 0 0 0 0; + font-size:0; + height:40px; + float:left; + display:flex; + font-family: 'Roboto', sans-serif; + background-color:$basetextweak; + width:100%; + + button { + font-size:14px; + left:0; + right:0; + margin:0 0 0 0; + border: none; + border-radius: 0; + height:100%; + width:37x; + background-color:$basehover; + color:$basetext; + cursor:pointer; + } + + button:hover { + background-color:$baseicon; + color:$basetext; + } + + button.cp-selected-mode { + background-color:$baseicon; + color:$basetext; + } + + input { + width:60px; + } + + div { + background-color:yellow; + width:100%; + height:100%; + z-index:2; + position:relative; + } +} + +#sliders-container { + padding:10px; +} + +.cp-slider-entry { + width:100%; + height:30px; + display:flex; + align-items:center; + margin-top:2px; + position:relative; + + label { + width: 20px; + font-size:15px; + font-style: bold; + } + + input[type=text] { + text-align:center; + width: 30px; + overflow:visible; + margin-left:4px; + } +} + +.colour-picker-slider { + width:90%; +} + +#cp-minipicker { + width:100%; + height:100px; + position:relative; + margin: 0 0 0 0; + z-index: inherit 2000; + + input { + width:100%; + margin: none; + padding: none; + } + + .cp-colours-previews { + width:100%; + position:relative; + } + + .cp-colour-preview { + width:100%; + position:relative; + background-color:blue; + color:$basecolor; + float:left; + height:30px; + justify-content: center; + display:flex; + align-items: center; + font-size:12px; + } + + #cp-colour-picking-modes { + width:100%; + position:relative; + } + + button { + font-size:14px; + left:0; + right:0; + margin:0 0 0 0; + border: none; + border-radius: 0; + height:30px; + width:16.66666%; + float:left; + overflow:hidden; + background-color:$basehover; + color:$basetext; + cursor:pointer; + } + + button:hover { + background-color:$baseicon; + color:$basetext; + } + + button.cp-selected-mode { + background-color:$baseicon; + color:$basetext; + } +} + +#cp-canvas-container { + width:100%; + height:100%; + position:relative; +} + +#cp-spectrum { + width:100%; + height:100px; + position:absolute; + background-color: transparent; +} + +.cp-picker-icon{ + width:16px; + height:16px; + border-radius:100%; + position:absolute; + background-color:white; + z-index:2; + border:2px solid black; +} + + +/***************PALETTE BLOCK****************/ +div#palette-block { + z-index:1000; + position:relative; + resize: horizontal; + margin: 0 0 0 0; + width:600px; + height:400px; +} + +div#palette-container { + display:inline-block; + background-color: #232125; + position:absolute; + scrollbar-color: #332f35 #232125; + scroll-behavior: smooth; + left:300px; + width:300px; + height:320px; + overflow-y: scroll; + + &::-webkit-scrollbar { + background: #232125; + width: 0.5em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 0.5em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } +} + +ul#palette-list { + list-style:none; + margin: 0 0 0 0; + padding: 0 0 0 0; + position:relative; + display:inline-block; + + li { + float:left; + width:50px; + height:50px; + border:none; + + min-width:20px; + min-height:20px; + max-width:75px; + max-height:75px; + } +} + + +div#pb-options { + position:relative; + left:280px; + height:30px; + width:300px; + top:300px; + + button { + border-radius:none; + position:relative; + float:left; + width:50%; + height:100%; + text-align:center; + cursor: pointer; + font-size:16px; + background-color:$baseicon; + border:none; + } + + button:hover { + color: $basehovertext; + background-color: $basehover; + } +} \ No newline at end of file diff --git a/css/_popup-container.scss b/css/_popup-container.scss new file mode 100644 index 0000000..5191f9c --- /dev/null +++ b/css/_popup-container.scss @@ -0,0 +1,155 @@ + +#pop-up-container { + position: fixed; + z-index: 2000; + width: 100%; + height: 100%; + background-color: rgba(35, 32, 36, 0.75); + display: none; + color: $basetext; + cursor: default; + &>div { + background: $basecolor; + border-radius: 3px; + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5); + width: 400px; + padding: 20px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: none; + } + h1 { + margin: 0 0 10px; + color: lighten($basecolor, 100%); + text-transform: uppercase; + font-size: 1.5em; + } + h2 { + margin: 25px 0 10px; + color: lighten($basecolor, 70%); + text-transform: uppercase; + font-size: 1em; + } + a { + color: $baselink; + border-bottom: dotted 1px transparent; + text-decoration: none; + &:hover { + border-bottom: dotted 1px $basetext; + } + } + + .close-button { + width: 32px; + height: 32px; + position: absolute; + right: 0; + top: 0; + background: transparent; + border: none; + color: $baseicon; + font-weight: bold; + font-size: 1em; + cursor: pointer; + border-radius: 0 3px 0 0; + path { + fill: $baseicon; + } + &:hover { + background: $basehover; + path { + fill: $basehovericon; + } + } + } + + div.update { + input { + background: $indent; + border: none; + border-radius: 4px; + color: $indenttext; + padding: 10px 20px; + margin: 0; + width: 60px; + text-align: center; + } + } + /* + input { + background: $indent; + border: none; + border-radius: 4px; + color: $indenttext; + padding: 10px 20px; + margin: 0; + width: 60px; + text-align: center; + } + */ + + button.default { + background: $basehover; + border: none; + border-radius: 4px; + color: $basehovertext; + padding: 10px 20px; + cursor: pointer; + margin: 20px 0 0 10px; + &:hover { + background: $baseselected; + } + } + + .dropdown-button { + background: $basehover url('/pixel-editor/dropdown-arrow.png') right center no-repeat; + border: none; + border-radius: 4px; + color: $basehovertext; + padding: 5px 20px 5px 5px; + cursor: pointer; + margin: 0; + width: 200px; + text-align: left; + &:hover { + background: $baseselected url('/pixel-editor/dropdown-arrow-hover.png') right center no-repeat; + color: $baseselectedtext; + } + &.selected { + border-radius: 4px 4px 0 0; + } + } + + .dropdown-menu { + background: $basehover; + border: none; + color: $basehovertext; + padding: 0; + margin: -1px 0 0 0; + width: 200px; + text-align: left; + position: absolute; + border-radius: 0 0 4px 4px; + overflow: hidden; + display: none; + &.selected { + display: block; + } + + button { + background: $basehover; + border: none; + color: $basehovertext; + padding: 5px 20px 5px 5px; + cursor: pointer; + margin: 0; + width: 100%; + text-align: left; + &:hover { + background: $baseselected; + } + } + } +} \ No newline at end of file diff --git a/css/_resize-menus.scss b/css/_resize-menus.scss new file mode 100644 index 0000000..384939d --- /dev/null +++ b/css/_resize-menus.scss @@ -0,0 +1,220 @@ +#resize-canvas, +#resize-sprite { + display: flex; + position: relative; + flex-wrap: wrap; +} + +#pivot-menu { + position: relative; + display: inline-flex; + flex-wrap: wrap; + vertical-align: middle; + text-align: center; + width: 130px; + float: left; + + button { + margin-right: 10px; + margin-bottom: 10px; + position: relative; + width: 32px; + height: 32px; + background: $basehover; + border: none; + + path { + fill: $basehovericon; + } + + transition: background 100ms ease-in-out, + transform 100ms ease; + -webkit-appearance: none; + -moz-appearance: none; + } + + button:hover, + button:focus, + button.rc-selected-pivot { + cursor: pointer; + background-color: $baseicon; + + path { + fill: $basehovericonhover; + } + + border: 2px solid color(base, foreground); + } + + button:active { + transform: scale(0.95); + } +} + +#borders-menu, +#rc-size-menu, +#rs-size-menu, +#rs-percentage-menu { + display: flex; + position: relative; + flex-wrap: wrap; + width: 250px; + font-size: 15px; + left: 10px; + text-align: center; + + button { + background: $basehover; + border: none; + + color: $basehovericon; + transition: background 100ms ease-in-out, + transform 100ms ease; + -webkit-appearance: none; + -moz-appearance: none; + } + + button:hover, + button:focus { + cursor: pointer; + background-color: $baseicon; + color: $basehovericonhover; + border: 2px solid color(base, foreground); + } + + button:active { + transform: scale(0.95); + } + + input[type=number] { + position: relative; + margin-left: 10px; + height: 15px !important; + width: 40px !important; + padding: 8px !important; + } + + input[type=number]::-webkit-outer-spin-button, + input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + input[type=number] { + -moz-appearance: textfield; + } + + span { + padding-right: 10px; + float: left; + position: relative; + vertical-align: middle; + height: 40px; + width: 100px; + display: inline-flex; + align-items: center; + } +} + +#rs-percentage-menu { + width: 400px; + + span { + width: 150px; + } +} + +#rs-size-menu { + width: 400px; + + span { + width: 150px; + } +} + +#rs-percentage-menu, +#rs-size-menu { + justify-content: center; + + div { + float: none; + } +} + +#borders-menu { + width: 400px; + justify-content: center; + + div { + float: none; + width: 330px; + padding-left: 50px; + + span { + padding-right: 20px; + } + } +} + +#rs-ratio-div { + width: 400px; + justify-content: center; + padding-left: 20px; + + span { + width: 400px; + justify-content: center; + } + + select { + height: 30px; + background-color: $basehover; + color: $basehovericon; + border: none; + position: relative; + left: 10px; + + option { + background-color: $basehover; + color: $basehovericon; + padding: 5px; + } + + option:checked, + option:hover { + box-shadow: 0 0 10px 100px $basehovericon inset; + color: $basehovericonhover; + } + } +} + +#rs-keep-ratio { + background: color(button); + border: none; + font-size: 14px; + color: color(button, foreground); + padding: 10px 20px; + margin: 0 auto; + position: relative; + display: block; +} + +#resize-canvas-confirm, +#resize-sprite-confirm { + background: color(button); + border: none; + font-size: 18px; + border-radius: 4px; + color: color(button, foreground); + padding: 10px 20px; + cursor: pointer; + margin: 0 auto; + position: relative; + top: 10px; + display: block; + + &:hover { + background: color(button, background, hover); + } +} \ No newline at end of file diff --git a/css/_settings.scss b/css/_settings.scss new file mode 100644 index 0000000..cd0d334 --- /dev/null +++ b/css/_settings.scss @@ -0,0 +1,15 @@ +.settings-entry { + display: flex; + align-items: baseline; + margin-top:10px; + + label { + flex: 1; + } + input { + width: 90px !important; + display: block; + box-sizing: border-box; + float:right; + } +} \ No newline at end of file diff --git a/css/_shake.scss b/css/_shake.scss new file mode 100644 index 0000000..9be6c2d --- /dev/null +++ b/css/_shake.scss @@ -0,0 +1,25 @@ + +.shake { + animation: shake 0.82s cubic-bezier(.36, .07, .19, .97) both; + position: relative; +} + +@keyframes shake { + 10%, + 90% { + transform: translate3d(-1px, 0, 0); + } + 20%, + 80% { + transform: translate3d(1px, 0, 0); + } + 30%, + 50%, + 70% { + transform: translate3d(-2px, 0, 0); + } + 40%, + 60% { + transform: translate3d(2px, 0, 0); + } +} \ No newline at end of file diff --git a/css/_splash-page.scss b/css/_splash-page.scss new file mode 100644 index 0000000..46939e3 --- /dev/null +++ b/css/_splash-page.scss @@ -0,0 +1,320 @@ + +/********SPLASH PAGE*************/ +#splash { + width:100% !important; + height:100%!important; + + background-color: #232125 !important; + opacity: 1 !important; + + #splash-input { + width:74%; + height:100% !important; + color:$baselink; + + #splash-menu { + position:relative; + height:100%; + left:0; + top:0; + } + .splash-menu { + display: flex; + } + + #editor-logo { + font-weight:bold; + text-transform:uppercase; + font-size:20px; + height:35vh; + width:100%; + position:relative; + + background-image:url('https://cdn.discordapp.com/attachments/506277390050131978/795660870221955082/final.png'); + background-size:cover; + background-position:center; + background-repeat:no-repeat; + } + + #black { + width:100%; + height:100%; + position:relative; + background-color:rgba(0,0,0,0.2); + } + + #sp-coverdata { + padding:20px; + + p, a { + font-size:15px; + position:absolute; + text-transform:none; + right:20px; + } + + p { + top:0px; + } + + a { + font-size:17px; + bottom:20px; + text-decoration:underline; + } + + * { + filter: drop-shadow(3px 5px 2px rgba(0, 0, 0, 0.4)); + } + } + } + + #sp-quickstart-container { + width:70%; + float:right; + padding:40px; + display: flex; + flex-direction: column; + justify-content: space-between; + + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + + overflow-y: auto; + + &::-webkit-scrollbar { + background: #232125; + width: 0.5em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 0.5em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } + + .mode-switcher { + margin-top: 2em; + font-size: 1.2em; + color: $basetext; + a { + font-weight: bolder; + color: white; + margin-left: 0.5em; + } + + //show the correct info when the .advanced class is added + .advanced {display: none}; + &.advanced-mode { + .basic {display: none} + .advanced {display: inline} + } + } + } + + #sp-quickstart { + display:flex; + flex-wrap: wrap; + align-content: flex-start; + overflow-y: auto; + min-height: 0; + flex: 1 1 0; + + // Fancy scrollbar + &::-webkit-scrollbar { + background: #232125; + width: 0.5em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 0.5em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } + } + + #sp-quickstart-title { + font-size:27px; + text-transform: uppercase; + font-weight: bold; + } + + .sp-template { + display: flex; + align-items: center; + height: 5em; + min-width: 5em; + + text-transform: uppercase; + width:16%; + border-radius:5%; + margin-right:4%; + margin-top:4%; + background-color:$basecolor; + + font-size: 18px; + text-align:center; + font-weight: bold; + + &:hover { + cursor:pointer; + background-color:$baseselected; + } + + p { + span { + display:block; + font-size:14px !important; + margin: 0 0 0 0; + padding: 0 0 0 0; + } + width:100%; + + float:left; + position:relative; + } + } + + /* + .sp-template:before { + content:''; + float:left; + padding-top:100%; + }*/ + + #sp-newpixel { + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + display: inline-block; + width: 30% !important; + height:65vh; + padding:20px; + position:relative; + background-color:$basecolor; + + #palette-button-splash { + left:5%; + width:90%; + } + + .sp-np-entry { + width:100%; + text-align:center; + } + + input { + border:none; + background-color: #232125; + color:$basetext; + font-size:14px; + width:40px; + padding:7px; + text-align:center; + } + + #create-button { + font-size:18px; + width:150px; + margin-top:40px; + font-weight: bold; + } + + #sp-mode-palette { + text-align: center; + position: relative; + float:bottom; + font-size:16px; + font-weight: bold; + + div.button-menu { + border:2px solid $basetextweak; + border-radius:5px; + position:relative; + display:inline-block; + padding: 0 0 0 0; + text-align:left; + width:90%; + + div { + border:none; + padding:none; + margin:none; + background-color:transparent; + width:50%; + float:left; + text-align: center; + height:25px; + cursor:pointer; + z-index:1; + + p { + z-index:0; + -ms-transform: translateY(-60%); + transform: translateY(-60%); + } + } + + .sp-interface-selected { + background-color: $basetextweak; + } + } + } + } + + #splash-news { + box-sizing: border-box; + + width:26%; + height:100%; + background-color:#151516 !important; + float: right; + } + + #latest-update { + width:100%; + font-size:15px; + height:90%; + line-height: 1.5; + position:relative; + top:20px; + padding: 0 1.5em; + + overflow-y:scroll; + box-sizing: border-box; + + img { + width:100%; + } + + &::-webkit-scrollbar { + background: #232125; + width: 0.5em; + } + &::-webkit-scrollbar-track { + margin-top: -0.125em; + width: 0.5em; + } + &::-webkit-scrollbar-thumb { + background: #332f35; + border-radius: 0.25em; + border: solid 0.125em #232125; //same color as scrollbar back to fake padding + } + &::-webkit-scrollbar-corner { + background: #232125; + } + } +} \ No newline at end of file diff --git a/css/_tools-menu.scss b/css/_tools-menu.scss new file mode 100644 index 0000000..2f35aae --- /dev/null +++ b/css/_tools-menu.scss @@ -0,0 +1,116 @@ + +#tools-menu { + left: 0; + width: 64px; + list-style-type: none; + top: 48px; + bottom: 0; + padding: 0; + margin: 0; + background-color: $basecolor; + box-sizing: border-box; + position: fixed; + z-index: 1120; +} + + + +#tools-menu li { + position: relative; +} + + + +#tools-menu li button:first-child { + text-align: center; + border: none; + background: none; + width: 100%; + padding: 0; + cursor: pointer; + height: 64px; +} + +#tools-menu li button path { + fill: $baseicon; +} + +#tools-menu li:hover button:first-child path { + fill: $basehovericon; +} + + +#tools-menu li.selected { + background: $baseselected !important; +} + +#tools-menu li.selected button:first-child path { + fill: $baseselectedicon; +} + +#tools-menu li.selected.expanded { + padding-bottom: 10px; +} + + +.tools-menu-sub-button { + text-align: center; + border: none; + background: none; + cursor: pointer; + width: 50%; + height: 22px; + display: none; + line-height: 0; + overflow: hidden; + position: absolute; + bottom: 0; + + path { + fill: $baseselectedicon !important; + } + &:hover { + background: $baseselectedhover !important; + path { + fill: $baseselectediconhover !important; + } + } +} + +#tools-menu li button#pencil-bigger-button, +#tools-menu li button#zoom-in-button, +#tools-menu li button#eraser-bigger-button, +#tools-menu li button#rectangle-bigger-button, +#tools-menu li button#ellipse-bigger-button, +#tools-menu li button#line-bigger-button { + left: 0; +} + +#tools-menu li button#pencil-smaller-button, +#tools-menu li button#zoom-out-button, +#tools-menu li button#eraser-smaller-button, +#tools-menu li button#rectangle-smaller-button, +#tools-menu li button#ellipse-smaller-button, +#tools-menu li button#line-smaller-button { + right: 0; +} + +#tools-menu li.selected button#pencil-bigger-button, +#tools-menu li.selected button#pencil-smaller-button, +#tools-menu li.selected button#zoom-in-button, +#tools-menu li.selected button#zoom-out-button, +#tools-menu li.selected button#eraser-bigger-button, +#tools-menu li.selected button#eraser-smaller-button, +#tools-menu li.selected button#rectangle-bigger-button, +#tools-menu li.selected button#rectangle-smaller-button, +#tools-menu li.selected button#ellipse-bigger-button, +#tools-menu li.selected button#ellipse-smaller-button, +#tools-menu li.selected button#line-bigger-button, +#tools-menu li.selected button#line-smaller-button { + display: block; +} + + +#tools-menu li:hover { + background: $basehover; +} \ No newline at end of file diff --git a/css/_variables.scss b/css/_variables.scss new file mode 100644 index 0000000..6e4e18a --- /dev/null +++ b/css/_variables.scss @@ -0,0 +1,16 @@ +$basecolor: #332f35; //color(base) + $basetext: lighten($basecolor, 50%); //color(menu, foreground), color(base, foreground, text) + $basetextweak: lighten($basecolor, 30%); //color(menu, foreground), color(base, foreground, text) + $baselink: lighten($basecolor, 100%); //color(menu, foreground), color(base, foreground, text) + $baseicon: lighten($basecolor, 25%); //color(base, foreground) +$basehover: lighten($basecolor, 6%); //color(base, background, hover), color(button), color(menu), color(menu, background, hover) + $basehovertext: lighten($basecolor, 60%); //color(base, foreground, bold), color(menu, foreground, hover), color(button, foreground) + $basehovericon: lighten($basecolor, 40%); //color(base, foreground, hover) + $basehovericonhover: lighten($basecolor, 60%); //color(base, foreground, hover) +$baseselected: lighten($basecolor, 15%); //color(selectedTool, background), color(button, background, hover) + $baseselectedtext: lighten($basecolor, 80%); //color(base, foreground, bold) + $baseselectedicon: lighten($basecolor, 50%); //color(subbutton, foreground), color(selectedTool, foreground) + $baseselectediconhover: lighten($basecolor, 70%); //color(subbutton, foreground, hover) +$baseselectedhover: lighten($basecolor, 25%); //color(subbutton, background, hover) +$indent: darken($basecolor, 5%); //color(indent) + $indenttext: lighten($basecolor, 50%); //color(indent, foreground) \ No newline at end of file diff --git a/_ext/sass/_zindex.scss b/css/_zindex.scss similarity index 100% rename from _ext/sass/_zindex.scss rename to css/_zindex.scss diff --git a/css/pixel-editor.scss b/css/pixel-editor.scss index 305cccc..3f87961 100644 --- a/css/pixel-editor.scss +++ b/css/pixel-editor.scss @@ -1,1861 +1,17 @@ +@import 'variables'; +@import 'general'; @import 'zindex'; - -$basecolor: #332f35; //color(base) - $basetext: lighten($basecolor, 50%); //color(menu, foreground), color(base, foreground, text) - $basetextweak: lighten($basecolor, 30%); //color(menu, foreground), color(base, foreground, text) - $baselink: lighten($basecolor, 100%); //color(menu, foreground), color(base, foreground, text) - $baseicon: lighten($basecolor, 25%); //color(base, foreground) -$basehover: lighten($basecolor, 6%); //color(base, background, hover), color(button), color(menu), color(menu, background, hover) - $basehovertext: lighten($basecolor, 60%); //color(base, foreground, bold), color(menu, foreground, hover), color(button, foreground) - $basehovericon: lighten($basecolor, 40%); //color(base, foreground, hover) - $basehovericonhover: lighten($basecolor, 60%); //color(base, foreground, hover) -$baseselected: lighten($basecolor, 15%); //color(selectedTool, background), color(button, background, hover) - $baseselectedtext: lighten($basecolor, 80%); //color(base, foreground, bold) - $baseselectedicon: lighten($basecolor, 50%); //color(subbutton, foreground), color(selectedTool, foreground) - $baseselectediconhover: lighten($basecolor, 70%); //color(subbutton, foreground, hover) -$baseselectedhover: lighten($basecolor, 25%); //color(subbutton, background, hover) -$indent: darken($basecolor, 5%); //color(indent) - $indenttext: lighten($basecolor, 50%); //color(indent, foreground) - - -body { - background: darken($basecolor, 6%); - font-family: 'Roboto', sans-serif; - margin: 0; - padding: 0; - color: #fff; - font-size: 14px; - width: 100%; - height: 100%; - overflow: hidden; - -moz-user-select: none; - /* Firefox */ - -ms-user-select: none; - /* Internet Explorer */ - -khtml-user-select: none; - /* KHTML browsers (e.g. Konqueror) */ - -webkit-user-select: none; - /* Chrome, Safari, and Opera */ - -webkit-touch-callout: none; - /* Disable Android and iOS callouts*/ -} - -#help { - max-height: 500px; - overflow-y:scroll; - - li { - margin-top:5px; - } - - // Fancy scrollbar - &::-webkit-scrollbar { - background: #232125; - width: 0.5em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 0.5em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } -} - -#layer-properties-menu { - visibility: hidden; - margin: 0; - padding: 0; - top: 0; - right: 0; - width: 120px; - text-align: center; - - margin-right: 200px; - /*border:1px solid $basetext;*/ - list-style: none; - position: relative; - z-index: 1200; - list-style-type: none; - - background-color: $basecolor; - position: fixed; - overflow: visible; - - li button { - color: $basetext; - height: 100%; - padding: 10px; - background: none; - border: none; - cursor: pointer; - width: 100%; - } - - li button:hover { - background-color: $basehover; - } -} - -.preview-canvas { - image-rendering: optimizeSpeed; - /* Legal fallback */ - image-rendering: -moz-crisp-edges; - /* Firefox */ - image-rendering: -o-crisp-edges; - /* Opera */ - image-rendering: -webkit-optimize-contrast; - /* Safari */ - image-rendering: optimize-contrast; - /* CSS3 Proposed */ - image-rendering: crisp-edges; - /* CSS4 Proposed */ - image-rendering: pixelated; - /* CSS4 Proposed */ - -ms-interpolation-mode: nearest-neighbor; - /* IE8+ */ -} - -#layers-menu { - &::-webkit-scrollbar { - background: #232125; - width: 1em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 1em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } - scrollbar-color: #332f35 #232125; - scroll-behavior: smooth; - width:200px; - top: 48px; - bottom: 0; - right:0; - padding: 0; - margin: 0; - background-color: $basecolor; - box-sizing: border-box; - position: fixed; - z-index: 1120; - list-style-type: none; - overflow-y:scroll; - overflow-x:hidden; - #add-layer-button { - path { - fill: $baseicon; - } - svg { - position: relative; - margin-right: 10px; - } - position:relative; - justify-content: center; - display:flex; - align-items:center; - margin-top:2px; - font-size: 1.2em; - color: $basetext; - height: 100%; - width: 100%; - padding: 17px; - background: none; - border: none; - cursor: pointer; - } - - #add-layer-button:hover { - color: $basehovertext; - background-color: $basehover; - } -} - -.selected-layer { - ul.layer-buttons li.layer-button { - visibility: visible; - button svg path { - fill: $baseselectedicon; - } - - &:hover button svg path { - fill: $baseselectediconhover; - } - } - - color: $baseselectedtext; - background-color: $baseselected !important; -} - -.layerdragover { - margin-top: 5px; - border-top: 3px solid $basehovertext; -} - -.layers-menu-entry { - cursor: pointer; - margin-bottom: 2px; - font-size: 1em; - color: $basetext; - background-color: lighten($basecolor, 4%); - display: inline-block; - height: 50px; - width: 100%; - display: flex; - align-items: center; - - ul.layer-buttons { - top: 0; - left: 0; - margin: 0; - padding: 0; - box-sizing: border-box; - position: relative; - height: 100%; - list-style: none; - - path { - fill: $basehovericon; - } - li:hover { - path { - fill: $basehovericonhover; - } - } - - .layer-button { - visibility: hidden; - height: 50%; - } - } - - .lock-layer-button, - .hide-layer-button { - background: none; - border: none; - cursor: pointer; - height: 100%; - position: relative; - } - - canvas { - display: inline-block; - height: 50px; - width: 50px; - background-color: lightgrey; - left: 4px; - } - - p { - right: 0; - display: inline-block; - padding-left: 10px; - height: 18px; - overflow: hidden; - position: relative; - } - -} - -.layers-menu-entry:hover { - ul.layer-buttons li { - visibility: visible !important; - } - - color: $basehovertext; - background-color: $basehover; -} - -//don't let svg handle click events, just send to parents -svg { - pointer-events: none; - path { - pointer-events: none; - } -} - -//remove blue outline in chrome -*:focus { - outline: 0 !important; -} - -.weak { - font-size: 0.8em; - color: $basetextweak; -} - -.drawingCanvas { - cursor: url('/pixel-art-where-to-start/pencil-tool-cursor.png'); - - border: solid 1px #fff; - image-rendering: optimizeSpeed; - /* Legal fallback */ - image-rendering: -moz-crisp-edges; - /* Firefox */ - image-rendering: -o-crisp-edges; - /* Opera */ - image-rendering: -webkit-optimize-contrast; - /* Safari */ - image-rendering: optimize-contrast; - /* CSS3 Proposed */ - image-rendering: crisp-edges; - /* CSS4 Proposed */ - image-rendering: pixelated; - /* CSS4 Proposed */ - -ms-interpolation-mode: nearest-neighbor; - /* IE8+ */ - width: 400px; - height: 400px; - position: fixed; - display: none; - box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.64); - background-color: transparent; -} - -#checkerboard { - z-index: 1; -} - -#pixel-canvas { - z-index: 3; - background: transparent; -} - -#pixel-grid { - z-index: 5000; - background: transparent; -} - -#tmp-canvas { - z-index: 5; - background: transparent; -} - - -#vfx-canvas { - z-index: -5000; - background: transparent; -} - -#eyedropper-preview { - position: absolute; - width: 45px; - height: 45px; - border-radius: 30px; - border: solid 10px red; - z-index: 1200; - display: none; - box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.25), inset 0 0 6px 0 rgba(0, 0, 0, 0.2); - pointer-events: none; - &.dark { - box-shadow: 0 0 8px 0 rgba(255, 255, 255, 0.5), inset 0 0 6px 0 rgba(255, 255, 255, 0.5); - } -} - -#brush-preview { - position: absolute; - border: solid 1px #fff; - z-index: 1200; - box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.5), inset 0 0 2px 0 rgba(0, 0, 0, 0.5); - pointer-events: none; - left: -500px; - &.dark { - border: solid 1px #000; - box-shadow: 0 0 3px 0 rgba(255, 255, 255, 0.8), inset 0 0 3px 0 rgba(255, 255, 255, 0.8); - } -} - -#canvas-view { - bottom: 0px; - left: 64px; - right: 48px; - top: 48px; - cursor: default; - position: fixed; - display: block; -} - -#canvas-view-shadow { - box-shadow: inset 0px 0px 4px 0px rgba(0, 0, 0, 0.4); - position: fixed; - bottom: 0px; - left: 64px; - right: 48px; - top: 48px; - display: block; - pointer-events: none; -} - -#main-menu { - height: 48px; - left: 0; - right: 0; - list-style-type: none; - margin: 0; - padding: 0; - background-color: $basecolor; - position: fixed; - z-index: 1110; - overflow: visible; - &>li { - float: left; - height: 100%; - } - li button, - li a { - color: $basetext; - height: 100%; - padding: 17px; - background: none; - border: none; - cursor: pointer; - } - li.selected { - background-color: $basehover; - &>button { - color: $basehovertext; - } - ul { - display: block; - } - } - li ul { - display: none; - position: absolute; - top: 48px; - list-style-type: none; - padding: 0; - margin: 0; - background-color: $basehover; - box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.5); - padding-bottom: 2px; - li { - width: 100%; - button, - a { - width: 100%; - text-align: left; - padding: 8px 32px 8px 16px; - font-size: 1em; - &:hover { - background-color: $baseselected; - color: $baseselectedtext; - } - } - a { - display: block; - text-decoration: none; - box-sizing: border-box; - } - } - } - .disabled { - color: #6f6e70 !important; - } -} - - -/*app title*/ - -.logo { - color: lighten($basecolor, 20%); - text-transform: uppercase; - font-weight: bold; - padding: 17px 10px 0; - cursor: default; - box-sizing: border-box; -} - -#data-holders { - display: none; -} - -#tools-menu, -#colors-menu { - list-style-type: none; - top: 48px; - bottom: 0; - padding: 0; - margin: 0; - background-color: $basecolor; - box-sizing: border-box; - position: fixed; - z-index: 1120; -} - -#tools-menu { - left: 0; - width: 64px; -} - -#colors-menu { - right: 200px; - width: 48px; - display: flex; - justify-content: flex-start; - flex-direction: column; - li { - width: 48px; - flex-basis: 48px; - - &:not(.noshrink) { - flex-grow: 1; - } - &.noshrink { - flex-grow: 0; - flex-shrink: 0; - } - } -} - -//added when the color is a duplicate of another -#duplicate-color-warning { - display: inline-block; - visibility: hidden; - margin-left: 5px; - opacity: 0.75; - cursor: help; - &:hover { - opacity: 0.9; - } -} - -.shake { - animation: shake 0.82s cubic-bezier(.36, .07, .19, .97) both; - position: relative; -} - -@keyframes shake { - 10%, - 90% { - transform: translate3d(-1px, 0, 0); - } - 20%, - 80% { - transform: translate3d(1px, 0, 0); - } - 30%, - 50%, - 70% { - transform: translate3d(-2px, 0, 0); - } - 40%, - 60% { - transform: translate3d(2px, 0, 0); - } -} - -//floating button to open jscolor picker -.color-edit-button { - position: absolute; - top: 3px; - left: 0px; - background: $basecolor; - padding: 6px 10px 3px 6px; - border-radius: 4px 0 0 4px; - cursor: pointer; - transition: left 0.25s; - z-index: -1; - box-shadow: 0px 15px 15px 0px rgba(0, 0, 0, 0.2); - path { - fill: $baseicon; - } - &:hover { - background: $basehover; - path { - fill: $basehovericon; - } - } //class added when jscolor is opened - &.hidden { - left: 0px !important; - } -} - -#colors-menu li:hover .color-edit-button { - display: block; - left: -32px; -} - -#colors-menu li.selected:hover .color-edit-button { - display: block; - left: -35px; -} - -#tools-menu li, -#colors-menu li { - position: relative; -} - -#colors-menu li button { - height: 100%; - display: block; -} - -.color-value { - display: none; -} - -#add-color-button { - background: $basecolor; - - path { - fill: #6f6873; - } -} - -#tools-menu li button:first-child { - text-align: center; - border: none; - background: none; - width: 100%; - padding: 0; - cursor: pointer; - height: 64px; -} - -#tools-menu li button path { - fill: $baseicon; -} - -#tools-menu li:hover button:first-child path { - fill: $basehovericon; -} - -#colors-menu li { - button { - border: none; - width: 100%; - cursor: url('/pixel-editor/eyedropper.png'), auto; - } //white outline - &.selected button::before { - content: ""; - display: block; - position: absolute; - top: -3px; - left: -3px; - border: solid 3px #fff; - width: 100%; - height: 100%; - border-radius: 4px; - box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.15); - z-index: 10; - } //inner outline - &.selected button::after { - content: ""; - display: block; - position: absolute; - top: 0; - left: 0; - border: solid 1px rgba(0, 0, 0, 0.15); - width: 100%; - height: 100%; - box-sizing: border-box; - } -} - -#colors-menu li.noshrink button { - cursor: pointer; -} - -#tools-menu li.selected { - background: $baseselected !important; -} - -#tools-menu li.selected button:first-child path { - fill: $baseselectedicon; -} - -#tools-menu li.selected.expanded { - padding-bottom: 10px; -} - -#tools-menu li:hover, -#main-menu li button:hover, -#add-color-button:hover, -#main-menu li.open { - background: $basehover; -} - -.tools-menu-sub-button { - text-align: center; - border: none; - background: none; - cursor: pointer; - width: 50%; - height: 22px; - display: none; - line-height: 0; - overflow: hidden; - position: absolute; - bottom: 0; - - path { - fill: $baseselectedicon !important; - } - &:hover { - background: $baseselectedhover !important; - path { - fill: $baseselectediconhover !important; - } - } -} - -#tools-menu li button#pencil-bigger-button, -#tools-menu li button#zoom-in-button, -#tools-menu li button#eraser-bigger-button, -#tools-menu li button#rectangle-bigger-button, -#tools-menu li button#ellipse-bigger-button, -#tools-menu li button#line-bigger-button { - left: 0; -} - -#tools-menu li button#pencil-smaller-button, -#tools-menu li button#zoom-out-button, -#tools-menu li button#eraser-smaller-button, -#tools-menu li button#rectangle-smaller-button, -#tools-menu li button#ellipse-smaller-button, -#tools-menu li button#line-smaller-button { - right: 0; -} - -#tools-menu li.selected button#pencil-bigger-button, -#tools-menu li.selected button#pencil-smaller-button, -#tools-menu li.selected button#zoom-in-button, -#tools-menu li.selected button#zoom-out-button, -#tools-menu li.selected button#eraser-bigger-button, -#tools-menu li.selected button#eraser-smaller-button, -#tools-menu li.selected button#rectangle-bigger-button, -#tools-menu li.selected button#rectangle-smaller-button, -#tools-menu li.selected button#ellipse-bigger-button, -#tools-menu li.selected button#ellipse-smaller-button, -#tools-menu li.selected button#line-bigger-button, -#tools-menu li.selected button#line-smaller-button { - display: block; -} - -#pop-up-container { - position: fixed; - z-index: 2000; - width: 100%; - height: 100%; - background-color: rgba(35, 32, 36, 0.75); - display: none; - color: $basetext; - cursor: default; - &>div { - background: $basecolor; - border-radius: 3px; - box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5); - width: 400px; - padding: 20px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - display: none; - } - h1 { - margin: 0 0 10px; - color: lighten($basecolor, 100%); - text-transform: uppercase; - font-size: 1.5em; - } - h2 { - margin: 25px 0 10px; - color: lighten($basecolor, 70%); - text-transform: uppercase; - font-size: 1em; - } - a { - color: $baselink; - border-bottom: dotted 1px transparent; - text-decoration: none; - &:hover { - border-bottom: dotted 1px $basetext; - } - } - - .close-button { - width: 32px; - height: 32px; - position: absolute; - right: 0; - top: 0; - background: transparent; - border: none; - color: $baseicon; - font-weight: bold; - font-size: 1em; - cursor: pointer; - border-radius: 0 3px 0 0; - path { - fill: $baseicon; - } - &:hover { - background: $basehover; - path { - fill: $basehovericon; - } - } - } - - div.update { - input { - background: $indent; - border: none; - border-radius: 4px; - color: $indenttext; - padding: 10px 20px; - margin: 0; - width: 60px; - text-align: center; - } - } - /* - input { - background: $indent; - border: none; - border-radius: 4px; - color: $indenttext; - padding: 10px 20px; - margin: 0; - width: 60px; - text-align: center; - } - */ - - button.default { - background: $basehover; - border: none; - border-radius: 4px; - color: $basehovertext; - padding: 10px 20px; - cursor: pointer; - margin: 20px 0 0 10px; - &:hover { - background: $baseselected; - } - } - - .dropdown-button { - background: $basehover url('/pixel-editor/dropdown-arrow.png') right center no-repeat; - border: none; - border-radius: 4px; - color: $basehovertext; - padding: 5px 20px 5px 5px; - cursor: pointer; - margin: 0; - width: 200px; - text-align: left; - &:hover { - background: $baseselected url('/pixel-editor/dropdown-arrow-hover.png') right center no-repeat; - color: $baseselectedtext; - } - &.selected { - border-radius: 4px 4px 0 0; - } - } - - .dropdown-menu { - background: $basehover; - border: none; - color: $basehovertext; - padding: 0; - margin: -1px 0 0 0; - width: 200px; - text-align: left; - position: absolute; - border-radius: 0 0 4px 4px; - overflow: hidden; - display: none; - &.selected { - display: block; - } - - button { - background: $basehover; - border: none; - color: $basehovertext; - padding: 5px 20px 5px 5px; - cursor: pointer; - margin: 0; - width: 100%; - text-align: left; - &:hover { - background: $baseselected; - } - } - } -} - -.keyboard-key { - background: lighten($basecolor, 20%); - box-shadow: 0 3px 0 2px lighten($basecolor, 12%); - padding: 0 4px; - border-radius: 2px; - margin: 6px; - display: inline-block; - color: #c0bfc1; -} - -.settings-entry { - display: flex; - align-items: baseline; - margin-top:10px; - - label { - flex: 1; - } - input { - width: 90px !important; - display: block; - box-sizing: border-box; - float:right; - } -} - -.preload { - display: none; -} - -#new-pixel-warning { - display: none; - text-align: center; - margin: 20px 0 0; - font-style: italic; -} - -.dimentions-x { - margin: -2px 7px; - path { - fill: $baseicon - } -} - -.jscolor-picker-bottom { - display: none; - position: absolute; - left: -4px; - right: -4px; - bottom: -7px; - color: $basetext; - span { - margin-left: 5px; - } - input { - width: 64px; - background: $indent; - color: $indenttext; - border-radius: 4px; - border: none; - margin: 0; - padding: 3px 12px; - margin-left: 5px; - } -} - -.delete-color-button { - background: none; - padding: 0px; - border: none; - text-align: center; - cursor: pointer; - float: right; - path { - fill: $baseicon; - } - &:hover path { - fill: $basehovericon; - } - &.disabled { - cursor: not-allowed; - & path { - fill: lighten($basecolor, 10%) !important; - } - } -} - -#no-palette-button { - display: none; -} - -#cookies-disabled-warning { - display: none; - color: $basetextweak; - font-style: italic; -} - -#editor-mode-info { - font-style: italic; -} - -#editor-mode { - display: none; -} - -#resize-canvas, #resize-sprite { - display:flex; - position:relative; - flex-wrap:wrap; -} - -#pivot-menu { - position: relative; - display:inline-flex; - flex-wrap:wrap; - vertical-align:middle; - text-align:center; - width:130px; - float:left; - - button { - margin-right:10px; - margin-bottom:10px; - position:relative; - width:32px; - height:32px; - background:$basehover; - border:none; - - path { - fill:$basehovericon; - } - transition: background 100ms ease-in-out, - transform 100ms ease; - -webkit-appearance: none; - -moz-appearance: none; - } - - button:hover, - button:focus, - button.rc-selected-pivot { - cursor:pointer; - background-color: $baseicon; - path { - fill:$basehovericonhover; - } - border: 2px solid color(base, foreground); - } - button:active { - transform: scale(0.95); - } -} - -#borders-menu, #rc-size-menu, #rs-size-menu, #rs-percentage-menu { - display:flex; - position:relative; - flex-wrap: wrap; - width:250px; - font-size:15px; - left:10px; - text-align:center; - - button { - background:$basehover; - border:none; - - color: $basehovericon; - transition: background 100ms ease-in-out, - transform 100ms ease; - -webkit-appearance: none; - -moz-appearance: none; - } - - button:hover, - button:focus { - cursor:pointer; - background-color: $baseicon; - color:$basehovericonhover; - border: 2px solid color(base, foreground); - } - button:active { - transform: scale(0.95); - } - - input[type=number] { - position:relative; - margin-left:10px; - height:15px !important; - width:40px !important; - padding:8px !important; - } - - input[type=number]::-webkit-outer-spin-button, - input[type=number]::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; - } - /* Firefox */ - input[type=number] { - -moz-appearance: textfield; - } - - span { - padding-right:10px; - float:left; - position:relative; - vertical-align:middle; - height:40px; - width:100px; - display: inline-flex; - align-items: center; - } -} - -#rs-percentage-menu { - width: 400px; - span { - width:150px; - } -} - -#rs-size-menu { - width: 400px; - span { - width:150px; - } -} - -#rs-percentage-menu, #rs-size-menu { - justify-content: center; - - div { - float: none; - } -} - -#borders-menu { - width:400px; - justify-content: center; - - div { - float: none; - width: 330px; - padding-left:50px; - - span { - padding-right:20px; - } - } -} - -#rs-ratio-div { - width:400px; - justify-content: center; - padding-left:20px; - - span { - width:400px; - justify-content: center; - } - - select { - height:30px; - background-color: $basehover; - color: $basehovericon; - border:none; - position:relative; - left:10px; - - option { - background-color: $basehover; - color:$basehovericon; - padding:5px; - } - - option:checked, option:hover { - box-shadow: 0 0 10px 100px $basehovericon inset; - color: $basehovericonhover; - } - } -} - -#rs-keep-ratio { - background: color(button); - border: none; - font-size:14px; - color: color(button, foreground); - padding: 10px 20px; - margin: 0 auto; - position:relative; - display: block; -} - -#resize-canvas-confirm, #resize-sprite-confirm { - background: color(button); - border: none; - font-size:18px; - border-radius: 4px; - color: color(button, foreground); - padding: 10px 20px; - cursor: pointer; - margin: 0 auto; - position:relative; - top:10px; - display: block; - &:hover { - background: color(button, background, hover); - } -} - -#compatibility-warning { - display: flex; - justify-content: center; - align-items: center; - visibility: hidden; - z-index: 3000; - position: absolute; - width: 100%; - height: 100%; - background-color: rgba(35, 32, 36, 0.92); - color: $basetext; - div { - position: relative; - width: 100%; - height: 100%; - - div { - width: 400px; - background-color: $basecolor; - padding: 20px; - width: 400px; - height: 200px; - - position: absolute; - top: 50%; - left: 50%; - - margin: -120px 0 0 -220px; - } - } - a { - color: $baselink; - border-bottom: dotted 1px transparent; - text-decoration: none; - &:hover { - border-bottom: dotted 1px $basetext; - } - } - button { - background: $basehover; - border: none; - border-radius: 4px; - color: $basehovertext; - padding: 10px 20px; - cursor: pointer; - margin: 0 auto; - display: block; - &:hover { - background: $baseselected; - } - } -} -/***********************COLOUR PICKER*****************************/ -#colour-picker { - background-color:$basecolor; - width:250px; - height:350px; - position:absolute; - display:inline-block; - - input[type=text] { - background-color:$basetext; - color:$basecolor; - box-shadow:none; - border:none; - } - - input[type=range] { - width: 100%; - margin: 2.2px 0; - background-color: transparent; - -webkit-appearance: none; - } - input[type=range]::-webkit-slider-runnable-track { - background: #484d4d; - border: 0; - width: 100%; - height: 25.6px; - cursor: pointer; - } - input[type=range]::-webkit-slider-thumb { - margin-top: -2.2px; - width: 18px; - height: 30px; - background: $basetext; - border: 0; - cursor: pointer; - -webkit-appearance: none; - } - input[type=range]::-moz-range-track { - background: #484d4d; - border: 0; - width: 100%; - height: 25.6px; - cursor: pointer; - } - input[type=range]::-moz-range-thumb { - width: 18px; - height: 30px; - background: $basetextweak; - border: 0; - cursor: pointer; - } - - /*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out - how to remove the vertical space around the range input in IE*/ - @supports (-ms-ime-align:auto) { - /* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */ - input[type=range].slider { - margin: 0; - /*Edge starts the margin from the thumb, not the track as other browsers do*/ - } - } -} - -#cp-modes { - margin: 0 0 0 0; - font-size:0; - height:40px; - float:left; - display:flex; - font-family: 'Roboto', sans-serif; - background-color:$basetextweak; - width:100%; - - button { - font-size:14px; - left:0; - right:0; - margin:0 0 0 0; - border: none; - border-radius: 0; - height:100%; - width:37x; - background-color:$basehover; - color:$basetext; - cursor:pointer; - } - - button:hover { - background-color:$baseicon; - color:$basetext; - } - - button.cp-selected-mode { - background-color:$baseicon; - color:$basetext; - } - - input { - width:60px; - } - - div { - background-color:yellow; - width:100%; - height:100%; - z-index:2; - position:relative; - } -} - -#sliders-container { - padding:10px; -} - -.cp-slider-entry { - width:100%; - height:30px; - display:flex; - align-items:center; - margin-top:2px; - position:relative; - - label { - width: 20px; - font-size:15px; - font-style: bold; - } - - input[type=text] { - text-align:center; - width: 30px; - overflow:visible; - margin-left:4px; - } -} - -.colour-picker-slider { - width:90%; -} - -#cp-minipicker { - width:100%; - height:100px; - position:relative; - margin: 0 0 0 0; - z-index: inherit 2000; - - input { - width:100%; - margin: none; - padding: none; - } - - .cp-colours-previews { - width:100%; - position:relative; - } - - .cp-colour-preview { - width:100%; - position:relative; - background-color:blue; - color:$basecolor; - float:left; - height:30px; - justify-content: center; - display:flex; - align-items: center; - font-size:12px; - } - - #cp-colour-picking-modes { - width:100%; - position:relative; - } - - button { - font-size:14px; - left:0; - right:0; - margin:0 0 0 0; - border: none; - border-radius: 0; - height:30px; - width:16.66666%; - float:left; - overflow:hidden; - background-color:$basehover; - color:$basetext; - cursor:pointer; - } - - button:hover { - background-color:$baseicon; - color:$basetext; - } - - button.cp-selected-mode { - background-color:$baseicon; - color:$basetext; - } -} - -#cp-canvas-container { - width:100%; - height:100%; - position:relative; -} - -#cp-spectrum { - width:100%; - height:100px; - position:absolute; - background-color: transparent; -} - -.cp-picker-icon{ - width:16px; - height:16px; - border-radius:100%; - position:absolute; - background-color:white; - z-index:2; - border:2px solid black; -} - - -/***************PALETTE BLOCK****************/ -div#palette-block { - z-index:1000; - position:relative; - resize: horizontal; - margin: 0 0 0 0; - width:600px; - height:400px; -} - -div#palette-container { - display:inline-block; - background-color: #232125; - position:absolute; - scrollbar-color: #332f35 #232125; - scroll-behavior: smooth; - left:300px; - width:300px; - height:320px; - overflow-y: scroll; - - &::-webkit-scrollbar { - background: #232125; - width: 0.5em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 0.5em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } -} - -ul#palette-list { - list-style:none; - margin: 0 0 0 0; - padding: 0 0 0 0; - position:relative; - display:inline-block; - - li { - float:left; - width:50px; - height:50px; - border:none; - - min-width:20px; - min-height:20px; - max-width:75px; - max-height:75px; - } -} - - -div#pb-options { - position:relative; - left:280px; - height:30px; - width:300px; - top:300px; - - button { - border-radius:none; - position:relative; - float:left; - width:50%; - height:100%; - text-align:center; - cursor: pointer; - font-size:16px; - background-color:$baseicon; - border:none; - } - - button:hover { - color: $basehovertext; - background-color: $basehover; - } -} - -/********SPLASH PAGE*************/ -#splash { - width:100% !important; - height:100%!important; - - background-color: #232125 !important; - opacity: 1 !important; - - #splash-input { - width:74%; - height:100% !important; - color:$baselink; - - #splash-menu { - position:relative; - height:100%; - left:0; - top:0; - } - - #editor-logo { - font-weight:bold; - text-transform:uppercase; - font-size:20px; - height:35vh; - width:100%; - position:relative; - - background-image:url('https://cdn.discordapp.com/attachments/506277390050131978/795660870221955082/final.png'); - background-size:cover; - background-position:center; - background-repeat:no-repeat; - } - - #black { - width:100%; - height:100%; - position:relative; - background-color:rgba(0,0,0,0.2); - } - - #sp-coverdata { - padding:20px; - - p, a { - font-size:15px; - position:absolute; - text-transform:none; - right:20px; - } - - p { - top:0px; - } - - a { - font-size:17px; - bottom:20px; - text-decoration:underline; - } - } - } - - #sp-quickstart-container { - height:100%; - max-height: 500px; - width:70%; - float:right; - padding:40px; - - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; /* Opera/IE 8+ */ - - overflow-y: scroll; - &::-webkit-scrollbar { - background: #232125; - width: 0.5em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 0.5em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } - } - - #sp-quickstart { - display:flex; - flex-direction: row; - flex-wrap: wrap; - height:100%; - - // Fancy scrollbar - &::-webkit-scrollbar { - background: #232125; - width: 0.5em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 0.5em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } - } - - #sp-quickstart-title { - font-size:27px; - text-transform: uppercase; - font-weight: bold; - } - - .sp-template { - display: flex; - align-items: center; - text-transform: uppercase; - width:16%; - border-radius:5%; - margin-right:4%; - margin-top:4%; - background-color:$basecolor; - - font-size: 18px; - text-align:center; - font-weight: bold; - - &:hover { - cursor:pointer; - background-color:$baseselected; - } - - p { - span { - display:block; - font-size:14px !important; - margin: 0 0 0 0; - padding: 0 0 0 0; - } - width:100%; - - float:left; - position:relative; - } - } - - .sp-template:before { - content:''; - float:left; - padding-top:100%; - } - - #sp-newpixel { - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; /* Opera/IE 8+ */ - display: inline-block; - width: 30% !important; - height:65vh; - padding:20px; - position:relative; - background-color:$basecolor; - - #palette-button-splash { - left:5%; - width:90%; - } - - .sp-np-entry { - width:100%; - text-align:center; - } - - input { - border:none; - background-color: #232125; - color:$basetext; - font-size:14px; - width:40px; - padding:7px; - text-align:center; - } - - #create-button { - font-size:18px; - width:150px; - margin-top:40px; - font-weight: bold; - } - - #sp-mode-palette { - text-align: center; - position: relative; - float:bottom; - font-size:16px; - font-weight: bold; - - div.button-menu { - border:2px solid $basetextweak; - border-radius:5px; - position:relative; - display:inline-block; - padding: 0 0 0 0; - text-align:left; - width:90%; - - div { - border:none; - padding:none; - margin:none; - background-color:transparent; - width:50%; - float:left; - text-align: center; - height:25px; - cursor:pointer; - z-index:1; - - p { - z-index:0; - -ms-transform: translateY(-60%); - transform: translateY(-60%); - } - } - - .sp-interface-selected { - background-color: $basetextweak; - } - } - } - } - - #splash-news { - box-sizing: border-box; - padding-left:20px; - width:26%; - height:100%; - background-color:#151516 !important; - float: right; - } - - #latest-update { - width:100%; - font-size:15px; - height:90%; - line-height: 1.5; - position:relative; - top:20px; - - overflow-y:scroll; - box-sizing: border-box; - - img { - width:100%; - } - - &::-webkit-scrollbar { - background: #232125; - width: 0.5em; - } - &::-webkit-scrollbar-track { - margin-top: -0.125em; - width: 0.5em; - } - &::-webkit-scrollbar-thumb { - background: #332f35; - border-radius: 0.25em; - border: solid 0.125em #232125; //same color as scrollbar back to fake padding - } - &::-webkit-scrollbar-corner { - background: #232125; - } - } -} \ No newline at end of file +@import 'shake'; +@import 'help'; +@import 'layers'; +@import 'canvas'; +@import 'main-menu'; +@import 'tools-menu'; +@import 'colors-menu'; +@import 'popup-container'; +@import 'settings'; +@import 'new-pixel'; +@import 'compatibility'; +@import 'resize-menus'; +@import 'palette-editor'; +@import 'splash-page'; \ No newline at end of file diff --git a/debug.log b/debug.log deleted file mode 100644 index 3b8e60d..0000000 --- a/debug.log +++ /dev/null @@ -1 +0,0 @@ -[0114/110029.536:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) diff --git a/helpers/svg.js b/helpers/svg.js new file mode 100644 index 0000000..1035433 --- /dev/null +++ b/helpers/svg.js @@ -0,0 +1,41 @@ +const fs = require("fs"); +const handlebars = require("handlebars"); +const ltx = require("ltx"); +const resolve = require("resolve"); + +const path = "../svg/"; +const nameToModule = {}; +const cache = {}; + +module.exports = function (name, opts) { + name = path + name; + + const mod = + nameToModule[name] || + (nameToModule[name] = resolve.sync(name, { + extensions: [".svg"], + })); + + const content = + cache[name] || (cache[name] = fs.readFileSync(mod, "utf-8")); + + const svg = parse(content); + + Object.assign(svg.attrs, opts.hash); + + return new handlebars.SafeString(svg.root().toString()); +}; + +module.exports.cache = cache; + +function parse(xml, mod) { + const svg = ltx.parse(xml); + if (svg.name != "svg") { + throw new TypeError("Input must be an SVG"); + } + + delete svg.attrs.xmlns; + delete svg.attrs["xmlns:xlink"]; + + return svg; +} diff --git a/js/_createButton.js b/js/_createButton.js index 23b807f..bda39d5 100644 --- a/js/_createButton.js +++ b/js/_createButton.js @@ -9,7 +9,7 @@ function create(isSplash) { var height = getValue('size-height' + splashPostfix); // If I'm creating from the splash screen, I use the splashMode variable - var mode = isSplash ? splashMode : getValue('editor-mode'); + var mode = isSplash ? splashMode : pixelEditorMode; newPixel(width, height, mode); @@ -29,9 +29,7 @@ function create(isSplash) { //reset new form setValue('size-width', 64); setValue('size-height', 64); - setValue("editor-mode", 'Advanced') - setText('editor-mode-button', 'Choose a mode...'); setText('palette-button', 'Choose a palette...'); setText('preset-button', 'Choose a preset...'); } @@ -43,10 +41,9 @@ on('click', 'create-button', function (){ // Getting the values of the form var width = getValue('size-width'); var height = getValue('size-height'); - var mode = getValue("editor-mode"); // Creating a new pixel with those properties - newPixel(width, height, mode); + newPixel(width, height); document.getElementById('new-pixel-warning').style.display = 'block'; //get selected palette name @@ -61,9 +58,7 @@ on('click', 'create-button', function (){ //reset new form setValue('size-width', 64); setValue('size-height', 64); - setValue("editor-mode", 'Advanced') - setText('editor-mode-button', 'Choose a mode...'); setText('palette-button', 'Choose a palette...'); setText('preset-button', 'Choose a preset...'); }); @@ -95,9 +90,7 @@ on('click', 'create-button-splash', function (){ //reset new pixel form setValue('size-width-splash', 64); setValue('size-height-splash', 64); - setValue("editor-mode", 'Advanced') - setText('editor-mode-button', 'Choose a mode...'); setText('palette-button', 'Choose a palette...'); setText('preset-button', 'Choose a preset...'); }); diff --git a/js/_editorMode.js b/js/_editorMode.js index ccb8dcf..9d98cf2 100644 --- a/js/_editorMode.js +++ b/js/_editorMode.js @@ -7,30 +7,13 @@ let modes = { } } -let infoBox = document.getElementById('editor-mode-info'); -let currentSplashButton = document.getElementById("sp-mode-palette").children[0].children[1]; - -function splashMode(mouseEvent, mode) { - if (currentSplashButton == undefined) { - currentSplashButton = mouseEvent.target.parentElement; - } - - if (mode !== pixelEditorMode) { - // Remove selected class to old button - currentSplashButton.classList.remove("sp-interface-selected"); - // Add selected class to new button - mouseEvent.target.parentElement.classList.add("sp-interface-selected"); - - // Setting the new mode - pixelEditorMode = mode; - } - - // Setting the new selected button - currentSplashButton = mouseEvent.target.parentElement; -} +on('click', 'switch-editor-mode-splash', function (e) { + console.log('switching mode') + switchMode(); +}); function switchMode(mustConfirm = true) { - + console.log('switching mode', 'current:',pixelEditorMode) //switch to advanced mode if (pixelEditorMode == 'Basic') { // Switch to advanced ez pez lemon squez @@ -41,7 +24,13 @@ function switchMode(mustConfirm = true) { // Hide the palette menu document.getElementById('colors-menu').style.right = '200px' + //change splash text + document.querySelector('#sp-quickstart-container .mode-switcher').classList.add('advanced-mode'); + pixelEditorMode = 'Advanced'; + + //turn pixel grid off + togglePixelGrid('off'); } //switch to basic mode else { @@ -71,57 +60,15 @@ function switchMode(mustConfirm = true) { // Move the palette menu document.getElementById('colors-menu').style.right = '0px'; + + //change splash text + document.querySelector('#sp-quickstart-container .mode-switcher').classList.remove('advanced-mode'); + pixelEditorMode = 'Basic'; + togglePixelGrid('on'); } } on('click', 'switch-mode-button', function (e) { switchMode(); }); - -// Makes the menu open -on('click', 'editor-mode-button', function (e){ - //open or close the preset menu - toggle('editor-mode-button'); - toggle('editor-mode-menu'); - - //close the palette menu - deselect('palette-button'); - deselect('palette-menu'); - - //close the preset menu - deselect('preset-button'); - deselect('preset-menu'); - - //stop the click from propogating to the parent element - e.stopPropagation(); -}); - -//populate preset list in new pixel menu -Object.keys(modes).forEach(function(modeName,index) { - var editorModeMenu = document.getElementById('editor-mode-menu'); - - //create button - var button = document.createElement('button'); - button.appendChild(document.createTextNode(modeName)); - - //insert new element - editorModeMenu.appendChild(button); - - //add click event listener - on('click', button, function() { - - //change mode on new pixel - setValue('editor-mode', modeName); - // Change description - infoBox.innerHTML = modes[modeName].description; - - //hide the dropdown menu - deselect('editor-mode-menu'); - deselect('editor-mode-button'); - - //set the text of the dropdown to the newly selected mode - setText('editor-mode-button', modeName); - }); - -}); \ No newline at end of file diff --git a/js/_logs.js b/js/_logs.js deleted file mode 100644 index 30ee743..0000000 --- a/js/_logs.js +++ /dev/null @@ -1,15 +0,0 @@ -var rawFile = new XMLHttpRequest(); -rawFile.open("GET", '/pixel-editor/latestLog.html', false); -rawFile.onreadystatechange = function () -{ - if(rawFile.readyState === 4) - { - if(rawFile.status === 200 || rawFile.status == 0) - { - var allText = rawFile.responseText; - - document.getElementById("latest-update").innerHTML = allText; - } - } -} -rawFile.send(null); \ No newline at end of file diff --git a/js/_newPixel.js b/js/_newPixel.js index b9406ae..326dbd2 100644 --- a/js/_newPixel.js +++ b/js/_newPixel.js @@ -103,10 +103,10 @@ function newPixel (width, height, editorMode, fileContent = null) { // If the user selected a palette and isn't opening a file, I load the selected palette if (selectedPalette != 'Choose a palette...' && fileContent == null) { - + console.log('HELO', selectedPalette, palettes[selectedPalette]) //if this palette isnt the one specified in the url, then reset the url if (!palettes[selectedPalette].specified) - history.pushState(null, null, '/pixel-editor/app'); + history.pushState(null, null, '/pixel-editor'); //fill the palette with specified colours createColorPalette(palettes[selectedPalette].colors,true); @@ -114,7 +114,7 @@ function newPixel (width, height, editorMode, fileContent = null) { // Otherwise, I just generate 2 semirandom colours else if (fileContent == null) { //this wasn't a specified palette, so reset the url - history.pushState(null, null, '/pixel-editor/app'); + history.pushState(null, null, '/pixel-editor'); //generate default colors var fg = hslToRgb(Math.floor(Math.random()*255), 230,70); diff --git a/js/_onLoad.js b/js/_onLoad.js index 48f83b9..90d8367 100644 --- a/js/_onLoad.js +++ b/js/_onLoad.js @@ -1,17 +1,68 @@ + + + + //when the page is done loading, you can get ready to start window.onload = function () { featureToggles.onLoad(); currentTool.updateCursor(); + + //check if there are any url parameters + if (window.location.pathname.replace('/pixel-editor/','').length <= 1) { + console.log('no url parameters were found'); - //if the user specified dimensions - if (specifiedDimentions) { - //create a new pixel - newPixel(getValue('size-width'), getValue('size-height'), getValue('editor-mode')); - } else { - //otherwise show the new pixel dialog - showDialogue('splash', false); - } + //show splash screen + showDialogue('splash', false); + } + //url parameters were specified + else { + console.log('loading preset from url parameters', window.location.pathname); + + let args = window.location.pathname.split('/'); + let paletteSlug = args[2]; + let dimentions = args[3]; + + //fetch palette via lospec palette API + fetch('https://lospec.com/palette-list/'+paletteSlug+'.json') + .then(response => response.json()) + .then(data => { + //palette loaded successfully + console.log('loaded palette', data); + palettes[paletteSlug] = data; + palettes[paletteSlug].specified = true; + + //refresh list of palettes + document.getElementById('palette-menu-splash').refresh(); + + //if the dimentions were specified + if (dimentions && dimentions.length >= 3 && dimentions.includes('x')) { + let width = dimentions.split('x')[0]; + let height = dimentions.split('x')[1]; + + console.log('dimentions were specified',width,'x',height) + + //firstPixel = false; + + //create new document + newPixel(width, height); + } + + //dimentions were not specified -- show splash screen with palette preselected + else { + //show splash + showDialogue('new-pixel', false); + } + + }) + //error fetching url (either palette doesn't exist, or lospec is down) + .catch((error) => { + console.warn('failed to load palette "'+paletteSlug+'"', error); + + //proceed to splash screen + showDialogue('splash', false); + }); + } }; \ No newline at end of file diff --git a/js/_palettes.js b/js/_palettes.js index bcf69c0..4f789f2 100644 --- a/js/_palettes.js +++ b/js/_palettes.js @@ -1,3 +1,59 @@ + +palettes = { + "Endesga 32": { + colors: "be4a2f,d77643,ead4aa,e4a672,b86f50,733e39,3e2731,a22633,e43b44,f77622,feae34,fee761,63c74d,3e8948,265c42,193c3e,124e89,0099db,2ce8f5,ffffff,c0cbdc,8b9bb4,5a6988,3a4466,262b44,181425,ff0044,68386c,b55088,f6757a,e8b796,c28569".split( + "," + ), + }, + + "Resurrect 64": { + colors: "2e222f,3e3546,625565,966c6c,ab947a,694f62,7f708a,9babb2,c7dcd0,ffffff,6e2727,b33831,ea4f36,f57d4a,ae2334,e83b3b,fb6b1d,f79617,f9c22b,7a3045,9e4539,cd683d,e6904e,fbb954,4c3e24,676633,a2a947,d5e04b,fbff86,165a4c,239063,1ebc73,91db69,cddf6c,313638,374e4a,547e64,92a984,b2ba90,0b5e65,0b8a8f,0eaf9b,30e1b9,8ff8e2,323353,484a77,4d65b4,4d9be6,8fd3ff,45293f,6b3e75,905ea9,a884f3,eaaded,753c54,a24b6f,cf657f,ed8099,831c5d,c32454,f04f78,f68181,fca790,fdcbb0".split( + "," + ), + }, + + "AAP-64": { + colors: "060608,141013,3b1725,73172d,b4202a,df3e23,fa6a0a,f9a31b,ffd541,fffc40,d6f264,9cdb43,59c135,14a02e,1a7a3e,24523b,122020,143464,285cc4,249fde,20d6c7,a6fcdb,ffffff,fef3c0,fad6b8,f5a097,e86a73,bc4a9b,793a80,403353,242234,221c1a,322b28,71413b,bb7547,dba463,f4d29c,dae0ea,b3b9d1,8b93af,6d758d,4a5462,333941,422433,5b3138,8e5252,ba756a,e9b5a3,e3e6ff,b9bffb,849be4,588dbe,477d85,23674e,328464,5daf8d,92dcba,cdf7e2,e4d2aa,c7b08b,a08662,796755,5a4e44,423934".split( + "," + ), + }, + + "Zughy 32": { + colors: "472d3c,5e3643,7a444a,a05b53,bf7958,eea160,f4cca1,b6d53c,71aa34,397b44,3c5956,302c2e,5a5353,7d7071,a0938e,cfc6b8,dff6f5,8aebf1,28ccdf,3978a8,394778,39314b,564064,8e478c,cd6093,ffaeb6,f4b41b,f47e1b,e6482e,a93b3b,827094,4f546b".split( + "," + ), + }, + + Journey: { + colors: "050914,110524,3b063a,691749,9c3247,d46453,f5a15d,ffcf8e,ff7a7d,ff417d,d61a88,94007a,42004e,220029,100726,25082c,3d1132,73263d,bd4035,ed7b39,ffb84a,fff540,c6d831,77b02a,429058,2c645e,153c4a,052137,0e0421,0c0b42,032769,144491,488bd4,78d7ff,b0fff1,faffff,c7d4e1,928fb8,5b537d,392946,24142c,0e0f2c,132243,1a466b,10908e,28c074,3dff6e,f8ffb8,f0c297,cf968c,8f5765,52294b,0f022e,35003b,64004c,9b0e3e,d41e3c,ed4c40,ff9757,d4662f,9c341a,691b22,450c28,2d002e".split( + "," + ), + }, + + Vinik24: { + colors: "000000,6f6776,9a9a97,c5ccb8,8b5580,c38890,a593a5,666092,9a4f50,c28d75,7ca1c0,416aa3,8d6268,be955c,68aca9,387080,6e6962,93a167,6eaa78,557064,9d9f7f,7e9e99,5d6872,433455".split( + "," + ), + }, + + "Sweetie 16": { + colors: "1a1c2c,5d275d,b13e53,ef7d57,ffcd75,a7f070,38b764,257179,29366f,3b5dc9,41a6f6,73eff7,f4f4f4,94b0c2,566c86,333c57".split( + "," + ), + }, + + Lospec500: { + colors: "10121c,2c1e31,6b2643,ac2847,ec273f,94493a,de5d3a,e98537,f3a833,4d3533,6e4c30,a26d3f,ce9248,dab163,e8d282,f7f3b7,1e4044,006554,26854c,5ab552,9de64e,008b8b,62a477,a6cb96,d3eed3,3e3b65,3859b3,3388de,36c5f4,6dead6,5e5b8c,8c78a5,b0a7b8,deceed,9a4d76,c878af,cc99ff,fa6e79,ffa2ac,ffd1d5,f6e8e0,ffffff".split( + "," + ), + }, +}; +palettes["Commodore 64"] = {"name":"Commodore 64","author":"","colors":["000000","626262","898989","adadad","ffffff","9f4e44","cb7e75","6d5412","a1683c","c9d487","9ae29b","5cab5e","6abfc6","887ecb","50459b","a057a3"]}; +palettes["PICO-8"] = {"name":"PICO-8","author":"","colors":["000000","1D2B53","7E2553","008751","AB5236","5F574F","C2C3C7","FFF1E8","FF004D","FFA300","FFEC27","00E436","29ADFF","83769C","FF77A8","FFCCAA"]}; +palettes["Gameboy Color"] = {"name":"Nintendo Gameboy (Black Zero)","author":"","colors":["2e463d","385d49","577b46","7e8416"]}; + + + //populate palettes list in new pixel menu (() => { const palettesMenu = document.getElementById('palette-menu'); @@ -9,43 +65,50 @@ const loadPaletteButton = document.getElementById('load-palette-button'); const loadPaletteButtonSplash = document.getElementById('load-palette-button-splash'); - Object.keys(palettes).forEach((paletteName,) => { + splashPalettes.refresh = function () { + splashPalettes.innerHTML = ''; + palettesMenu.innerHTML = ''; - const button = document.createElement('button'); - button.appendChild(document.createTextNode(paletteName)); + Object.keys(palettes).forEach((paletteName,) => { - //if the palette was specified by the user, change the dropdown to it - if (palettes[paletteName].specified) { - Util.setText('palette-button', paletteName); - Util.setText('palette-button-splash', paletteName) - //Show empty palette option - noPaletteButton.style.display = 'block'; - } + const button = document.createElement('button'); + button.appendChild(document.createTextNode(paletteName)); - const buttonEvent = () => { - //hide the dropdown menu - Util.deselect('palette-menu'); - Util.deselect('palette-button'); - Util.deselect('palette-menu-splash'); - Util.deselect('palette-button-splash'); + //if the palette was specified by the user, change the dropdown to it + if (palettes[paletteName].specified) { + Util.setText('palette-button', paletteName); + Util.setText('palette-button-splash', paletteName) + //Show empty palette option + noPaletteButton.style.display = 'block'; + } - //show empty palette option - noPaletteButton.style.display = 'block'; + const buttonEvent = () => { + //hide the dropdown menu + Util.deselect('palette-menu'); + Util.deselect('palette-button'); + Util.deselect('palette-menu-splash'); + Util.deselect('palette-button-splash'); - //set the text of the dropdown to the newly selected preset - Util.setText('palette-button', paletteName); - Util.setText('palette-button-splash', paletteName); - } + //show empty palette option + noPaletteButton.style.display = 'block'; - // Making a copy for the splash page too - const copyButton = button.cloneNode(true); - copyButton.addEventListener('click', buttonEvent); - button.addEventListener('click', buttonEvent); + //set the text of the dropdown to the newly selected preset + Util.setText('palette-button', paletteName); + Util.setText('palette-button-splash', paletteName); + } - // Appending it to the splash palette menu - splashPalettes.appendChild(copyButton); - palettesMenu.appendChild(button); - }); + // Making a copy for the splash page too + const copyButton = button.cloneNode(true); + copyButton.addEventListener('click', buttonEvent); + button.addEventListener('click', buttonEvent); + + // Appending it to the splash palette menu + splashPalettes.appendChild(copyButton); + palettesMenu.appendChild(button); + }); + } + + splashPalettes.refresh(); const loadPaletteButtonEvent = () => { @@ -78,7 +141,6 @@ }) newPixelElement.addEventListener('click', () => { - Util.deselect('editor-mode-menu'); Util.deselect('preset-button'); Util.deselect('preset-menu'); Util.deselect('palette-button'); diff --git a/js/_pixelGrid.js b/js/_pixelGrid.js index 0ce55ce..2385434 100644 --- a/js/_pixelGrid.js +++ b/js/_pixelGrid.js @@ -1,9 +1,9 @@ // Start colour of the pixel grid (can be changed in the preferences) -let pixelGridColor = "#0000FF"; +let pixelGridColor = "#000000"; // Distance between one line and another in HTML pixels let lineDistance = 12; -// The grid is not visible at the beginning -let pixelGridVisible = false; +// The grid is visible by default +let pixelGridVisible = true; // Saving the canvas containing the pixel grid pixelGridCanvas = document.getElementById("pixel-grid"); @@ -11,12 +11,15 @@ pixelGridCanvas = document.getElementById("pixel-grid"); * (triggered by the show pixel grid button in the top menu) * */ -function togglePixelGrid(event) { +function togglePixelGrid(newState) { + console.log('toggling pixel grid', newState) // Getting the button because I have to change its text let button = document.getElementById("toggle-pixelgrid-button"); - // Toggling the state - pixelGridVisible = !pixelGridVisible; + //Set the state based on the passed newState variable, otherwise just toggle it + if (newState == 'on') pixelGridVisible = true; + else if (newState == 'off') pixelGridVisible = false; + else pixelGridVisible = !pixelGridVisible; // If it was visible, I hide it if (pixelGridVisible) { diff --git a/js/_settings.js b/js/_settings.js index 3c39602..1c92a98 100644 --- a/js/_settings.js +++ b/js/_settings.js @@ -15,7 +15,7 @@ if(!settingsFromCookie) { enableEyedropperPreview: true, //unused - performance numberOfHistoryStates: 20, maxColorsOnImportedImage: 128, - pixelGridColour: '#0000FF' + pixelGridColour: '#000000' }; } else{ diff --git a/js/_splashPage.js b/js/_splashPage.js index 96bd305..278e70d 100644 --- a/js/_splashPage.js +++ b/js/_splashPage.js @@ -18,6 +18,6 @@ let coverImage = document.getElementById('editor-logo'); let authorLink = coverImage.getElementsByTagName('a')[0]; let chosenImage = images[Math.round(Math.random() * (images.length - 1))]; -coverImage.style.backgroundImage = 'url("/pixel-editor/' + chosenImage.path + '.png")'; +coverImage.style.backgroundImage = 'url("' + chosenImage.path + '.png")'; authorLink.setAttribute('href', chosenImage.link); authorLink.innerHTML = 'Art by ' + chosenImage.author; \ No newline at end of file diff --git a/js/_variables.js b/js/_variables.js index 4c85ab9..41bf84b 100644 --- a/js/_variables.js +++ b/js/_variables.js @@ -3,9 +3,9 @@ var canvasSize; var zoom = 7; var dragging = false; var lastMouseClickPos = [0,0]; -var dialogueOpen = false; +var dialogueOpen = true; var documentCreated = false; -var pixelEditorMode = "Advanced"; +var pixelEditorMode = "Basic"; //common elements var brushPreview = document.getElementById("brush-preview"); diff --git a/js/checkCompatibilityPixelEditor.js b/js/checkCompatibilityPixelEditor.js new file mode 100644 index 0000000..b440d25 --- /dev/null +++ b/js/checkCompatibilityPixelEditor.js @@ -0,0 +1,15 @@ +function closeCompatibilityWarning() { + document.getElementById("compatibility-warning").style.visibility = "hidden"; +} + +//check browser/version +if ( + (bowser.firefox && bowser.version >= 28) || + (bowser.chrome && bowser.version >= 29) || + (!bowser.mobile && !bowser.tablet) +) + console.log("compatibility check passed"); + + +//show warning +else document.getElementById("compatibility-warning").style.visibility = "visible"; diff --git a/_ext/scripts/libraries/cookies.js b/js/lib/cookies.js similarity index 100% rename from _ext/scripts/libraries/cookies.js rename to js/lib/cookies.js diff --git a/js/sortable.js b/js/lib/sortable.js similarity index 100% rename from js/sortable.js rename to js/lib/sortable.js diff --git a/js/pixel-editor.js b/js/pixel-editor.js index 80dc6cf..79351e4 100644 --- a/js/pixel-editor.js +++ b/js/pixel-editor.js @@ -1,18 +1,18 @@ /**utilities**/ -//=include utilities/on.js -//=include utilities/onChildren.js -//=include utilities/onClick.js -//=include utilities/onClickChildren.js -//=include utilities/select.js -//=include utilities/getSetText.js -//=include utilities/getSetValue.js -//=include utilities/hexToRgb.js -//=include utilities/rgbToHex.js -//=include utilities/rgbToHsl.js -//=include utilities/hslToRgb.js -//=include libraries/cookies.js +//=include util/on.js +//=include util/onChildren.js +//=include util/onClick.js +//=include util/onClickChildren.js +//=include util/select.js +//=include util/getSetText.js +//=include util/getSetValue.js +//=include util/hexToRgb.js +//=include util/rgbToHex.js +//=include util/rgbToHsl.js +//=include util/hslToRgb.js +//=include lib/cookies.js //=include _pixelEditorUtility.js -//=include sortable.js +//=include lib/sortable.js //=include _algorithms.js //=include Util.js @@ -34,7 +34,7 @@ //=include _changeZoom.js //=include ColorModule.js //=include _dialogue.js -//=include _featuresLog.js +//!=include _featuresLog.js //=include _drawLine.js //=include _getCursorPosition.js //=include _fill.js @@ -51,7 +51,6 @@ //=include _colorPicker.js //=include _paletteBlock.js //=include _splashPage.js -//=include _logs.js /**load file**/ //=include _loadImage.js diff --git a/js/util/ajax.js b/js/util/ajax.js new file mode 100644 index 0000000..ae8b77e --- /dev/null +++ b/js/util/ajax.js @@ -0,0 +1,79 @@ +//GET: ajax(String url, Function success [,timeout]) +//POST: ajax(String url, Object postData, Function success [,timeout]) +Util.ajax = function (url, arg2, arg3, arg4) { + if (typeof arg2 == 'function') { + var success = arg2; + var timeout = arg3 || 10000; + } + else { + var postData = arg2; + var success = arg3; + var timeout = arg4 || 10000; + } + + var start = new Date(); + console.log('AJAX - STARTING REQUEST', url, '(' + timeout + ')'); + + //start new request + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + var result; + + //try to parse as json + try { + result = JSON.parse(this.response); + console.log('AJAX - COMPLETE ('+(new Date()-start)+'ms) - json:', result); + } + catch (e) { + result = this.response; + console.log('AJAX - COMPLETE ('+(new Date()-start)+'ms) - string:', this.response, e); + } + + //return result + success(result); + + xhr = null; + } + else if (this.readyState == 4) { + console.log('ajax failed', this.readyState, this.status); + success({ error: 'failure' }); + } + }; + + xhr.ontimeout = function(e) { + console.log('ajax request timed out') + success({ error: 'timeout' }); + }; + + if (postData) { + //post request + console.log('post data: ', postData instanceof FormData, postData); + + //the the input isn't already formdata, convert it to form data + if (!(postData instanceof FormData)) { + console.log('converting to form data'); + + var formData = new FormData(); + + for (var key in postData) { + formData.append(key, postData[key]); + } + + postData = formData; + } + + //send to server + xhr.open("POST", url, true); + xhr.timeout = timeout; + xhr.send(postData); + } + else { + //get request + xhr.open("GET", url, true); + xhr.timeout = timeout; + xhr.send(); + } + + return xhr; +} \ No newline at end of file diff --git a/_ext/scripts/utilities/getSetText.js b/js/util/getSetText.js similarity index 100% rename from _ext/scripts/utilities/getSetText.js rename to js/util/getSetText.js diff --git a/_ext/scripts/utilities/getSetValue.js b/js/util/getSetValue.js similarity index 100% rename from _ext/scripts/utilities/getSetValue.js rename to js/util/getSetValue.js diff --git a/_ext/scripts/utilities/hexToRgb.js b/js/util/hexToRgb.js similarity index 100% rename from _ext/scripts/utilities/hexToRgb.js rename to js/util/hexToRgb.js diff --git a/_ext/scripts/utilities/hslToRgb.js b/js/util/hslToRgb.js similarity index 100% rename from _ext/scripts/utilities/hslToRgb.js rename to js/util/hslToRgb.js diff --git a/_ext/scripts/utilities/on.js b/js/util/on.js similarity index 100% rename from _ext/scripts/utilities/on.js rename to js/util/on.js diff --git a/_ext/scripts/utilities/onChildren.js b/js/util/onChildren.js similarity index 100% rename from _ext/scripts/utilities/onChildren.js rename to js/util/onChildren.js diff --git a/_ext/scripts/utilities/onClick.js b/js/util/onClick.js similarity index 100% rename from _ext/scripts/utilities/onClick.js rename to js/util/onClick.js diff --git a/_ext/scripts/utilities/onClickChildren.js b/js/util/onClickChildren.js similarity index 100% rename from _ext/scripts/utilities/onClickChildren.js rename to js/util/onClickChildren.js diff --git a/_ext/scripts/utilities/rgbToHex.js b/js/util/rgbToHex.js similarity index 100% rename from _ext/scripts/utilities/rgbToHex.js rename to js/util/rgbToHex.js diff --git a/_ext/scripts/utilities/rgbToHsl.js b/js/util/rgbToHsl.js similarity index 100% rename from _ext/scripts/utilities/rgbToHsl.js rename to js/util/rgbToHsl.js diff --git a/_ext/scripts/utilities/select.js b/js/util/select.js similarity index 100% rename from _ext/scripts/utilities/select.js rename to js/util/select.js diff --git a/package-lock.json b/package-lock.json index d9a02a2..a756d4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3135,8 +3135,9 @@ } }, "handlebars-helper-svg": { - "version": "git+ssh://git@bitbucket.org/skeddles/npm-handlebars-helper-svg-lospec-open-source.git#2feeec5000aecce96ba2f714ec540880537ae208", - "from": "handlebars-helper-svg@git+https://bitbucket.org/skeddles/npm-handlebars-helper-svg-lospec-open-source.git", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/handlebars-helper-svg/-/handlebars-helper-svg-2.0.2.tgz", + "integrity": "sha512-uCLLeD3F+6pcTczOz2DH6OtFkJ2lKixWUT0nrZimME36BdCwHheAwL5tfyYpsUUUB/yle/ZRK0/Cv7Def/d5XA==", "requires": { "ltx": "^2.3.0", "resolve": "^1.1.7" @@ -3855,9 +3856,9 @@ } }, "ltx": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.9.2.tgz", - "integrity": "sha512-llB7HflFhlfsYYT1SAe80elCBO5C20ryLdwPB/A/BZk38hhVeZztDlWQ9uTyvKNPX4aK6sA+JfS1f/mfzp5cxA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.10.0.tgz", + "integrity": "sha512-RB4zR6Mrp/0wTNS9WxMvpgfht/7u/8QAC9DpPD19opL/4OASPa28uoliFqeDkLUU8pQ4aeAfATBZmz1aSAHkMw==", "requires": { "inherits": "^2.0.4" } diff --git a/package.json b/package.json index cd8a3bc..0e2ad92 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "gulp-include": "^2.3.1", "gulp-rename": "^2.0.0", "gulp-sass": "^4.0.2", - "handlebars-helper-svg": "git+https://bitbucket.org/skeddles/npm-handlebars-helper-svg-lospec-open-source.git", + "handlebars-helper-svg": "^2.0.2", "nodemon": "^2.0.7", "open": "^8.0.6", "open-cli": "^6.0.1", diff --git a/server.js b/server.js index e6167ff..3bb5c2e 100644 --- a/server.js +++ b/server.js @@ -6,30 +6,10 @@ const app = express(); const BUILDDIR = process.argv[2] || './build'; const PORT = process.argv[3] || 3000; -//ROUTE - index.htm -app.get('/', (req, res) => { - res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) { - if (err) { - console.log('error sending file', err); - } else { - console.log("Server: Successfully served index.html"); - - /*setTimeout(()=>{ - console.log('closing server'); - res.app.server.close(); - process.exit(); - },1000*10); */ - } - }); -}); - -// Better to show landing page rather than 404 on editor page reload -app.get('/pixel-editor/app', (req, res) => { - res.redirect('/'); -}) //ROUTE - other files -app.use(express.static(path.join(__dirname, BUILDDIR))); +app.use('/pixel-editor', express.static(path.join(__dirname, BUILDDIR))); + // "reload" module allows us to trigger webpage reload automatically on file changes, but inside pixel editor it also // makes browser steal focus from any other window in order to ask user about unsaved changes. It might be quite @@ -46,3 +26,26 @@ if (process.env.RELOAD === "yes") { console.log(`Web server listening on port ${PORT}`); }) } + +// Better to show landing page rather than 404 on editor page reload +app.get('/', (req, res) => { + res.redirect('/pixel-editor'); +}) + + +//ROUTE - match / or any route with just numbers letters and dashes, and return index.htm (all other routes should have been handled already) +app.get(['/pixel-editor', /^\/pixel-editor\/[\/a-z0-9-]+$/gi ], (req, res) => { + res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) { + if (err) { + console.log('error sending file', err); + } else { + console.log("Server: Successfully served index.html", req.originalUrl); + } + }); +}); + +// Better to show landing page rather than 404 on editor page reload +app.get('/pixel-editor/app', (req, res) => { + res.redirect('/'); +}) + diff --git a/_ext/svg/adjust.svg b/svg/adjust.svg similarity index 100% rename from _ext/svg/adjust.svg rename to svg/adjust.svg diff --git a/_ext/svg/arrows/bottom.svg b/svg/arrows/bottom.svg similarity index 100% rename from _ext/svg/arrows/bottom.svg rename to svg/arrows/bottom.svg diff --git a/_ext/svg/arrows/bottomleft.svg b/svg/arrows/bottomleft.svg similarity index 100% rename from _ext/svg/arrows/bottomleft.svg rename to svg/arrows/bottomleft.svg diff --git a/_ext/svg/arrows/bottomright.svg b/svg/arrows/bottomright.svg similarity index 100% rename from _ext/svg/arrows/bottomright.svg rename to svg/arrows/bottomright.svg diff --git a/_ext/svg/arrows/left.svg b/svg/arrows/left.svg similarity index 100% rename from _ext/svg/arrows/left.svg rename to svg/arrows/left.svg diff --git a/_ext/svg/arrows/middle.svg b/svg/arrows/middle.svg similarity index 100% rename from _ext/svg/arrows/middle.svg rename to svg/arrows/middle.svg diff --git a/_ext/svg/arrows/right.svg b/svg/arrows/right.svg similarity index 100% rename from _ext/svg/arrows/right.svg rename to svg/arrows/right.svg diff --git a/_ext/svg/arrows/top.svg b/svg/arrows/top.svg similarity index 100% rename from _ext/svg/arrows/top.svg rename to svg/arrows/top.svg diff --git a/_ext/svg/arrows/topleft.svg b/svg/arrows/topleft.svg similarity index 100% rename from _ext/svg/arrows/topleft.svg rename to svg/arrows/topleft.svg diff --git a/_ext/svg/arrows/topright.svg b/svg/arrows/topright.svg similarity index 100% rename from _ext/svg/arrows/topright.svg rename to svg/arrows/topright.svg diff --git a/_ext/svg/ellipse.svg b/svg/ellipse.svg similarity index 100% rename from _ext/svg/ellipse.svg rename to svg/ellipse.svg diff --git a/_ext/svg/eraser.svg b/svg/eraser.svg similarity index 100% rename from _ext/svg/eraser.svg rename to svg/eraser.svg diff --git a/_ext/svg/eyedropper.svg b/svg/eyedropper.svg similarity index 100% rename from _ext/svg/eyedropper.svg rename to svg/eyedropper.svg diff --git a/_ext/svg/fill.svg b/svg/fill.svg similarity index 100% rename from _ext/svg/fill.svg rename to svg/fill.svg diff --git a/_ext/svg/filledellipse.svg b/svg/filledellipse.svg similarity index 100% rename from _ext/svg/filledellipse.svg rename to svg/filledellipse.svg diff --git a/_ext/svg/fullrect.svg b/svg/fullrect.svg similarity index 94% rename from _ext/svg/fullrect.svg rename to svg/fullrect.svg index 05958ee..23bae31 100644 --- a/_ext/svg/fullrect.svg +++ b/svg/fullrect.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_ext/svg/invisible.svg b/svg/invisible.svg similarity index 100% rename from _ext/svg/invisible.svg rename to svg/invisible.svg diff --git a/_ext/svg/line.svg b/svg/line.svg similarity index 94% rename from _ext/svg/line.svg rename to svg/line.svg index f5aa17b..75cbe7c 100644 --- a/_ext/svg/line.svg +++ b/svg/line.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_ext/svg/lockedpadlock.svg b/svg/lockedpadlock.svg similarity index 100% rename from _ext/svg/lockedpadlock.svg rename to svg/lockedpadlock.svg diff --git a/_ext/svg/lospec_logo_1x.svg b/svg/lospec_logo_1x.svg similarity index 100% rename from _ext/svg/lospec_logo_1x.svg rename to svg/lospec_logo_1x.svg diff --git a/_ext/svg/minus.svg b/svg/minus.svg similarity index 100% rename from _ext/svg/minus.svg rename to svg/minus.svg diff --git a/_ext/svg/newfile.svg b/svg/newfile.svg similarity index 100% rename from _ext/svg/newfile.svg rename to svg/newfile.svg diff --git a/_ext/svg/openfile.svg b/svg/openfile.svg similarity index 100% rename from _ext/svg/openfile.svg rename to svg/openfile.svg diff --git a/_ext/svg/pan.svg b/svg/pan.svg similarity index 100% rename from _ext/svg/pan.svg rename to svg/pan.svg diff --git a/_ext/svg/pencil.svg b/svg/pencil.svg similarity index 100% rename from _ext/svg/pencil.svg rename to svg/pencil.svg diff --git a/_ext/svg/plus.svg b/svg/plus.svg similarity index 100% rename from _ext/svg/plus.svg rename to svg/plus.svg diff --git a/_ext/svg/rectangle.svg b/svg/rectangle.svg similarity index 94% rename from _ext/svg/rectangle.svg rename to svg/rectangle.svg index 7ebcba9..8a68a92 100644 --- a/_ext/svg/rectangle.svg +++ b/svg/rectangle.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_ext/svg/rectselect.svg b/svg/rectselect.svg similarity index 96% rename from _ext/svg/rectselect.svg rename to svg/rectselect.svg index edb2491..464768a 100644 --- a/_ext/svg/rectselect.svg +++ b/svg/rectselect.svg @@ -1,108 +1,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_ext/svg/trash.svg b/svg/trash.svg similarity index 100% rename from _ext/svg/trash.svg rename to svg/trash.svg diff --git a/_ext/svg/unlockedpadlock.svg b/svg/unlockedpadlock.svg similarity index 100% rename from _ext/svg/unlockedpadlock.svg rename to svg/unlockedpadlock.svg diff --git a/_ext/svg/visible.svg b/svg/visible.svg similarity index 100% rename from _ext/svg/visible.svg rename to svg/visible.svg diff --git a/_ext/svg/warning.svg b/svg/warning.svg similarity index 98% rename from _ext/svg/warning.svg rename to svg/warning.svg index bef18ae..5b49c2e 100644 --- a/_ext/svg/warning.svg +++ b/svg/warning.svg @@ -1,3 +1,3 @@ - - - + + + diff --git a/_ext/svg/x.svg b/svg/x.svg similarity index 100% rename from _ext/svg/x.svg rename to svg/x.svg diff --git a/_ext/svg/zoom.svg b/svg/zoom.svg similarity index 100% rename from _ext/svg/zoom.svg rename to svg/zoom.svg diff --git a/views/about-popup.hbs b/views/about-popup.hbs new file mode 100644 index 0000000..5c8760f --- /dev/null +++ b/views/about-popup.hbs @@ -0,0 +1,10 @@ +
+ +

About Lospec Pixel Editor

+
version 1.1.0
+

This is a web-based tool for creating and editing pixel art.

+

The goal of this tool is to be an accessible and intuitive tool that's simple enough for a first time pixel artist while still being usable enough for a veteran.

+

In the future I hope to add enough features to become a full fledged pixel art editor, with everything an artist could need.

+

About Lospec

+

Lospec is a website created to host tools for pixel artists. To see more of our tools, visit our homepage. To hear about any updates or new tools, follow us on Twitter.

+
\ No newline at end of file diff --git a/views/canvas-resize-popup.hbs b/views/canvas-resize-popup.hbs new file mode 100644 index 0000000..5c4fb40 --- /dev/null +++ b/views/canvas-resize-popup.hbs @@ -0,0 +1,59 @@ + +
+ +

Resize canvas

+ + + + + + + + + + + + + + + +

Size

+
+ + Width: + + + + Height: + +
+
+ + +

Borders offsets

+
+ + Left: + + + + Right: + + + + Top: + + + + Bottom: + +
+ +
+
\ No newline at end of file diff --git a/views/canvases.hbs b/views/canvases.hbs new file mode 100644 index 0000000..b17615f --- /dev/null +++ b/views/canvases.hbs @@ -0,0 +1,9 @@ + +
+ + + + + +
+
\ No newline at end of file diff --git a/views/changelog-popup.hbs b/views/changelog-popup.hbs new file mode 100644 index 0000000..ec94ca3 --- /dev/null +++ b/views/changelog-popup.hbs @@ -0,0 +1,11 @@ +
+ + +

Changelog

+ {{#each changelog}} +

Version {{@key}}

+ + {{/each}} +
\ No newline at end of file diff --git a/views/colors-menu.hbs b/views/colors-menu.hbs new file mode 100644 index 0000000..bba9602 --- /dev/null +++ b/views/colors-menu.hbs @@ -0,0 +1,14 @@ + + +
+ # +
{{svg "warning.svg" width="14" + height="12" }}
+ +
+ +
+ {{svg "adjust.svg" width="20" height="20" }} +
\ No newline at end of file diff --git a/views/compatibility-warning.hbs b/views/compatibility-warning.hbs new file mode 100644 index 0000000..29b7d78 --- /dev/null +++ b/views/compatibility-warning.hbs @@ -0,0 +1,15 @@ +
+
+
+

Warning: a modern, desktop, web browser is required to use this tool.

+

We detected that you may have an out of date or unsupported web browser. This tool, like many others on + this site and across the web uses features only available in new web browsers. We reccommend updating + your current browser or downloading Firefox or Chrome.

+ +
+
+
+ + \ No newline at end of file diff --git a/views/credits-popup.hbs b/views/credits-popup.hbs new file mode 100644 index 0000000..a36577e --- /dev/null +++ b/views/credits-popup.hbs @@ -0,0 +1,10 @@ +
+ +

Credits

+

Icons

+ +
\ No newline at end of file diff --git a/views/data-asdfgasd.hbs b/views/data-asdfgasd.hbs new file mode 100644 index 0000000..e69de29 diff --git a/views/help-popup.hbs b/views/help-popup.hbs new file mode 100644 index 0000000..a02ce58 --- /dev/null +++ b/views/help-popup.hbs @@ -0,0 +1,44 @@ +
+ +

Help

+

Palette

+ +

Hotkeys

+ +

Mouse Shortcuts

+ +

Layers

+ +
\ No newline at end of file diff --git a/views/holders.hbs b/views/holders.hbs new file mode 100644 index 0000000..1c83b49 --- /dev/null +++ b/views/holders.hbs @@ -0,0 +1,7 @@ +
+ dl + dl + + + +
\ No newline at end of file diff --git a/views/index.hbs b/views/index.hbs new file mode 100644 index 0000000..db5ce38 --- /dev/null +++ b/views/index.hbs @@ -0,0 +1,44 @@ + + + + + + {{title}} + + + + + {{{google-analytics}}} + {{{favicons}}} + + + + {{> compatibility-warning}} + {{> preload}} + + {{> main-menu}} + {{> tools-menu}} + {{> colors-menu}} + {{> layers-menu}} + + {{> tool-previews}} + {{> canvases}} + {{> holders}} + +
+ {{> start-pixel-popup}} + {{> splash-page-popup}} + {{> sprite-resize-popup}} + {{> canvas-resize-popup}} + {{> palette-popup}} + {{> help-popup}} + {{> about-popup}} + {{> changelog-popup}} + {{> credits-popup}} + {{> settings-popup}} +
+ + + + + \ No newline at end of file diff --git a/logs/latestLog.html b/views/latestLog.hbs similarity index 99% rename from logs/latestLog.html rename to views/latestLog.hbs index 9871410..6cdd02a 100644 --- a/logs/latestLog.html +++ b/views/latestLog.hbs @@ -1,4 +1,3 @@ -

Latest update

Hello there, welcome to the latest version of the Lospec Pixel Editor. As you can see, we changed quite a lot of things. Let's go through all them, starting from this page. diff --git a/views/layers-menu.hbs b/views/layers-menu.hbs new file mode 100644 index 0000000..c4ea3b3 --- /dev/null +++ b/views/layers-menu.hbs @@ -0,0 +1,49 @@ + + + + \ No newline at end of file diff --git a/_ext/modules/hbs/layout-contribute.hbs b/views/layout-contribute.hbs similarity index 100% rename from _ext/modules/hbs/layout-contribute.hbs rename to views/layout-contribute.hbs diff --git a/views/main-menu.hbs b/views/main-menu.hbs new file mode 100644 index 0000000..0b31a8a --- /dev/null +++ b/views/main-menu.hbs @@ -0,0 +1,68 @@ + \ No newline at end of file diff --git a/views/palette-popup.hbs b/views/palette-popup.hbs new file mode 100644 index 0000000..e5a3ae5 --- /dev/null +++ b/views/palette-popup.hbs @@ -0,0 +1,74 @@ + +
+ + +

Edit palette

+ +
+
+ + + + +
+ +
+ +
+
+ + + +
+ +
+ + + +
+ +
+ + + +
+
+ +
+ +
+ +
+
+ +
+
+ #123456 +
+
+ +
+ + + + + + +
+
+
+ +
+ +
+ +
+ + +
+
\ No newline at end of file diff --git a/views/pixel-editor-splash-page.hbs b/views/pixel-editor-splash-page.hbs deleted file mode 100644 index 9732386..0000000 --- a/views/pixel-editor-splash-page.hbs +++ /dev/null @@ -1,42 +0,0 @@ -

{{title}}

- -

-The Lospec Pixel editor is a free pixel art program that you can use right here -in your web browser. Our goal was to create an easy to use, intuitive and -unobtrusive pixel art application that you can use anywhere. Whether you're -creating assets for a game or just want to make 8 bit art, this tool is an easy -way to pixel fast. -

- -Lospec Pixel Editor Screenshot - -

-This application does not have all the features of more advanced desktop editor, -but we will add more over time. It currently features a pencil, eraser, fill, pan, eyedropper -and zoom tool. You can also easily adjust any colors in your palette. You can -use any palette in our Palette List by clicking the pencil next to the palette -title. -

- -

-This app currently only works on desktops, and requires a modern browser such as -the latest versions of Firefox or Chrome. -

- -Enter app now  {{svg "angle-right.svg" width="32" height="32"}} - -
- -

This app has been made in collaboration with contributors on GitHub. We welcome anyone to submit bugfixes and new features.

- -
Our Contributors:
- -
- -
- -View on GitHub  {{svg "github"}} - - - - diff --git a/views/pixel-editor.hbs b/views/pixel-editor.hbs deleted file mode 100644 index f7c5e5a..0000000 --- a/views/pixel-editor.hbs +++ /dev/null @@ -1,656 +0,0 @@ - - - - - - {{title}} - - - - - {{{google-analytics}}} - {{{favicons}}} - - - -
-
-

Warning: a modern, desktop, web browser is required to use this tool.

-

We detected that you may have an out of date or unsupported web browser. This tool, like many others on this site and across the web uses features only available in new web browsers. We reccommend updating your current browser or downloading Firefox or Chrome.

- -
-
- - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - -
-
- - -
- - - - - -
-
- -
- dl - dl - - - -
- -
- # -
{{svg "warning.svg" width="14" height="12" }}
- -
- -
- {{svg "adjust.svg" width="20" height="20" }} -
- -
- -
- -

New Pixel

- - -

Editor mode

- - - -

- - -

Preset

- - - -

Size

- {{svg "x.svg" width="16" height="16" class="dimentions-x"}} -

Palette

- - - -
Creating a new pixel will discard your current one.
-
- -
-
- - -
-
-
-

Latest updates

-
-
- -
- - -
-
-

New Custom Pixel

- -

Editor mode

-
-
-

Basic

-

Advanced

-
-
- -

Size

-
- {{svg "x.svg" width="16" height="16" class="dimentions-x"}} -
- -

Palette

- - - -
Creating a new pixel will discard your current one.
-
- -
-
- -
-
- Quickstart -
- -
-

Load

-

New Gameboy

-

New C64

-

New Pico8

-

New 16x16

-

New 32x32

-

New 64x64

-

New 128x128

-

New 256x256

-

New 512x512

-
-
-
-
-
- - -
- -

Scale sprite

- -

New size

- -
- - Width: - - - - Height: - -
-
- -

Resize percentages

- -
- - Width % - - - - Height % - -
-
- - Keep current ratio - - - Scaling algorithm: - - -
- -
-
-
- - -
- -

Resize canvas

- - - - - - - - - - - - - - - -

Size

-
- - Width: - - - - Height: - -
-
- - -

Borders offsets

-
- - Left: - - - - Right: - - - - Top: - - - - Bottom: - -
- -
-
- - -
- - -

Edit palette

- -
-
- - - - -
- -
- -
-
- - - -
- -
- - - -
- -
- - - -
-
- -
- -
- -
-
- -
-
- #123456 -
-
- -
- - - - - - -
-
-
- -
-
    -
  • -
  • -
-
- -
- - -
-
- -
- -

Help

-

Palette

- -

Hotkeys

- -

Mouse Shortcuts

- -

Layers

- -
-
- -

About Lospec Pixel Editor

-
version 1.1.0
-

This is a web-based tool for creating and editing pixel art.

-

The goal of this tool is to be an accessible and intuitive tool that's simple enough for a first time pixel artist while still being usable enough for a veteran.

-

In the future I hope to add enough features to become a full fledged pixel art editor, with everything an artist could need.

-

About Lospec

-

Lospec is a website created to host tools for pixel artists. To see more of our tools, visit our homepage. To hear about any updates or new tools, follow us on Twitter.

-
-
- - -

Changelog

- {{#each changelog}} -

Version {{@key}}

- - {{/each}} -
-
- -

Credits

-

Icons

- -
-
- -

Settings

- -
-

History

-
- -
- -

Pixel grid

-
- -
-
- -

Your browsers cookies are disabled, settings will be lost upon closing this page.

- -
- -
-
-
- - - - - - \ No newline at end of file diff --git a/views/preload.hbs b/views/preload.hbs new file mode 100644 index 0000000..127eff7 --- /dev/null +++ b/views/preload.hbs @@ -0,0 +1,14 @@ +
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/views/settings-popup.hbs b/views/settings-popup.hbs new file mode 100644 index 0000000..a283ec3 --- /dev/null +++ b/views/settings-popup.hbs @@ -0,0 +1,22 @@ +
+ +

Settings

+ +
+

History

+
+ +
+ +

Pixel grid

+
+ +
+
+ +

Your browsers cookies are disabled, settings will be lost upon closing this page.

+ +
+ +
+
\ No newline at end of file diff --git a/views/splash-page-popup.hbs b/views/splash-page-popup.hbs new file mode 100644 index 0000000..d381df6 --- /dev/null +++ b/views/splash-page-popup.hbs @@ -0,0 +1,71 @@ + +
+
+
+

Latest updates

+ + {{> latestLog}} +
+
+ +
+ + +
+
+

New Custom Pixel

+ +

Size

+
+ {{svg "x.svg" width="16" height="16" class="dimentions-x"}} +
+ +

Palette

+ + + +
Creating a new pixel will discard your current one.
+
+ +
+
+ +
+
+ Quickstart +
+ +
+

Load

+

New Gameboy

+

New C64

+

New Pico8

+

New 16x16

+

New 32x32

+

New 64x64

+

New 128x128

+

New 256x256

+

New 512x512

+
+ +
+ You are using Basic Mode. + You are using Advanced Mode. + + Switch to Advanced Mode. + Switch to using Basic Mode. + ยป + +
+
+
+
+
\ No newline at end of file diff --git a/views/sprite-resize-popup.hbs b/views/sprite-resize-popup.hbs new file mode 100644 index 0000000..8db0ec0 --- /dev/null +++ b/views/sprite-resize-popup.hbs @@ -0,0 +1,49 @@ + +
+ +

Scale sprite

+ +

New size

+ +
+ + Width: + + + + Height: + +
+
+ +

Resize percentages

+ +
+ + Width % + + + + Height % + +
+
+ + Keep current ratio + + + Scaling algorithm: + + +
+ +
+
+
\ No newline at end of file diff --git a/views/start-pixel-popup.hbs b/views/start-pixel-popup.hbs new file mode 100644 index 0000000..a35cad0 --- /dev/null +++ b/views/start-pixel-popup.hbs @@ -0,0 +1,21 @@ + +
+ +

New Pixel

+ + +

Preset

+ + + +

Size

+ {{svg "x.svg" width="16" height="16" class="dimentions-x"}} +

Palette

+ + + +
Creating a new pixel will discard your current one.
+
+ +
+
\ No newline at end of file diff --git a/views/tool-previews.hbs b/views/tool-previews.hbs new file mode 100644 index 0000000..0615d60 --- /dev/null +++ b/views/tool-previews.hbs @@ -0,0 +1,3 @@ + +
+
\ No newline at end of file diff --git a/views/tools-menu.hbs b/views/tools-menu.hbs new file mode 100644 index 0000000..9748228 --- /dev/null +++ b/views/tools-menu.hbs @@ -0,0 +1,46 @@ + \ No newline at end of file