fixed merge

This commit is contained in:
Sam Keddy
2020-04-15 00:10:21 +00:00
45 changed files with 5409 additions and 4199 deletions

34
.eslintrc.json Normal file
View File

@@ -0,0 +1,34 @@
{
"env": {
"browser": false,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

130
build.js
View File

@@ -1,93 +1,59 @@
var fs = require('fs-extra'); const fs = require('fs');
var hbs = require('handlebars'); const path = require('path');
var glob = require("glob"); const gulp = require('gulp');
var sass = require("sass"); const include = require('gulp-include');
var path = require("path"); const hb = require('gulp-hb');
var gulp = require('gulp'); const sass = require('gulp-sass');
var include = require('gulp-include'); const rename = require('gulp-rename');
const BUILDDIR = './build'; const hb_svg = require('handlebars-helper-svg');
const BUILDDIR = process.argv[2] || './build/';
const SLUG = 'pixel-editor'; const SLUG = 'pixel-editor';
console.log('Building Pixel Editor'); console.log('Building Pixel Editor');
hbs.registerHelper('svg', require('handlebars-helper-svg'));
require('hbs-register-helpers')(hbs,'./_ext/modules/hbs/helpers/**/*.js');
require('hbs-register-partials')(hbs,'./_ext/modules/hbs/_*.hbs');
//empty the build folder, or create it function copy_images(){
fs.emptyDirSync(BUILDDIR); gulp.src('./images/')
.pipe(gulp.dest(path.join(BUILDDIR, SLUG)));
}
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)));
}
//copy images function render_css(){
fs.copySync('./images','./build/'+SLUG); gulp.src('css/*.scss')
.pipe(sass({includePaths: ['css', '_ext/sass', '_ext/modules/css']}))
.pipe(gulp.dest(path.join(BUILDDIR, SLUG)));
}
//render js function compile_page(){
gulp.src('./js/*.js') gulp.src(path.join('./views/', SLUG + '.hbs'))
.pipe(include({includePaths: [ .pipe(hb({encoding: 'utf8'})
'_ext/scripts', .partials('./_ext/modules/_*.hbs')
'js', .helpers({ svg: hb_svg })
'!js/_*.js', .helpers('./_ext/modules/hbs/helpers/**/*.js')
]})) .data({
.on('error', console.log) projectSlug: SLUG,
.pipe(gulp.dest('build/'+SLUG)); title: 'Lospec Pixel Editor',
layout: false,
}))
.pipe(rename('index.htm'))
.pipe(gulp.dest(BUILDDIR));
}
//render css // empty the build folder, or create it
var sassFiles = glob.sync('css/*.scss'); fs.rmdirSync(BUILDDIR, { recursive: true });
fs.mkdirSync(BUILDDIR);
sassFiles.forEach((s) => { gulp.parallel(copy_images, render_js, render_css, compile_page)();
var f = sass.renderSync({file: s, outFile: 'test.css', includePaths: ['css', '_ext/sass', '_ext/modules/css']});
console.log('compiling:',path.basename(f.stats.entry))
fs.writeFileSync('build/'+SLUG+'/'+path.basename(f.stats.entry,'scss')+'css', f.css);
});
//compile page
var pageTemplate = hbs.compile(fs.readFileSync('./views/'+SLUG+'.hbs',{encoding: 'utf8'}));
var page = pageTemplate({
projectSlug: SLUG,
title: 'Lospec Pixel Editor',
layout: false,
});
//save output
fs.writeFileSync('./build/index.htm',page);
//server
const express = require('express');
const app = express();
//ROUTE - index.htm
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname+'/build/index.htm'), {}, function (err) {
if (err) console.log('error sending file',err);
else {
setTimeout(()=>{
console.log('closing server')
server.close();
process.exit();
},1000*10);
}
});
});
//ROUTE - other files
app.use(express.static(path.join(__dirname, 'build')));
//start server
var server = app.listen(3000, () => {
console.log('\nTemp server started at http://localhost:3000!');
//console.log('press ctrl+c to stop ');
var opn = require('opn');
// opens the url in the default browser
opn('http://localhost:3000');
});

34
js/.eslintrc.json Normal file
View File

@@ -0,0 +1,34 @@
{
"env": {
"browser": true,
"es6": true
},
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
4,
{
"SwitchCase": 1
}
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

View File

@@ -2,48 +2,48 @@
//input hex color string //input hex color string
//returns list item element //returns list item element
function addColor (newColor) { function addColor (newColor) {
//add # at beginning if not present //add # at beginning if not present
if (newColor.charAt(0) != '#') if (newColor.charAt(0) != '#')
newColor = '#' + newColor; newColor = '#' + newColor;
//create list item //create list item
var listItem = document.createElement("li"); var listItem = document.createElement('li');
//create button //create button
var button = document.createElement("button"); var button = document.createElement('button');
button.classList.add("color-button"); button.classList.add('color-button');
button.style.backgroundColor = newColor; button.style.backgroundColor = newColor;
button.addEventListener("mouseup", clickedColor); button.addEventListener('mouseup', clickedColor);
listItem.appendChild(button); listItem.appendChild(button);
/* /*
//create input to hold color value //create input to hold color value
var colorValue = document.createElement("input"); var colorValue = document.createElement("input");
colorValue.classList.add("color-value"); colorValue.classList.add("color-value");
listItem.appendChild(colorValue); listItem.appendChild(colorValue);
*/ */
//insert new listItem element at the end of the colors menu (right before add button) //insert new listItem element at the end of the colors menu (right before add button)
colorsMenu.insertBefore(listItem, colorsMenu.children[colorsMenu.children.length-1]); colorsMenu.insertBefore(listItem, colorsMenu.children[colorsMenu.children.length-1]);
//add jscolor functionality //add jscolor functionality
initColor(button); initColor(button);
//add edit button //add edit button
var editButtonTemplate = document.getElementsByClassName('color-edit-button')[0]; var editButtonTemplate = document.getElementsByClassName('color-edit-button')[0];
newEditButton = editButtonTemplate.cloneNode(true); newEditButton = editButtonTemplate.cloneNode(true);
listItem.appendChild(newEditButton); listItem.appendChild(newEditButton);
//when you click the edit button //when you click the edit button
on('click', newEditButton, function (event, button) { on('click', newEditButton, function (event, button) {
//hide edit button //hide edit button
button.parentElement.lastChild.classList.add('hidden'); button.parentElement.lastChild.classList.add('hidden');
//show jscolor picker //show jscolor picker
button.parentElement.firstChild.jscolor.show(); button.parentElement.firstChild.jscolor.show();
}); });
return listItem; return listItem;
} }

View File

@@ -1,59 +1,59 @@
//add color button //add color button
on('click', 'add-color-button', function(){ on('click', 'add-color-button', function(){
if (!documentCreated) return; if (!documentCreated) return;
var colorCheckingStyle = ` var colorCheckingStyle = `
color: white; color: white;
background: #3c4cc2; background: #3c4cc2;
`; `;
var colorIsUnique = true var colorIsUnique = true;
do { do {
//console.log('%cchecking for unique colors', colorCheckingStyle) //console.log('%cchecking for unique colors', colorCheckingStyle)
//generate random color //generate random color
var hue = Math.floor(Math.random()*255); var hue = Math.floor(Math.random()*255);
var sat = 130+Math.floor(Math.random()*100); var sat = 130+Math.floor(Math.random()*100);
var lit = 70+Math.floor(Math.random()*100); var lit = 70+Math.floor(Math.random()*100);
var newColorRgb = hslToRgb(hue,sat,lit) var newColorRgb = hslToRgb(hue,sat,lit);
var newColor = rgbToHex(newColorRgb.r,newColorRgb.g,newColorRgb.b) var newColor = rgbToHex(newColorRgb.r,newColorRgb.g,newColorRgb.b);
var newColorHex = newColor; var newColorHex = newColor;
//check if color has been used before //check if color has been used before
colors = document.getElementsByClassName('color-button'); colors = document.getElementsByClassName('color-button');
colorCheckingLoop: for (var i = 0; i < colors.length; i++) { colorCheckingLoop: for (var i = 0; i < colors.length; i++) {
//console.log('%c'+newColorHex +' '+ colors[i].jscolor.toString(), colorCheckingStyle) //console.log('%c'+newColorHex +' '+ colors[i].jscolor.toString(), colorCheckingStyle)
//if generated color matches this color //if generated color matches this color
if (newColorHex == colors[i].jscolor.toString()) { if (newColorHex == colors[i].jscolor.toString()) {
//console.log('%ccolor already exists', colorCheckingStyle) //console.log('%ccolor already exists', colorCheckingStyle)
//start loop again //start loop again
colorIsUnique = false; colorIsUnique = false;
//exit //exit
break colorCheckingLoop; break colorCheckingLoop;
} }
}
} }
} while (colorIsUnique == false);
while (colorIsUnique == false);
//remove current color selection
//remove current color selection document.querySelector('#colors-menu li.selected').classList.remove('selected');
document.querySelector("#colors-menu li.selected").classList.remove("selected");
//add new color and make it selected
//add new color and make it selected var addedColor = addColor(newColor);
var addedColor = addColor(newColor); addedColor.classList.add('selected');
addedColor.classList.add('selected'); context.fillStyle = '#' + newColor;
context.fillStyle = '#' + newColor;
//add history state
//add history state //saveHistoryState({type: 'addcolor', colorValue: addedColor.firstElementChild.jscolor.toString()});
//saveHistoryState({type: 'addcolor', colorValue: addedColor.firstElementChild.jscolor.toString()}); new HistoryStateAddColor(addedColor.firstElementChild.jscolor.toString());
new HistoryStateAddColor(addedColor.firstElementChild.jscolor.toString());
//show color picker
//show color picker addedColor.firstElementChild.jscolor.show();
addedColor.firstElementChild.jscolor.show(); console.log('showing picker');
console.log("showing picker");
//hide edit button
//hide edit button addedColor.lastChild.classList.add('hidden');
addedColor.lastChild.classList.add('hidden'); }, false);
}, false);

View File

@@ -1,26 +0,0 @@
function changeTool (newToolName) {
console.log('changing tool to',newToolName)
var selectedTool = tool[newToolName];
// Ending any selection in progress
if (currentTool.name.includes("select") && !selectedTool.name.includes("select") && !selectionCanceled) {
endSelection();
}
//set tool and temp tje tje tpp;
currentTool = selectedTool;
currentToolTemp = selectedTool;
var tools = document.getElementById("tools-menu").children;
for (var i = 0; i < tools.length; i++) {
tools[i].classList.remove("selected");
}
//give the button of the selected tool the .selected class
document.getElementById(selectedTool.name+"-button").parentNode.classList.add("selected");
//change cursor
currentTool.updateCursor();
}

View File

@@ -1,4 +1,3 @@
function changeZoom (layer, direction, cursorLocation) { function changeZoom (layer, direction, cursorLocation) {
var oldWidth = canvasSize[0] * zoom; var oldWidth = canvasSize[0] * zoom;
var oldHeight = canvasSize[1] * zoom; var oldHeight = canvasSize[1] * zoom;
@@ -29,4 +28,4 @@ function changeZoom (layer, direction, cursorLocation) {
// adjust brush size // adjust brush size
currentTool.updateCursor(); currentTool.updateCursor();
} }

View File

@@ -1,20 +1,19 @@
/////=include libraries/bowser.js /////=include libraries/bowser.js
function closeCompatibilityWarning () { function closeCompatibilityWarning () {
document.getElementById('compatibility-warning').style.visibility = 'hidden'; document.getElementById('compatibility-warning').style.visibility = 'hidden';
} }
console.log('checking compatibility') console.log('checking compatibility');
//check browser/version //check browser/version
if ( (bowser.msie && bowser.version < 11) || if ((bowser.msie && bowser.version < 11) ||
(bowser.firefox && bowser.version < 28) || (bowser.firefox && bowser.version < 28) ||
(bowser.chrome && bowser.version < 29) || (bowser.chrome && bowser.version < 29) ||
(bowser.msedge && bowser.version < 12) || (bowser.msedge && bowser.version < 12) ||
(bowser.safari && bowser.version < 9) || (bowser.safari && bowser.version < 9) ||
(bowser.opera && bowser.version < 17) ) (bowser.opera && bowser.version < 17) )
//show warning //show warning
document.getElementById('compatibility-warning').style.visibility = 'visible'; document.getElementById('compatibility-warning').style.visibility = 'visible';
else alert(bowser.name+' '+bowser.version+' is fine!') else alert(bowser.name+' '+bowser.version+' is fine!');

View File

@@ -1,59 +1,59 @@
// This script contains all the functions used to manage the checkboard // This script contains all the functions used to manage the checkboard
// Setting current colour (each square has a different colour // Setting current colour (each square has a different colour
var currentColor = firstCheckerBoardColor; var currentColor = firstCheckerBoardColor;
// Saving number of squares filled until now // Saving number of squares filled until now
var nSquaresFilled = 0; var nSquaresFilled = 0;
function fillCheckerboard() { function fillCheckerboard() {
// Getting checkerboard context // Getting checkerboard context
var context = checkerBoard.context; var context = checkerBoard.context;
// Cycling through the canvas (using it as a matrix) // Cycling through the canvas (using it as a matrix)
for (var i=0; i<canvasSize[0] / checkerBoardSquareSize; i++) { for (var i=0; i<canvasSize[0] / checkerBoardSquareSize; i++) {
nSquaresFilled = 0; nSquaresFilled = 0;
for (var j=0; j<canvasSize[1] / checkerBoardSquareSize; j++) { for (var j=0; j<canvasSize[1] / checkerBoardSquareSize; j++) {
var rectX; var rectX;
var rectY; var rectY;
// Managing the not perfect squares (the ones at the sides if the canvas' sizes are not powers of checkerBoardSquareSize // Managing the not perfect squares (the ones at the sides if the canvas' sizes are not powers of checkerBoardSquareSize
if (i * checkerBoardSquareSize < canvasSize[0]) { if (i * checkerBoardSquareSize < canvasSize[0]) {
rectX = i * checkerBoardSquareSize; rectX = i * checkerBoardSquareSize;
} }
else { else {
rectX = canvasSize[0]; rectX = canvasSize[0];
} }
if (j * checkerBoardSquareSize < canvasSize[1]) { if (j * checkerBoardSquareSize < canvasSize[1]) {
rectY = j * checkerBoardSquareSize; rectY = j * checkerBoardSquareSize;
} }
else { else {
rectY = canvasSize[1]; rectY = canvasSize[1];
} }
// Selecting the colour // Selecting the colour
context.fillStyle = currentColor; context.fillStyle = currentColor;
context.fillRect(rectX, rectY, checkerBoardSquareSize, checkerBoardSquareSize); context.fillRect(rectX, rectY, checkerBoardSquareSize, checkerBoardSquareSize);
// Changing colour // Changing colour
changeCheckerboardColor(); changeCheckerboardColor();
nSquaresFilled++; nSquaresFilled++;
} }
// If the number of filled squares was even, I change colour for the next column // If the number of filled squares was even, I change colour for the next column
if ((nSquaresFilled % 2) == 0) { if ((nSquaresFilled % 2) == 0) {
changeCheckerboardColor(); changeCheckerboardColor();
} }
} }
} }
// Simply switches the checkerboard colour // Simply switches the checkerboard colour
function changeCheckerboardColor(isVertical) { function changeCheckerboardColor(isVertical) {
if (currentColor == firstCheckerBoardColor) { if (currentColor == firstCheckerBoardColor) {
currentColor = secondCheckerBoardColor; currentColor = secondCheckerBoardColor;
} else if (currentColor == secondCheckerBoardColor) { } else if (currentColor == secondCheckerBoardColor) {
currentColor = firstCheckerBoardColor; currentColor = firstCheckerBoardColor;
} }
} }

View File

@@ -3,28 +3,25 @@ function clickedColor (e){
//left clicked color //left clicked color
if (e.which == 1) { if (e.which == 1) {
// remove current color selection
//remove current color selection var selectedColor = document.querySelector('#colors-menu li.selected');
var selectedColor = document.querySelector("#colors-menu li.selected") if (selectedColor) selectedColor.classList.remove('selected');
if (selectedColor) selectedColor.classList.remove("selected");
//set current color //set current color
currentLayer.context.fillStyle = this.style.backgroundColor; currentLayer.context.fillStyle = this.style.backgroundColor;
currentGlobalColor = this.style.backgroundColor; currentGlobalColor = this.style.backgroundColor;
//make color selected //make color selected
e.target.parentElement.classList.add('selected'); e.target.parentElement.classList.add('selected');
//right clicked color } else if (e.which == 3) { //right clicked color
} else if (e.which == 3) { console.log('right clicked color button');
console.log('right clicked color button')
//hide edit color button (to prevent it from showing)
//hide edit color button (to prevent it from showing) e.target.parentElement.lastChild.classList.add('hidden');
e.target.parentElement.lastChild.classList.add('hidden');
//show color picker
//show color picker e.target.jscolor.show();
e.target.jscolor.show();
} }
} }

View File

@@ -3,92 +3,92 @@
document.getElementById('jscolor-hex-input').addEventListener('change', colorChanged, false); document.getElementById('jscolor-hex-input').addEventListener('change', colorChanged, false);
on('input', 'jscolor-hex-input', function (e) { on('input', 'jscolor-hex-input', function (e) {
//get hex value //get hex value
var newColorHex = e.target.value.toLowerCase(); var newColorHex = e.target.value.toLowerCase();
//if the color is not (yet) a valid hex color, exit this function and do nothing //if the color is not (yet) a valid hex color, exit this function and do nothing
if (/^[0-9a-f]{6}$/i.test(newColorHex) == false) if (/^[0-9a-f]{6}$/i.test(newColorHex) == false)
return; return;
//get currently editing color //get currently editing color
var currentlyEditedColor = document.getElementsByClassName('jscolor-active')[0]; var currentlyEditedColor = document.getElementsByClassName('jscolor-active')[0];
//update the actual color picker to the inputted color //update the actual color picker to the inputted color
currentlyEditedColor.firstChild.jscolor.fromString(newColorHex); currentlyEditedColor.firstChild.jscolor.fromString(newColorHex);
colorChanged(e); colorChanged(e);
}) });
//changes all of one color to another after being changed from color picker //changes all of one color to another after being changed from color picker
function colorChanged(e) { function colorChanged(e) {
console.log('colorChanged()'); console.log('colorChanged()');
//get colors //get colors
var newColor = hexToRgb(e.target.value); var newColor = hexToRgb(e.target.value);
var oldColor = e.target.oldColor; var oldColor = e.target.oldColor;
//save undo state
//saveHistoryState({type: 'colorchange', newColor: e.target.value, oldColor: rgbToHex(oldColor), canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
new HistoryStateEditColor(e.target.value.toLowerCase(), rgbToHex(oldColor));
//get the currently selected color
var currentlyEditedColor = document.getElementsByClassName('jscolor-active')[0];
var duplicateColorWarning = document.getElementById("duplicate-color-warning");
//check if selected color already matches another color //save undo state
colors = document.getElementsByClassName('color-button'); //saveHistoryState({type: 'colorchange', newColor: e.target.value, oldColor: rgbToHex(oldColor), canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
var colorCheckingStyle = "background: #bc60c4; color: white" new HistoryStateEditColor(e.target.value.toLowerCase(), rgbToHex(oldColor));
var newColorHex = e.target.value.toLowerCase();
//if the color is not a valid hex color, exit this function and do nothing
if (/^[0-9a-f]{6}$/i.test(newColorHex) == false)
return;
//loop through all colors in palette
for (var i = 0; i < colors.length; i++) {
//if generated color matches this color
if (newColorHex == colors[i].jscolor.toString()) {
//console.log('%ccolor already exists'+(colors[i].parentElement.classList.contains('jscolor-active')?' (but is the current color)':''), colorCheckingStyle);
//if the color isnt the one that has the picker currently open //get the currently selected color
if (!colors[i].parentElement.classList.contains('jscolor-active')) { var currentlyEditedColor = document.getElementsByClassName('jscolor-active')[0];
//console.log('%cColor is duplicate', colorCheckingStyle) var duplicateColorWarning = document.getElementById('duplicate-color-warning');
//show the duplicate color warning //check if selected color already matches another color
duplicateColorWarning.style.visibility = 'visible'; colors = document.getElementsByClassName('color-button');
var colorCheckingStyle = 'background: #bc60c4; color: white';
//shake warning icon var newColorHex = e.target.value.toLowerCase();
duplicateColorWarning.classList.remove('shake');
void duplicateColorWarning.offsetWidth; //if the color is not a valid hex color, exit this function and do nothing
duplicateColorWarning.classList.add('shake'); if (/^[0-9a-f]{6}$/i.test(newColorHex) == false)
//exit function without updating color
return; return;
}
}
}
//if the color being edited has a duplicate color warning, remove it
duplicateColorWarning.style.visibility = 'hidden';
currentlyEditedColor.firstChild.jscolor.fromString(newColorHex)
replaceAllOfColor(oldColor, newColor);
//set new old color to changed color
e.target.oldColor = newColor;
//loop through all colors in palette
//if this is the current color, update the drawing color for (var i = 0; i < colors.length; i++) {
if (e.target.colorElement.parentElement.classList.contains('selected')) {
//console.log('this color is the current color'); //if generated color matches this color
context.fillStyle = currentColor; if (newColorHex == colors[i].jscolor.toString()) {
} // console.log('%ccolor already exists'+(colors[i].parentElement.classList.contains('jscolor-active')?' (but is the current color)':''), colorCheckingStyle);
/* this is wrong and bad
if (settings.switchToChangedColor) { //if the color isnt the one that has the picker currently open
if (!colors[i].parentElement.classList.contains('jscolor-active')) {
}*/ // console.log('%cColor is duplicate', colorCheckingStyle);
//show the duplicate color warning
duplicateColorWarning.style.visibility = 'visible';
//shake warning icon
duplicateColorWarning.classList.remove('shake');
void duplicateColorWarning.offsetWidth;
duplicateColorWarning.classList.add('shake');
//exit function without updating color
return;
}
}
}
//if the color being edited has a duplicate color warning, remove it
duplicateColorWarning.style.visibility = 'hidden';
currentlyEditedColor.firstChild.jscolor.fromString(newColorHex);
replaceAllOfColor(oldColor, newColor);
//set new old color to changed color
e.target.oldColor = newColor;
//if this is the current color, update the drawing color
if (e.target.colorElement.parentElement.classList.contains('selected')) {
// console.log('this color is the current color');
context.fillStyle = currentColor;
}
/* this is wrong and bad
if (settings.switchToChangedColor) {
}*/
} }

View File

@@ -1,22 +1,21 @@
on('click', 'create-button', function (){ on('click', 'create-button', function (){
var width = getValue('size-width'); var width = getValue('size-width');
var height = getValue('size-height'); var height = getValue('size-height');
newPixel(width,height,'asdfg'); newPixel(width,height,'asdfg');
document.getElementById('new-pixel-warning').style.display = 'block'; document.getElementById('new-pixel-warning').style.display = 'block';
//get selected palette name //get selected palette name
var selectedPalette = getText('palette-button'); var selectedPalette = getText('palette-button');
if (selectedPalette == 'Choose a palette...') if (selectedPalette == 'Choose a palette...')
selectedPalette = 'none'; selectedPalette = 'none';
//track google event //track google event
ga('send', 'event', 'Pixel Editor New', selectedPalette, width+'/'+height); /*global ga*/ ga('send', 'event', 'Pixel Editor New', selectedPalette, width+'/'+height); /*global ga*/
//reset new form //reset new form
setValue('size-width', 64); setValue('size-width', 64);
setValue('size-height', 64); setValue('size-height', 64);
setText('palette-button', 'Choose a palette...'); setText('palette-button', 'Choose a palette...');
setText('preset-button', 'Choose a preset...'); setText('preset-button', 'Choose a preset...');
}); });

View File

@@ -1,45 +1,45 @@
function createColorPalette(selectedPalette, fillBackground) { function createColorPalette(selectedPalette, fillBackground) {
//remove current palette //remove current palette
colors = document.getElementsByClassName('color-button'); colors = document.getElementsByClassName('color-button');
while (colors.length > 0) { while (colors.length > 0) {
colors[0].parentElement.remove(); colors[0].parentElement.remove();
} }
var lightestColor = '#000000';
var darkestColor = '#ffffff';
for (var i = 0; i < selectedPalette.length; i++) {
var newColor = selectedPalette[i];
var newColorElement = addColor(newColor);
var newColorHex = hexToRgb(newColor); var lightestColor = '#000000';
var darkestColor = '#ffffff';
var lightestColorHex = hexToRgb(lightestColor); for (var i = 0; i < selectedPalette.length; i++) {
if (newColorHex.r + newColorHex.g + newColorHex.b > lightestColorHex.r + lightestColorHex.g + lightestColorHex.b) var newColor = selectedPalette[i];
lightestColor = newColor; var newColorElement = addColor(newColor);
var darkestColorHex = hexToRgb(darkestColor); var newColorHex = hexToRgb(newColor);
if (newColorHex.r + newColorHex.g + newColorHex.b < darkestColorHex.r + darkestColorHex.g + darkestColorHex.b) {
var lightestColorHex = hexToRgb(lightestColor);
//remove current color selection if (newColorHex.r + newColorHex.g + newColorHex.b > lightestColorHex.r + lightestColorHex.g + lightestColorHex.b)
var selectedColor = document.querySelector("#colors-menu li.selected") lightestColor = newColor;
if (selectedColor) selectedColor.classList.remove("selected");
var darkestColorHex = hexToRgb(darkestColor);
//set as current color if (newColorHex.r + newColorHex.g + newColorHex.b < darkestColorHex.r + darkestColorHex.g + darkestColorHex.b) {
newColorElement.classList.add('selected');
//remove current color selection
darkestColor = newColor; var selectedColor = document.querySelector('#colors-menu li.selected');
} if (selectedColor) selectedColor.classList.remove('selected');
} //set as current color
newColorElement.classList.add('selected');
//fill bg with lightest color
if (fillBackground) { darkestColor = newColor;
currentLayer.context.fillStyle = lightestColor; }
currentLayer.context.fillRect(0, 0, canvasSize[0], canvasSize[1]);
} }
//set as current color //fill bg with lightest color
currentLayer.context.fillStyle = darkestColor; if (fillBackground) {
} currentLayer.context.fillStyle = lightestColor;
currentLayer.context.fillRect(0, 0, canvasSize[0], canvasSize[1]);
}
//set as current color
currentLayer.context.fillStyle = darkestColor;
}

View File

@@ -3,82 +3,82 @@
//called when the delete button is pressed on color picker //called when the delete button is pressed on color picker
//input color button or hex string //input color button or hex string
function deleteColor (color) { function deleteColor (color) {
const logStyle = 'background: #913939; color: white; padding: 5px;'; const logStyle = 'background: #913939; color: white; padding: 5px;';
//console.log('%c'+'deleting color', logStyle);
//if color is a string, then find the corresponding button
if (typeof color === 'string') {
console.log('trying to find ',color)
//get all colors in palette
colors = document.getElementsByClassName('color-button');
//loop through colors
for (var i = 0; i < colors.length; i++) {
console.log(color,'=',colors[i].jscolor.toString())
if (color == colors[i].jscolor.toString()) {
console.log('match')
//set color to the color button
color = colors[i];
console.log('found color', color);
//exit loop
break;
}
}
//if the color wasn't found
if (typeof color === 'string') {
console.log('color not found');
//exit function
return;
}
}
//hide color picker
color.jscolor.hide();
//find lightest color in palette
var colors = document.getElementsByClassName('color-button');
var lightestColor = [0,null];
for (var i = 0; i < colors.length; i++) {
//get colors lightness
var lightness = rgbToHsl(colors[i].jscolor.toRgb()).l;
//console.log('%c'+lightness, logStyle)
//if not the color we're deleting
if (colors[i] != color) {
//if lighter than the current lightest, set as the new lightest
if (lightness > lightestColor[0]) {
lightestColor[0] = lightness;
lightestColor[1] = colors[i];
}
}
}
//console.log('%c'+'replacing with lightest color: '+lightestColor[1].jscolor.toString(), logStyle)
//replace deleted color with lightest color
replaceAllOfColor(color.jscolor.toString(),lightestColor[1].jscolor.toString());
//if the color you are deleting is the currently selected color
if (color.parentElement.classList.contains('selected')) {
//console.log('%c'+'deleted color is currently selected', logStyle);
//set current color TO LIGHTEST COLOR
lightestColor[1].parentElement.classList.add('selected');
currentLayer.context.fillStyle = '#'+lightestColor[1].jscolor.toString();
}
//delete the element
colorsMenu.removeChild(color.parentElement);
//console.log('%c'+'deleting color', logStyle);
}
//if color is a string, then find the corresponding button
if (typeof color === 'string') {
console.log('trying to find ',color);
//get all colors in palette
colors = document.getElementsByClassName('color-button');
//loop through colors
for (var i = 0; i < colors.length; i++) {
console.log(color,'=',colors[i].jscolor.toString());
if (color == colors[i].jscolor.toString()) {
console.log('match');
//set color to the color button
color = colors[i];
console.log('found color', color);
//exit loop
break;
}
}
//if the color wasn't found
if (typeof color === 'string') {
console.log('color not found');
//exit function
return;
}
}
//hide color picker
color.jscolor.hide();
//find lightest color in palette
var colors = document.getElementsByClassName('color-button');
var lightestColor = [0,null];
for (var i = 0; i < colors.length; i++) {
//get colors lightness
var lightness = rgbToHsl(colors[i].jscolor.toRgb()).l;
//console.log('%c'+lightness, logStyle)
//if not the color we're deleting
if (colors[i] != color) {
//if lighter than the current lightest, set as the new lightest
if (lightness > lightestColor[0]) {
lightestColor[0] = lightness;
lightestColor[1] = colors[i];
}
}
}
//console.log('%c'+'replacing with lightest color: '+lightestColor[1].jscolor.toString(), logStyle)
//replace deleted color with lightest color
replaceAllOfColor(color.jscolor.toString(),lightestColor[1].jscolor.toString());
//if the color you are deleting is the currently selected color
if (color.parentElement.classList.contains('selected')) {
//console.log('%c'+'deleted color is currently selected', logStyle);
//set current color TO LIGHTEST COLOR
lightestColor[1].parentElement.classList.add('selected');
currentLayer.context.fillStyle = '#'+lightestColor[1].jscolor.toString();
}
//delete the element
colorsMenu.removeChild(color.parentElement);
}

View File

@@ -1,36 +1,36 @@
function showDialogue (dialogueName, trackEvent) { function showDialogue (dialogueName, trackEvent) {
if (typeof trackEvent === 'undefined') trackEvent = true; if (typeof trackEvent === 'undefined') trackEvent = true;
dialogueOpen = true; dialogueOpen = true;
popUpContainer.style.display = 'block'; popUpContainer.style.display = 'block';
document.getElementById(dialogueName).style.display = 'block'; document.getElementById(dialogueName).style.display = 'block';
//track google event //track google event
if (trackEvent) if (trackEvent)
ga('send', 'event', 'Palette Editor Dialogue', dialogueName); /*global ga*/ ga('send', 'event', 'Palette Editor Dialogue', dialogueName); /*global ga*/
} }
function closeDialogue () { function closeDialogue () {
popUpContainer.style.display = 'none'; popUpContainer.style.display = 'none';
var popups = popUpContainer.children; var popups = popUpContainer.children;
for (var i = 0; i < popups.length; i++) { for (var i = 0; i < popups.length; i++) {
popups[i].style.display = 'none'; popups[i].style.display = 'none';
} }
dialogueOpen = false; dialogueOpen = false;
} }
popUpContainer.addEventListener("click", function (e) { popUpContainer.addEventListener('click', function (e) {
if (e.target == popUpContainer) if (e.target == popUpContainer)
closeDialogue(); closeDialogue();
}); });
//add click handlers for all cancel buttons //add click handlers for all cancel buttons
var cancelButtons = popUpContainer.getElementsByClassName('close-button'); var cancelButtons = popUpContainer.getElementsByClassName('close-button');
for (var i = 0; i < cancelButtons.length; i++) { for (var i = 0; i < cancelButtons.length; i++) {
cancelButtons[i].addEventListener('click', function () { cancelButtons[i].addEventListener('click', function () {
closeDialogue(); closeDialogue();
}); });
} }

View File

@@ -52,4 +52,4 @@ function lineOnLayer(x0,y0,x1,y1, brushSize, context) {
if (e2 >-dy) {err -=dy; x0+=sx;} if (e2 >-dy) {err -=dy; x0+=sx;}
if (e2 < dx) {err +=dx; y0+=sy;} if (e2 < dx) {err +=dx; y0+=sy;}
} }
} }

View File

@@ -1,18 +1,18 @@
var mainMenuItems = document.getElementById("main-menu").children; var mainMenuItems = document.getElementById('main-menu').children;
//for each button in main menu (starting at 1 to avoid logo) //for each button in main menu (starting at 1 to avoid logo)
for (var i = 1; i < mainMenuItems.length; i++) { for (var i = 1; i < mainMenuItems.length; i++) {
//get the button that's in the list item //get the button that's in the list item
var menuItem = mainMenuItems[i]; var menuItem = mainMenuItems[i];
var menuButton = menuItem.children[0]; var menuButton = menuItem.children[0];
console.log(mainMenuItems) console.log(mainMenuItems);
//when you click a main menu items button //when you click a main menu items button
on('click', menuButton, function (e, button) { on('click', menuButton, function (e, button) {
console.log('parent ', button.parentElement) console.log('parent ', button.parentElement);
select(button.parentElement); select(button.parentElement);
}); });
var subMenu = menuItem.children[1]; var subMenu = menuItem.children[1];
@@ -23,114 +23,114 @@ for (var i = 1; i < mainMenuItems.length; i++) {
//when you click an item within a menu button //when you click an item within a menu button
for (var j = 0; j < subMenuItems.length; j++) { for (var j = 0; j < subMenuItems.length; j++) {
var subMenuItem = subMenuItems[j]; var subMenuItem = subMenuItems[j];
var subMenuButton = subMenuItem.children[0]; var subMenuButton = subMenuItem.children[0];
subMenuButton.addEventListener("click", function (e) { subMenuButton.addEventListener('click', function (e) {
switch(this.textContent) { switch(this.textContent) {
//File Menu //File Menu
case 'New': case 'New':
showDialogue('new-pixel'); showDialogue('new-pixel');
break; break;
case 'Open': case 'Open':
//if a document exists //if a document exists
if (documentCreated) { if (documentCreated) {
//check if the user wants to overwrite //check if the user wants to overwrite
if (confirm('Opening a pixel will discard your current one. Are you sure you want to do that?')) if (confirm('Opening a pixel will discard your current one. Are you sure you want to do that?'))
//open file selection dialog //open file selection dialog
document.getElementById("open-image-browse-holder").click(); document.getElementById('open-image-browse-holder').click();
} }
else else
//open file selection dialog //open file selection dialog
document.getElementById("open-image-browse-holder").click(); document.getElementById('open-image-browse-holder').click();
break; break;
case 'Save as...': case 'Save as...':
if (documentCreated) { if (documentCreated) {
//create name //create name
var selectedPalette = getText('palette-button'); var selectedPalette = getText('palette-button');
if (selectedPalette != 'Choose a palette...'){ if (selectedPalette != 'Choose a palette...'){
var paletteAbbreviation = palettes[selectedPalette].abbreviation; var paletteAbbreviation = palettes[selectedPalette].abbreviation;
var fileName = 'pixel-'+paletteAbbreviation+'-'+canvasSize[0]+'x'+canvasSize[1]+'.png'; var fileName = 'pixel-'+paletteAbbreviation+'-'+canvasSize[0]+'x'+canvasSize[1]+'.png';
} else { } else {
var fileName = 'pixel-'+canvasSize[0]+'x'+canvasSize[1]+'.png'; var fileName = 'pixel-'+canvasSize[0]+'x'+canvasSize[1]+'.png';
selectedPalette = 'none'; selectedPalette = 'none';
} }
//set download link //set download link
var linkHolder = document.getElementById("save-image-link-holder"); var linkHolder = document.getElementById('save-image-link-holder');
linkHolder.href = canvas.toDataURL(); linkHolder.href = canvas.toDataURL();
linkHolder.download = fileName; linkHolder.download = fileName;
linkHolder.click(); linkHolder.click();
//track google event //track google event
ga('send', 'event', 'Pixel Editor Save', selectedPalette, canvasSize[0]+'/'+canvasSize[1]); /*global ga*/ ga('send', 'event', 'Pixel Editor Save', selectedPalette, canvasSize[0]+'/'+canvasSize[1]); /*global ga*/
} }
break; break;
case 'Exit': case 'Exit':
console.log('exit') console.log('exit');
//if a document exists, make sure they want to delete it //if a document exists, make sure they want to delete it
if (documentCreated) { if (documentCreated) {
//ask user if they want to leave //ask user if they want to leave
if (confirm('Exiting will discard your current pixel. Are you sure you want to do that?')) if (confirm('Exiting will discard your current pixel. Are you sure you want to do that?'))
//skip onbeforeunload prompt //skip onbeforeunload prompt
window.onbeforeunload = null; window.onbeforeunload = null;
else else
e.preventDefault(); e.preventDefault();
} }
break; break;
//Edit Menu //Edit Menu
case 'Undo': case 'Undo':
undo(); undo();
break; break;
case 'Redo': case 'Redo':
redo(); redo();
break; break;
//Palette Menu //Palette Menu
case 'Add color': case 'Add color':
addColor('#eeeeee'); addColor('#eeeeee');
break; break;
//Help Menu //Help Menu
case 'Settings': case 'Settings':
//fill form with current settings values //fill form with current settings values
setValue('setting-numberOfHistoryStates', settings.numberOfHistoryStates); setValue('setting-numberOfHistoryStates', settings.numberOfHistoryStates);
showDialogue('settings'); showDialogue('settings');
break; break;
//Help Menu //Help Menu
case 'Help': case 'Help':
showDialogue('help'); showDialogue('help');
break; break;
case 'About': case 'About':
showDialogue('about'); showDialogue('about');
break; break;
case 'Changelog': case 'Changelog':
showDialogue('changelog'); showDialogue('changelog');
break; break;
} }
closeMenu(); closeMenu();
}); });
} }
} }
function closeMenu () { function closeMenu () {
//remove .selected class from all menu buttons //remove .selected class from all menu buttons
for (var i = 0; i < mainMenuItems.length; i++) { for (var i = 0; i < mainMenuItems.length; i++) {
deselect(mainMenuItems[i]); deselect(mainMenuItems[i]);
} }
} }

View File

@@ -1,110 +1,110 @@
function fill(cursorLocation) { function fill(cursorLocation) {
//changes a pixels color
function colorPixel(tempImage, pixelPos, fillColor) {
//console.log('colorPixel:',pixelPos);
tempImage.data[pixelPos] = fillColor.r;
tempImage.data[pixelPos + 1] = fillColor.g;
tempImage.data[pixelPos + 2] = fillColor.b;
tempImage.data[pixelPos + 3] = 255;
/*
tempImage.data[pixelPos] = fillColor.r;
tempImage.data[pixelPos + 1] = fillColor.g;
tempImage.data[pixelPos + 2] = fillColor.b;
*/
}
//change x y to color value passed from the function and use that as the original color
function matchStartColor(tempImage, pixelPos, color) {
//console.log('matchPixel:',x,y)
var r = tempImage.data[pixelPos];
var g = tempImage.data[pixelPos + 1];
var b = tempImage.data[pixelPos + 2];
//console.log(r == color[0] && g == color[1] && b == color[2]);
return (r == color[0] && g == color[1] && b == color[2]);
}
//save history state
new HistoryStateEditCanvas();
//saveHistoryState({type: 'canvas', canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
//console.log('filling at '+ Math.floor(cursorLocation[0]/zoom) + ','+ Math.floor(cursorLocation[1]/zoom));
//temporary image holds the data while we change it //changes a pixels color
var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); function colorPixel(tempImage, pixelPos, fillColor) {
//console.log('colorPixel:',pixelPos);
tempImage.data[pixelPos] = fillColor.r;
tempImage.data[pixelPos + 1] = fillColor.g;
tempImage.data[pixelPos + 2] = fillColor.b;
tempImage.data[pixelPos + 3] = 255;
/*
tempImage.data[pixelPos] = fillColor.r;
tempImage.data[pixelPos + 1] = fillColor.g;
tempImage.data[pixelPos + 2] = fillColor.b;
*/
}
//this is an array that holds all of the pixels at the top of the cluster //change x y to color value passed from the function and use that as the original color
var topmostPixelsArray = [[Math.floor(cursorLocation[0]/zoom), Math.floor(cursorLocation[1]/zoom)]]; function matchStartColor(tempImage, pixelPos, color) {
//console.log('topmostPixelsArray:',topmostPixelsArray) //console.log('matchPixel:',x,y)
//the offset of the pixel in the temp image data to start with var r = tempImage.data[pixelPos];
var startingPosition = (topmostPixelsArray[0][1] * canvasSize[0] + topmostPixelsArray[0][0]) * 4; var g = tempImage.data[pixelPos + 1];
var b = tempImage.data[pixelPos + 2];
//console.log(r == color[0] && g == color[1] && b == color[2]);
return (r == color[0] && g == color[1] && b == color[2]);
}
//the color of the cluster that is being filled //save history state
var clusterColor = [tempImage.data[startingPosition],tempImage.data[startingPosition+1],tempImage.data[startingPosition+2]]; new HistoryStateEditCanvas();
//saveHistoryState({type: 'canvas', canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
//console.log('filling at '+ Math.floor(cursorLocation[0]/zoom) + ','+ Math.floor(cursorLocation[1]/zoom));
//the new color to fill with //temporary image holds the data while we change it
var fillColor = hexToRgb(currentLayer.context.fillStyle); var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
//if you try to fill with the same color that's already there, exit the function //this is an array that holds all of the pixels at the top of the cluster
if (clusterColor[0] == fillColor.r && var topmostPixelsArray = [[Math.floor(cursorLocation[0]/zoom), Math.floor(cursorLocation[1]/zoom)]];
clusterColor[1] == fillColor.g && //console.log('topmostPixelsArray:',topmostPixelsArray)
clusterColor[2] == fillColor.b )
return;
//loop until there are no more values left in this array //the offset of the pixel in the temp image data to start with
while (topmostPixelsArray.length) { var startingPosition = (topmostPixelsArray[0][1] * canvasSize[0] + topmostPixelsArray[0][0]) * 4;
var reachLeft, reachRight;
//move the most recent pixel from the array and set it as our current working pixels //the color of the cluster that is being filled
var currentPixel = topmostPixelsArray.pop(); var clusterColor = [tempImage.data[startingPosition],tempImage.data[startingPosition+1],tempImage.data[startingPosition+2]];
//set the values of this pixel to x/y variables just for readability //the new color to fill with
var x = currentPixel[0]; var fillColor = hexToRgb(currentLayer.context.fillStyle);
var y = currentPixel[1];
//this variable holds the index of where the starting values for the current pixel are in the data array //if you try to fill with the same color that's already there, exit the function
//we multiply the number of rows down (y) times the width of each row, then add x. at the end we multiply by 4 because if (clusterColor[0] == fillColor.r &&
//each pixel has 4 values, rgba clusterColor[1] == fillColor.g &&
var pixelPos = (y * canvasSize[0] + x) * 4; clusterColor[2] == fillColor.b )
return;
//move up in the image until you reach the top or the pixel you hit was not the right color //loop until there are no more values left in this array
while (y-- >= 0 && matchStartColor(tempImage, pixelPos, clusterColor)) { while (topmostPixelsArray.length) {
pixelPos -= canvasSize[0] * 4; var reachLeft, reachRight;
}
pixelPos += canvasSize[0] * 4;
++y;
reachLeft = false;
reachRight = false;
while (y++ < canvasSize[1] - 1 && matchStartColor(tempImage, pixelPos, clusterColor)) {
colorPixel(tempImage, pixelPos, fillColor);
if (x > 0) {
if (matchStartColor(tempImage, pixelPos - 4, clusterColor)) {
if (!reachLeft) {
topmostPixelsArray.push([x - 1, y]);
reachLeft = true;
}
}
else if (reachLeft) {
reachLeft = false;
}
}
if (x < canvasSize[0] - 1) { //move the most recent pixel from the array and set it as our current working pixels
if (matchStartColor(tempImage, pixelPos + 4, clusterColor)) { var currentPixel = topmostPixelsArray.pop();
if (!reachRight) {
topmostPixelsArray.push([x + 1, y]);
reachRight = true;
}
}
else if (reachRight) {
reachRight = false;
}
}
pixelPos += canvasSize[0] * 4; //set the values of this pixel to x/y variables just for readability
} var x = currentPixel[0];
} var y = currentPixel[1];
//this variable holds the index of where the starting values for the current pixel are in the data array
//we multiply the number of rows down (y) times the width of each row, then add x. at the end we multiply by 4 because
//each pixel has 4 values, rgba
var pixelPos = (y * canvasSize[0] + x) * 4;
//move up in the image until you reach the top or the pixel you hit was not the right color
while (y-- >= 0 && matchStartColor(tempImage, pixelPos, clusterColor)) {
pixelPos -= canvasSize[0] * 4;
}
pixelPos += canvasSize[0] * 4;
++y;
reachLeft = false;
reachRight = false;
while (y++ < canvasSize[1] - 1 && matchStartColor(tempImage, pixelPos, clusterColor)) {
colorPixel(tempImage, pixelPos, fillColor);
if (x > 0) {
if (matchStartColor(tempImage, pixelPos - 4, clusterColor)) {
if (!reachLeft) {
topmostPixelsArray.push([x - 1, y]);
reachLeft = true;
}
}
else if (reachLeft) {
reachLeft = false;
}
}
if (x < canvasSize[0] - 1) {
if (matchStartColor(tempImage, pixelPos + 4, clusterColor)) {
if (!reachRight) {
topmostPixelsArray.push([x + 1, y]);
reachRight = true;
}
}
else if (reachRight) {
reachRight = false;
}
}
pixelPos += canvasSize[0] * 4;
}
}
currentLayer.context.putImageData(tempImage, 0, 0); currentLayer.context.putImageData(tempImage, 0, 0);
//console.log('done filling') //console.log('done filling')
} }

View File

@@ -1,21 +1,21 @@
//get cursor position relative to canvas //get cursor position relative to canvas
function getCursorPosition(e) { function getCursorPosition(e) {
var x; var x;
var y; var y;
if (e.pageX != undefined && e.pageY != undefined) { if (e.pageX != undefined && e.pageY != undefined) {
x = e.pageX; x = e.pageX;
y = e.pageY; y = e.pageY;
} }
else { else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
} }
x -= canvas.offsetLeft; x -= canvas.offsetLeft;
y -= canvas.offsetTop; y -= canvas.offsetTop;
return [x,y]; return [x,y];
} }
// TODO: apply the function below to every getCursorPosition call // TODO: apply the function below to every getCursorPosition call
@@ -24,20 +24,20 @@ function getCursorPosition(e) {
//get cursor position relative to canvas //get cursor position relative to canvas
function getCursorPositionRelative(e, layer) { function getCursorPositionRelative(e, layer) {
var x; var x;
var y; var y;
if (e.pageX != undefined && e.pageY != undefined) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= layer.canvas.offsetLeft; if (e.pageX != undefined && e.pageY != undefined) {
y -= layer.canvas.offsetTop; x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return [x,y]; x -= layer.canvas.offsetLeft;
} y -= layer.canvas.offsetTop;
return [x,y];
}

View File

@@ -5,194 +5,194 @@ const undoLogStyle = 'background: #87ff1c; color: black; padding: 5px;';
//prototype for undoing canvas changes //prototype for undoing canvas changes
function HistoryStateEditCanvas () { function HistoryStateEditCanvas () {
this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
this.undo = function () { this.undo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
this.canvas = currentCanvas; this.canvas = currentCanvas;
redoStates.push(this); redoStates.push(this);
} };
this.redo = function () { this.redo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
this.canvas = currentCanvas; this.canvas = currentCanvas;
undoStates.push(this); undoStates.push(this);
} };
//add self to undo array //add self to undo array
saveHistoryState(this); saveHistoryState(this);
} }
//prototype for undoing added colors //prototype for undoing added colors
function HistoryStateAddColor (colorValue) { function HistoryStateAddColor (colorValue) {
this.colorValue = colorValue; this.colorValue = colorValue;
this.undo = function () { this.undo = function () {
redoStates.push(this); redoStates.push(this);
deleteColor(this.colorValue); deleteColor(this.colorValue);
} };
this.redo = function () { this.redo = function () {
addColor(this.colorValue); addColor(this.colorValue);
undoStates.push(this); undoStates.push(this);
} };
//add self to undo array //add self to undo array
saveHistoryState(this); saveHistoryState(this);
} }
//prototype for undoing deleted colors //prototype for undoing deleted colors
function HistoryStateDeleteColor (colorValue) { function HistoryStateDeleteColor (colorValue) {
this.colorValue = colorValue; this.colorValue = colorValue;
this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
this.undo = function () { this.undo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
addColor(this.colorValue); addColor(this.colorValue);
this.canvas = currentCanvas; this.canvas = currentCanvas;
redoStates.push(this); redoStates.push(this);
} };
this.redo = function () { this.redo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
deleteColor(this.colorValue); deleteColor(this.colorValue);
this.canvas = currentCanvas; this.canvas = currentCanvas;
undoStates.push(this); undoStates.push(this);
} };
//add self to undo array //add self to undo array
saveHistoryState(this); saveHistoryState(this);
} }
//prototype for undoing colors edits //prototype for undoing colors edits
function HistoryStateEditColor (newColorValue, oldColorValue) { function HistoryStateEditColor (newColorValue, oldColorValue) {
this.newColorValue = newColorValue; this.newColorValue = newColorValue;
this.oldColorValue = oldColorValue; this.oldColorValue = oldColorValue;
this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); this.canvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
this.undo = function () { this.undo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
//find new color in palette and change it back to old color //find new color in palette and change it back to old color
var colors = document.getElementsByClassName('color-button'); var colors = document.getElementsByClassName('color-button');
for (var i = 0; i < colors.length; i++) { for (var i = 0; i < colors.length; i++) {
console.log(newColorValue, '==', colors[i].jscolor.toString()) console.log(newColorValue, '==', colors[i].jscolor.toString());
if (newColorValue == colors[i].jscolor.toString()) { if (newColorValue == colors[i].jscolor.toString()) {
colors[i].jscolor.fromString(oldColorValue); colors[i].jscolor.fromString(oldColorValue);
break; break;
} }
} }
this.canvas = currentCanvas; this.canvas = currentCanvas;
redoStates.push(this); redoStates.push(this);
} };
this.redo = function () { this.redo = function () {
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
currentLayer.context.putImageData(this.canvas, 0, 0); currentLayer.context.putImageData(this.canvas, 0, 0);
//find old color in palette and change it back to new color //find old color in palette and change it back to new color
var colors = document.getElementsByClassName('color-button'); var colors = document.getElementsByClassName('color-button');
for (var i = 0; i < colors.length; i++) { for (var i = 0; i < colors.length; i++) {
console.log(oldColorValue, '==', colors[i].jscolor.toString()) console.log(oldColorValue, '==', colors[i].jscolor.toString());
if (oldColorValue == colors[i].jscolor.toString()) { if (oldColorValue == colors[i].jscolor.toString()) {
colors[i].jscolor.fromString(newColorValue); colors[i].jscolor.fromString(newColorValue);
break; break;
} }
} }
this.canvas = currentCanvas; this.canvas = currentCanvas;
undoStates.push(this); undoStates.push(this);
} };
//add self to undo array //add self to undo array
saveHistoryState(this); saveHistoryState(this);
} }
//rename to add undo state //rename to add undo state
function saveHistoryState (state) { function saveHistoryState (state) {
console.log('%csaving history state', undoLogStyle) console.log('%csaving history state', undoLogStyle);
console.log(state) console.log(state);
//get current canvas data and save to undoStates array //get current canvas data and save to undoStates array
undoStates.push(state); undoStates.push(state);
//limit the number of states to settings.numberOfHistoryStates //limit the number of states to settings.numberOfHistoryStates
if (undoStates.length > settings.numberOfHistoryStates) { if (undoStates.length > settings.numberOfHistoryStates) {
undoStates = undoStates.splice(-settings.numberOfHistoryStates, settings.numberOfHistoryStates); undoStates = undoStates.splice(-settings.numberOfHistoryStates, settings.numberOfHistoryStates);
} }
//there is now definitely at least 1 undo state, so the button shouldnt be disabled //there is now definitely at least 1 undo state, so the button shouldnt be disabled
document.getElementById('undo-button').classList.remove('disabled'); document.getElementById('undo-button').classList.remove('disabled');
//there should be no redoStates after an undoState is saved //there should be no redoStates after an undoState is saved
redoStates = []; redoStates = [];
console.log(undoStates) console.log(undoStates);
console.log(redoStates) console.log(redoStates);
} }
function undo () { function undo () {
console.log('%cundo', undoLogStyle); console.log('%cundo', undoLogStyle);
//if there are any states saved to undo
if (undoStates.length > 0) {
document.getElementById('redo-button').classList.remove('disabled'); //if there are any states saved to undo
if (undoStates.length > 0) {
//get state
var undoState = undoStates[undoStates.length-1]; document.getElementById('redo-button').classList.remove('disabled');
console.log(undoState);
//get state
//restore the state var undoState = undoStates[undoStates.length-1];
undoState.undo(); console.log(undoState);
//remove from the undo list //restore the state
undoStates.splice(undoStates.length-1,1); undoState.undo();
//if theres none left to undo, disable the option //remove from the undo list
if (undoStates.length == 0) undoStates.splice(undoStates.length-1,1);
document.getElementById('undo-button').classList.add('disabled');
} //if theres none left to undo, disable the option
if (undoStates.length == 0)
console.log(undoStates) document.getElementById('undo-button').classList.add('disabled');
console.log(redoStates) }
console.log(undoStates);
console.log(redoStates);
} }
function redo () { function redo () {
console.log('%credo', undoLogStyle); console.log('%credo', undoLogStyle);
if (redoStates.length > 0) { if (redoStates.length > 0) {
//enable undo button //enable undo button
document.getElementById('undo-button').classList.remove('disabled'); document.getElementById('undo-button').classList.remove('disabled');
//get state //get state
var redoState = redoStates[redoStates.length-1]; var redoState = redoStates[redoStates.length-1];
console.log(redoState); console.log(redoState);
//restore the state //restore the state
redoState.redo(); redoState.redo();
//remove from redo array //remove from redo array
redoStates.splice(redoStates.length-1,1); redoStates.splice(redoStates.length-1,1);
//if theres none left to redo, disable the option //if theres none left to redo, disable the option
if (redoStates.length == 0) if (redoStates.length == 0)
document.getElementById('redo-button').classList.add('disabled'); document.getElementById('redo-button').classList.add('disabled');
} }
console.log(undoStates) console.log(undoStates);
console.log(redoStates) console.log(redoStates);
} }

View File

@@ -1,15 +1,15 @@
var spacePressed = false; var spacePressed = false;
function KeyPress(e) { function KeyPress(e) {
var keyboardEvent = window.event? event : e; var keyboardEvent = window.event? event : e;
//if the user is typing in an input field, ignore these hotkeys //if the user is typing in an input field, ignore these hotkeys
if (document.activeElement.tagName == 'INPUT') return; if (document.activeElement.tagName == 'INPUT') return;
//if no document has been created yet, //if no document has been created yet,
//orthere is a dialog box open //orthere is a dialog box open
//ignore hotkeys //ignore hotkeys
if (!documentCreated || dialogueOpen) return; if (!documentCreated || dialogueOpen) return;
// //
if (e.key === "Escape") { if (e.key === "Escape") {

View File

@@ -1,23 +1,23 @@
//format a color button //format a color button
function initColor (colorElement) { function initColor (colorElement) {
//console.log('initColor()'); //console.log('initColor()');
//console.log(document.getElementById('jscolor-hex-input')) //console.log(document.getElementById('jscolor-hex-input'))
//add jscolor picker for this color //add jscolor picker for this color
colorElement.jscolor = new jscolor(colorElement.parentElement, { colorElement.jscolor = new jscolor(colorElement.parentElement, {
valueElement: null, //if you dont set this to null, it turns the button (colorElement) into text, we set it when you open the picker valueElement: null, //if you dont set this to null, it turns the button (colorElement) into text, we set it when you open the picker
styleElement: colorElement, styleElement: colorElement,
width:151, width:151,
position: 'left', position: 'left',
padding:0, padding:0,
borderWidth:14, borderWidth:14,
borderColor: '#332f35', borderColor: '#332f35',
backgroundColor: '#332f35', backgroundColor: '#332f35',
insetColor: 'transparent', insetColor: 'transparent',
value: colorElement.style.backgroundColor, value: colorElement.style.backgroundColor,
deleteButton: true, deleteButton: true,
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@@ -15,9 +15,9 @@
* @param canvas HTML canvas element * @param canvas HTML canvas element
*/ */
function Layer(width, height, canvas) { function Layer(width, height, canvas) {
this.canvasSize = [width, height], this.canvasSize = [width, height];
this.canvas = canvas, this.canvas = canvas;
this.context = this.canvas.getContext("2d"), this.context = this.canvas.getContext('2d');
// Initializes the canvas // Initializes the canvas
this.initialize = function() { this.initialize = function() {
var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75); var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75);
@@ -38,10 +38,10 @@ function Layer(width, height, canvas) {
//center canvas in window //center canvas in window
this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px'; this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px';
this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px'; this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px';
this.context.imageSmoothingEnabled = false; this.context.imageSmoothingEnabled = false;
this.context.mozImageSmoothingEnabled = false; this.context.mozImageSmoothingEnabled = false;
}, };
// Resizes canvas // Resizes canvas
this.resize = function() { this.resize = function() {
let newWidth = (this.canvas.width * zoom) + 'px'; let newWidth = (this.canvas.width * zoom) + 'px';
@@ -49,7 +49,7 @@ function Layer(width, height, canvas) {
this.canvas.style.width = newWidth; this.canvas.style.width = newWidth;
this.canvas.style.height = newHeight; this.canvas.style.height = newHeight;
}, };
// Copies the otherCanvas' position and size // Copies the otherCanvas' position and size
this.copyData = function(otherCanvas) { this.copyData = function(otherCanvas) {
this.canvas.style.width = otherCanvas.canvas.style.width; this.canvas.style.width = otherCanvas.canvas.style.width;
@@ -57,5 +57,5 @@ function Layer(width, height, canvas) {
this.canvas.style.left = otherCanvas.canvas.style.left; this.canvas.style.left = otherCanvas.canvas.style.left;
this.canvas.style.top = otherCanvas.canvas.style.top; this.canvas.style.top = otherCanvas.canvas.style.top;
} };
} }

View File

@@ -1,61 +1,61 @@
document.getElementById('open-image-browse-holder').addEventListener('change', function () { document.getElementById('open-image-browse-holder').addEventListener('change', function () {
if (this.files && this.files[0]) { if (this.files && this.files[0]) {
//make sure file is allowed filetype
var fileContentType = this.files[0].type;
if (fileContentType == 'image/png' || fileContentType == 'image/gif') {
//load file
var fileReader = new FileReader();
fileReader.onload = function(e) {
var img = new Image();
img.onload = function() {
//create a new pixel with the images dimentions
newPixel(this.width, this.height, []);
//draw the image onto the canvas
currentLayer.context.drawImage(img, 0, 0);
var colorPalette = {};
var imagePixelData = currentLayer.context.getImageData(0,0,this.width, this.height).data;
var imagePixelDataLength = imagePixelData.length;
console.log(imagePixelData)
for (var i = 0; i < imagePixelDataLength; i += 4) {
var color = imagePixelData[i]+','+imagePixelData[i + 1]+','+imagePixelData[i + 2];
if (!colorPalette[color]) {
colorPalette[color] = {r:imagePixelData[i],g:imagePixelData[i + 1],b:imagePixelData[i + 2]};
//don't allow more than 256 colors to be added
if (Object.keys(colorPalette).length >= settings.maxColorsOnImportedImage) {
alert('The image loaded seems to have more than '+settings.maxColorsOnImportedImage+' colors.')
break;
}
}
}
//create array out of colors object
var colorPaletteArray = [];
for (var color in colorPalette) {
if( colorPalette.hasOwnProperty(color) ) {
colorPaletteArray.push('#'+rgbToHex(colorPalette[color]));
}
}
console.log('COLOR PALETTE ARRAY', colorPaletteArray)
//create palette form colors array
createColorPalette(colorPaletteArray, false);
//track google event
ga('send', 'event', 'Pixel Editor Load', colorPalette.length, this.width+'/'+this.height); /*global ga*/
}; //make sure file is allowed filetype
img.src = e.target.result; var fileContentType = this.files[0].type;
}; if (fileContentType == 'image/png' || fileContentType == 'image/gif') {
fileReader.readAsDataURL(this.files[0]);
} //load file
else alert('Only PNG and GIF files are allowed at this time.'); var fileReader = new FileReader();
} fileReader.onload = function(e) {
}); var img = new Image();
img.onload = function() {
//create a new pixel with the images dimentions
newPixel(this.width, this.height, []);
//draw the image onto the canvas
currentLayer.context.drawImage(img, 0, 0);
var colorPalette = {};
var imagePixelData = currentLayer.context.getImageData(0,0,this.width, this.height).data;
var imagePixelDataLength = imagePixelData.length;
console.log(imagePixelData);
for (var i = 0; i < imagePixelDataLength; i += 4) {
var color = imagePixelData[i]+','+imagePixelData[i + 1]+','+imagePixelData[i + 2];
if (!colorPalette[color]) {
colorPalette[color] = {r:imagePixelData[i],g:imagePixelData[i + 1],b:imagePixelData[i + 2]};
//don't allow more than 256 colors to be added
if (Object.keys(colorPalette).length >= settings.maxColorsOnImportedImage) {
alert('The image loaded seems to have more than '+settings.maxColorsOnImportedImage+' colors.');
break;
}
}
}
//create array out of colors object
var colorPaletteArray = [];
for (var color in colorPalette) {
if( colorPalette.hasOwnProperty(color) ) {
colorPaletteArray.push('#'+rgbToHex(colorPalette[color]));
}
}
console.log('COLOR PALETTE ARRAY', colorPaletteArray);
//create palette form colors array
createColorPalette(colorPaletteArray, false);
//track google event
ga('send', 'event', 'Pixel Editor Load', colorPalette.length, this.width+'/'+this.height); /*global ga*/
};
img.src = e.target.result;
};
fileReader.readAsDataURL(this.files[0]);
}
else alert('Only PNG and GIF files are allowed at this time.');
}
});

View File

@@ -1,50 +1,50 @@
//this is called when a user picks a file after selecting "load palette" from the new pixel dialogue //this is called when a user picks a file after selecting "load palette" from the new pixel dialogue
document.getElementById('load-palette-browse-holder').addEventListener('change', function () { document.getElementById('load-palette-browse-holder').addEventListener('change', function () {
if (this.files && this.files[0]) { if (this.files && this.files[0]) {
//make sure file is allowed filetype //make sure file is allowed filetype
var fileContentType = this.files[0].type; var fileContentType = this.files[0].type;
if (fileContentType == 'image/png' || fileContentType == 'image/gif') { if (fileContentType == 'image/png' || fileContentType == 'image/gif') {
//load file //load file
var fileReader = new FileReader(); var fileReader = new FileReader();
fileReader.onload = function(e) { fileReader.onload = function(e) {
var img = new Image(); var img = new Image();
img.onload = function() { img.onload = function() {
//draw image onto the temporary canvas //draw image onto the temporary canvas
var loadPaletteCanvas = document.getElementById("load-palette-canvas-holder"); var loadPaletteCanvas = document.getElementById('load-palette-canvas-holder');
var loadPaletteContext = loadPaletteCanvas.getContext("2d"); var loadPaletteContext = loadPaletteCanvas.getContext('2d');
loadPaletteCanvas.width = img.width; loadPaletteCanvas.width = img.width;
loadPaletteCanvas.height = img.height; loadPaletteCanvas.height = img.height;
loadPaletteContext.drawImage(img, 0, 0); loadPaletteContext.drawImage(img, 0, 0);
//create array to hold found colors //create array to hold found colors
var colorPalette = []; var colorPalette = [];
var imagePixelData = loadPaletteContext.getImageData(0,0,this.width, this.height).data; var imagePixelData = loadPaletteContext.getImageData(0,0,this.width, this.height).data;
console.log(imagePixelData) console.log(imagePixelData);
//loop through pixels looking for colors to add to palette //loop through pixels looking for colors to add to palette
for (var i = 0; i < imagePixelData.length; i += 4) { for (var i = 0; i < imagePixelData.length; i += 4) {
var color = '#'+rgbToHex(imagePixelData[i],imagePixelData[i + 1],imagePixelData[i + 2]); var color = '#'+rgbToHex(imagePixelData[i],imagePixelData[i + 1],imagePixelData[i + 2]);
if (colorPalette.indexOf(color) == -1) { if (colorPalette.indexOf(color) == -1) {
colorPalette.push(color); colorPalette.push(color);
} }
} }
//add to palettes so that it can be loaded when they click okay //add to palettes so that it can be loaded when they click okay
palettes['Loaded palette'] = {}; palettes['Loaded palette'] = {};
palettes['Loaded palette'].colors = colorPalette; palettes['Loaded palette'].colors = colorPalette;
setText('palette-button', 'Loaded palette'); setText('palette-button', 'Loaded palette');
}; };
img.src = e.target.result; img.src = e.target.result;
}; };
fileReader.readAsDataURL(this.files[0]); fileReader.readAsDataURL(this.files[0]);
} }
else alert('Only PNG and GIF files are supported at this time.'); else alert('Only PNG and GIF files are supported at this time.');
} }
}); });

View File

@@ -118,14 +118,35 @@ window.addEventListener("mouseup", function (mouseEvent) {
if (mouseEvent.which == 1){ if (mouseEvent.which == 1){
mode = "in"; mode = "in";
} }
else if (mouseEvent.which == 3){ }
mode = "out"; else if (currentTool == 'fill' && mouseEvent.target.className == 'drawingCanvas') {
console.log('filling');
//if you clicked on anything but the canvas, do nothing
if (!mouseEvent.target == currentLayer.canvas) return;
//get cursor postion
var cursorLocation = getCursorPosition(mouseEvent);
//offset to match cursor point
cursorLocation[0] += 2;
cursorLocation[1] += 12;
//fill starting at the location
fill(cursorLocation);
}
else if (currentTool == 'zoom' && mouseEvent.target.className == 'drawingCanvas') {
let mode;
if (mouseEvent.which == 1){
mode = 'in';
}
else if (mouseEvent.which == 3){
mode = 'out';
} }
changeZoom(layers[0], mode, getCursorPosition(mouseEvent)); changeZoom(layers[0], mode, getCursorPosition(mouseEvent));
for (let i=1; i<layers.length; i++) { for (let i=1; i<layers.length; i++) {
layers[i].copyData(layers[0]); layers[i].copyData(layers[0]);
} }
} }
else if (currentTool.name == 'rectselect' && isRectSelecting) { else if (currentTool.name == 'rectselect' && isRectSelecting) {
@@ -143,6 +164,19 @@ window.addEventListener("mouseup", function (mouseEvent) {
}, false); }, false);
function setPreviewPosition(preview, cursor, size){
preview.style.left = (
currentLayer.canvas.offsetLeft
+ Math.floor(cursor[0]/zoom) * zoom
- Math.floor(size / 2) * zoom
) + 'px';
preview.style.top = (
currentLayer.canvas.offsetTop
+ Math.floor(cursor[1]/zoom) * zoom
- Math.floor(size / 2) * zoom
) + 'px';
}
// OPTIMIZABLE: redundant || mouseEvent.target.className in currentTool ifs // OPTIMIZABLE: redundant || mouseEvent.target.className in currentTool ifs
@@ -231,7 +265,7 @@ function draw (mouseEvent) {
else if (currentTool.name == 'pan' && dragging) { else if (currentTool.name == 'pan' && dragging) {
// Setting first layer position // Setting first layer position
setCanvasOffset(layers[0].canvas, layers[0].canvas.offsetLeft + (cursorLocation[0] - lastPos[0]), layers[0].canvas.offsetTop + (cursorLocation[1] - lastPos[1])); setCanvasOffset(layers[0].canvas, layers[0].canvas.offsetLeft + (cursorLocation[0] - lastPos[0]), layers[0].canvas.offsetTop + (cursorLocation[1] - lastPos[1]));
// Copying that position to the other layers // Copying that position to the other layers
for (let i=1; i<layers.length; i++) { for (let i=1; i<layers.length; i++) {
layers[i].copyData(layers[0]); layers[i].copyData(layers[0]);
} }
@@ -248,8 +282,8 @@ function draw (mouseEvent) {
var colorLightness = Math.max(selectedColor[0],selectedColor[1],selectedColor[2]); var colorLightness = Math.max(selectedColor[0],selectedColor[1],selectedColor[2]);
//for the darkest 50% of colors, change the eyedropper preview to dark mode //for the darkest 50% of colors, change the eyedropper preview to dark mode
if (colorLightness>127) eyedropperPreview.classList.remove('dark'); if (colorLightness>127) eyedropperPreview.classList.remove('dark');
else eyedropperPreview.classList.add('dark'); else eyedropperPreview.classList.add('dark');
} }
else if (currentTool.name == 'resizebrush' && dragging) { else if (currentTool.name == 'resizebrush' && dragging) {
//get new brush size based on x distance from original clicking location //get new brush size based on x distance from original clicking location
@@ -319,10 +353,10 @@ function draw (mouseEvent) {
// Updating the cursor (move if inside rect, cross if not) // Updating the cursor (move if inside rect, cross if not)
currentTool.updateCursor(); currentTool.updateCursor();
// If I'm dragging, I move the preview // If I'm dragging, I move the preview
if (dragging && cursorInSelectedArea()) { if (dragging && cursorInSelectedArea()) {
updateMovePreview(mouseEvent); updateMovePreview(mouseEvent);
} }
} }
} }
@@ -334,17 +368,17 @@ canvasView.addEventListener("wheel", function(mouseEvent){
if (mouseEvent.deltaY < 0){ if (mouseEvent.deltaY < 0){
mode = 'in'; mode = 'in';
} }
else if (mouseEvent.deltaY > 0) { else if (mouseEvent.deltaY > 0) {
mode = 'out'; mode = 'out';
} }
// Changing zoom and position of the first layer // Changing zoom and position of the first layer
changeZoom(layers[0], mode, getCursorPosition(mouseEvent)) changeZoom(layers[0], mode, getCursorPosition(mouseEvent));
for (let i=1; i<layers.length; i++) { for (let i=1; i<layers.length; i++) {
// Copying first layer's data into the other layers // Copying first layer's data into the other layers
layers[i].copyData(layers[0]); layers[i].copyData(layers[0]);
} }
} }
}); });

View File

@@ -7,66 +7,66 @@ var firstTimeMove = true;
// TODO: move with arrows // TODO: move with arrows
function updateMovePreview(mouseEvent) { function updateMovePreview(mouseEvent) {
// ISSUE // ISSUE
selectionCanceled = false; selectionCanceled = false;
if (firstTimeMove) { if (firstTimeMove) {
cutSelection(mouseEvent); cutSelection(mouseEvent);
} }
firstTimeMove = false; firstTimeMove = false;
lastMousePos = getCursorPosition(mouseEvent); lastMousePos = getCursorPosition(mouseEvent);
// clear the entire tmp layer // clear the entire tmp layer
TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height);
// put the image data with offset // put the image data with offset
TMPLayer.context.putImageData( TMPLayer.context.putImageData(
imageDataToMove, imageDataToMove,
Math.round(lastMousePos[0] / zoom - imageDataToMove.width / 2), Math.round(lastMousePos[0] / zoom - imageDataToMove.width / 2),
Math.round(lastMousePos[1] / zoom - imageDataToMove.height / 2)); Math.round(lastMousePos[1] / zoom - imageDataToMove.height / 2));
lastMovePos = lastMousePos; lastMovePos = lastMousePos;
moveSelection(lastMousePos[0] / zoom, lastMousePos[1] / zoom, imageDataToMove.width, imageDataToMove.height) moveSelection(lastMousePos[0] / zoom, lastMousePos[1] / zoom, imageDataToMove.width, imageDataToMove.height);
} }
function endSelection() { function endSelection() {
TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height);
VFXLayer.context.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height); VFXLayer.context.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height);
if (imageDataToMove !== undefined) { if (imageDataToMove !== undefined) {
let underlyingImageData = currentLayer.context.getImageData(startX, startY, endX - startX, endY - startY); let underlyingImageData = currentLayer.context.getImageData(startX, startY, endX - startX, endY - startY);
for (let i=0; i<underlyingImageData.data.length; i+=4) { for (let i=0; i<underlyingImageData.data.length; i+=4) {
let currentMovePixel = [ let currentMovePixel = [
imageDataToMove.data[i], imageDataToMove.data[i+1], imageDataToMove.data[i], imageDataToMove.data[i+1],
imageDataToMove.data[i+2], imageDataToMove.data[i+3] imageDataToMove.data[i+2], imageDataToMove.data[i+3]
]; ];
let currentUnderlyingPixel = [ let currentUnderlyingPixel = [
underlyingImageData.data[i], underlyingImageData.data[i+1], underlyingImageData.data[i], underlyingImageData.data[i+1],
underlyingImageData.data[i+2], underlyingImageData.data[i+3] underlyingImageData.data[i+2], underlyingImageData.data[i+3]
]; ];
if (isPixelEmpty(currentMovePixel)) { if (isPixelEmpty(currentMovePixel)) {
if (!isPixelEmpty(underlyingImageData)) { if (!isPixelEmpty(underlyingImageData)) {
imageDataToMove.data[i] = currentUnderlyingPixel[0]; imageDataToMove.data[i] = currentUnderlyingPixel[0];
imageDataToMove.data[i+1] = currentUnderlyingPixel[1]; imageDataToMove.data[i+1] = currentUnderlyingPixel[1];
imageDataToMove.data[i+2] = currentUnderlyingPixel[2]; imageDataToMove.data[i+2] = currentUnderlyingPixel[2];
imageDataToMove.data[i+3] = currentUnderlyingPixel[3]; imageDataToMove.data[i+3] = currentUnderlyingPixel[3];
} }
} }
} }
if (lastMovePos !== undefined) { if (lastMovePos !== undefined) {
currentLayer.context.putImageData( currentLayer.context.putImageData(
imageDataToMove, imageDataToMove,
Math.round(lastMovePos[0] / zoom - imageDataToMove.width / 2), Math.round(lastMovePos[0] / zoom - imageDataToMove.width / 2),
Math.round(lastMovePos[1] / zoom - imageDataToMove.height / 2)); Math.round(lastMovePos[1] / zoom - imageDataToMove.height / 2));
} }
} }
selectionCanceled = true; selectionCanceled = true;
isRectSelecting = false; isRectSelecting = false;
firstTimeMove = true; firstTimeMove = true;
imageDataToMove = undefined; imageDataToMove = undefined;
} }

View File

@@ -1,5 +1,5 @@
function newPixel (width, height, palette) { function newPixel (width, height, palette) {
// Setting the current layer // Setting the current layer
currentLayer = new Layer(width, height, canvas); currentLayer = new Layer(width, height, canvas);
currentLayer.initialize(); currentLayer.initialize();
@@ -80,4 +80,4 @@ function newPixel (width, height, palette) {
document.getElementById('save-as-button').classList.remove('disabled'); document.getElementById('save-as-button').classList.remove('disabled');
documentCreated = true; documentCreated = true;
} }

View File

@@ -9,4 +9,4 @@ window.onload = function(){
else else
//otherwise show the new pixel dialog //otherwise show the new pixel dialog
showDialogue('new-pixel', false); showDialogue('new-pixel', false);
}; };

View File

@@ -1,7 +1,7 @@
//prevent user from leaving page with unsaved data //prevent user from leaving page with unsaved data
window.onbeforeunload = function() { window.onbeforeunload = function() {
if (documentCreated) if (documentCreated)
return 'You will lose your pixel if it\'s not saved!'; return 'You will lose your pixel if it\'s not saved!';
else return; else return;
} };

View File

@@ -1,62 +1,62 @@
//populate palettes list in new pixel menu //populate palettes list in new pixel menu
Object.keys(palettes).forEach(function(paletteName,index) { Object.keys(palettes).forEach(function(paletteName,index) {
var palettesMenu = document.getElementById("palette-menu"); var palettesMenu = document.getElementById('palette-menu');
//create button //create button
var button = document.createElement("button"); var button = document.createElement('button');
button.appendChild(document.createTextNode(paletteName)); button.appendChild(document.createTextNode(paletteName));
//insert new element
palettesMenu.appendChild(button);
//if the palette was specified by the user, change the dropdown to it
if (palettes[paletteName].specified == true) {
setText('palette-button', paletteName);
//Show empty palette option
document.getElementById('no-palette-button').style.display = 'block';
}
on('click', button, function() { //insert new element
palettesMenu.appendChild(button);
//hide the dropdown menu //if the palette was specified by the user, change the dropdown to it
deselect('palette-menu'); if (palettes[paletteName].specified == true) {
deselect('palette-button'); setText('palette-button', paletteName);
//Show empty palette option
//show empty palette option document.getElementById('no-palette-button').style.display = 'block';
document.getElementById('no-palette-button').style.display = 'block'; }
//set the text of the dropdown to the newly selected preset on('click', button, function() {
setText('palette-button', paletteName);
}); //hide the dropdown menu
deselect('palette-menu');
deselect('palette-button');
//show empty palette option
document.getElementById('no-palette-button').style.display = 'block';
//set the text of the dropdown to the newly selected preset
setText('palette-button', paletteName);
});
}); });
//select no palette //select no palette
on('click', 'no-palette-button', function () { on('click', 'no-palette-button', function () {
document.getElementById('no-palette-button').style.display = 'none'; document.getElementById('no-palette-button').style.display = 'none';
setText('palette-button', 'Choose a palette...'); setText('palette-button', 'Choose a palette...');
}); });
//select load palette //select load palette
on('click', 'load-palette-button', function () { on('click', 'load-palette-button', function () {
document.getElementById("load-palette-browse-holder").click(); document.getElementById('load-palette-browse-holder').click();
}); });
on('click', 'palette-button', function (e){ on('click', 'palette-button', function (e){
toggle('palette-button'); toggle('palette-button');
toggle('palette-menu'); toggle('palette-menu');
deselect('preset-button'); deselect('preset-button');
deselect('preset-menu'); deselect('preset-menu');
e.stopPropagation(); e.stopPropagation();
}); });
on('click', 'new-pixel', function (){ on('click', 'new-pixel', function (){
deselect('preset-button'); deselect('preset-button');
deselect('preset-menu'); deselect('preset-menu');
deselect('palette-button'); deselect('palette-button');
deselect('palette-menu'); deselect('palette-menu');
}); });

View File

@@ -1,7 +1,7 @@
function isPixelEmpty(pixel) { function isPixelEmpty(pixel) {
if ((pixel[0] == 0 && pixel[1] == 0 && pixel[2] == 0) || pixel[3] == 0) { if ((pixel[0] == 0 && pixel[1] == 0 && pixel[2] == 0) || pixel[3] == 0) {
return true; return true;
} }
return false; return false;
} }

View File

@@ -1,64 +1,64 @@
//prests //prests
var presets = { var presets = {
'Gameboy Color': { 'Gameboy Color': {
width: 240, width: 240,
height: 203, height: 203,
palette: 'Gameboy Color' palette: 'Gameboy Color'
}, },
'PICO-8': { 'PICO-8': {
width: 128, width: 128,
height: 128, height: 128,
palette: 'PICO-8', palette: 'PICO-8',
}, },
'Commodore 64': { 'Commodore 64': {
width: 40, width: 40,
height: 80, height: 80,
palette: 'Commodore 64' palette: 'Commodore 64'
} }
}; };
//populate preset list in new pixel menu //populate preset list in new pixel menu
Object.keys(presets).forEach(function(presetName,index) { Object.keys(presets).forEach(function(presetName,index) {
var presetsMenu = document.getElementById("preset-menu"); var presetsMenu = document.getElementById('preset-menu');
//create button //create button
var button = document.createElement("button"); var button = document.createElement('button');
button.appendChild(document.createTextNode(presetName)); button.appendChild(document.createTextNode(presetName));
//insert new element
presetsMenu.appendChild(button);
//add click event listener
on('click', button, function() {
//change dimentions on new pixel form //insert new element
setValue('size-width', presets[presetName].width); presetsMenu.appendChild(button);
setValue('size-height', presets[presetName].height);
//set the text of the dropdown to the newly selected preset //add click event listener
setText('palette-button', presets[presetName].palette); on('click', button, function() {
//hide the dropdown menu //change dimentions on new pixel form
deselect('preset-menu'); setValue('size-width', presets[presetName].width);
deselect('preset-button'); setValue('size-height', presets[presetName].height);
//set the text of the dropdown to the newly selected preset //set the text of the dropdown to the newly selected preset
setText('preset-button', presetName); setText('palette-button', presets[presetName].palette);
});
//hide the dropdown menu
deselect('preset-menu');
deselect('preset-button');
//set the text of the dropdown to the newly selected preset
setText('preset-button', presetName);
});
}); });
on('click', 'preset-button', function (e){ on('click', 'preset-button', function (e){
//open or close the preset menu //open or close the preset menu
toggle('preset-button'); toggle('preset-button');
toggle('preset-menu'); toggle('preset-menu');
//close the palette menu //close the palette menu
deselect('palette-button'); deselect('palette-button');
deselect('palette-menu'); deselect('palette-menu');
//stop the click from propogating to the parent element //stop the click from propogating to the parent element
e.stopPropagation(); e.stopPropagation();
}); });

View File

@@ -5,34 +5,34 @@ let endX;
let endY; let endY;
function startRectSelection(mouseEvent) { function startRectSelection(mouseEvent) {
// Saving the canvas // Saving the canvas
new HistoryStateEditCanvas(); new HistoryStateEditCanvas();
// Putting the vfx layer on top of everything // Putting the vfx layer on top of everything
VFXCanvas.style.zIndex = MAX_Z_INDEX; VFXCanvas.style.zIndex = MAX_Z_INDEX;
// Saving the start coords of the rect // Saving the start coords of the rect
let cursorPos = getCursorPosition(mouseEvent); let cursorPos = getCursorPosition(mouseEvent);
startX = Math.round(cursorPos[0] / zoom) - 0.5; startX = Math.round(cursorPos[0] / zoom) - 0.5;
startY = Math.round(cursorPos[1] / zoom) - 0.5; startY = Math.round(cursorPos[1] / zoom) - 0.5;
// Avoiding external selections // Avoiding external selections
if (startX < 0) { if (startX < 0) {
startX = 0; startX = 0;
} }
else if (startX > currentLayer.canvas.width) { else if (startX > currentLayer.canvas.width) {
startX = currentLayer.canvas.width; startX = currentLayer.canvas.width;
} }
if (startY < 0) { if (startY < 0) {
startY = 0; startY = 0;
} }
else if (startY > currentLayer.canvas.height) { else if (startY > currentLayer.canvas.height) {
startY = currentLayer.canvas.height; startY = currentLayer.canvas.height;
} }
// Drawing the rect // Drawing the rect
drawRect(startX, startY); drawRect(startX, startY);
selectionCanceled = false; selectionCanceled = false;
} }
function updateRectSelection(mouseEvent) { function updateRectSelection(mouseEvent) {
@@ -81,71 +81,71 @@ function cutSelection(mouseEvent) {
// Moving those pixels from the current layer to the tmp layer // Moving those pixels from the current layer to the tmp layer
TMPLayer.context.putImageData(imageDataToMove, startX + 1, startY); TMPLayer.context.putImageData(imageDataToMove, startX + 1, startY);
//originalDataPosition = [currentPos[0], currentPos[1]]; //originalDataPosition = [currentPos[0], currentPos[1]];
} }
function drawRect(x, y) { function drawRect(x, y) {
// Getting the vfx context // Getting the vfx context
let vfxContext = VFXCanvas.getContext("2d"); let vfxContext = VFXCanvas.getContext('2d');
// Clearing the vfx canvas // Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height); vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
vfxContext.lineWidth = 1; vfxContext.lineWidth = 1;
vfxContext.strokeStyle = "black"; vfxContext.strokeStyle = 'black';
vfxContext.setLineDash([4]); vfxContext.setLineDash([4]);
// Drawing the rect // Drawing the rect
vfxContext.beginPath(); vfxContext.beginPath();
vfxContext.rect(startX, startY, x - startX, y - startY); vfxContext.rect(startX, startY, x - startX, y - startY);
vfxContext.stroke(); vfxContext.stroke();
// TODO: make the rect blink from black to white in case of dark backgrounds // TODO: make the rect blink from black to white in case of dark backgrounds
} }
function applyChanges() { function applyChanges() {
VFXCanvas.style.zIndex = MIN_Z_INDEX; VFXCanvas.style.zIndex = MIN_Z_INDEX;
} }
// Checks whether the pointer is inside the selected area or not // Checks whether the pointer is inside the selected area or not
function cursorInSelectedArea() { function cursorInSelectedArea() {
let cursorPos = getCursorPosition(currentMouseEvent); let cursorPos = getCursorPosition(currentMouseEvent);
let x = cursorPos[0] / zoom; let x = cursorPos[0] / zoom;
let y = cursorPos[1] / zoom; let y = cursorPos[1] / zoom;
let leftX = Math.min(startX, endX); let leftX = Math.min(startX, endX);
let rightX = Math.max(startX, endX); let rightX = Math.max(startX, endX);
let topY = Math.max(startY, endY); let topY = Math.max(startY, endY);
let bottomY = Math.min(startY, endY); let bottomY = Math.min(startY, endY);
if (leftX <= x && x <= rightX) { if (leftX <= x && x <= rightX) {
if (bottomY <= y && y <= topY) { if (bottomY <= y && y <= topY) {
return true; return true;
} }
return false; return false;
} }
return false; return false;
} }
function moveSelection(x, y, width, height) { function moveSelection(x, y, width, height) {
// Getting the vfx context // Getting the vfx context
let vfxContext = VFXCanvas.getContext("2d"); let vfxContext = VFXCanvas.getContext('2d');
// Clearing the vfx canvas // Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height); vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
vfxContext.lineWidth = 1; vfxContext.lineWidth = 1;
vfxContext.setLineDash([4]); vfxContext.setLineDash([4]);
startX = Math.round(Math.round(x) - Math.round(width / 2)) + 0.5; startX = Math.round(Math.round(x) - Math.round(width / 2)) + 0.5;
startY = Math.round(Math.round(y) - Math.round(height / 2)) + 0.5; startY = Math.round(Math.round(y) - Math.round(height / 2)) + 0.5;
endX = startX + Math.round(width); endX = startX + Math.round(width);
endY = startY + Math.round(height); endY = startY + Math.round(height);
// Drawing the rect // Drawing the rect
vfxContext.beginPath(); vfxContext.beginPath();
vfxContext.rect(startX, startY, width, height); vfxContext.rect(startX, startY, width, height);
vfxContext.stroke(); vfxContext.stroke();
} }

View File

@@ -12,17 +12,17 @@ let endRectY;
function startRectDrawing(mouseEvent) { function startRectDrawing(mouseEvent) {
// Putting the vfx layer on top of everything // Putting the vfx layer on top of everything
VFXCanvas.style.zIndex = MAX_Z_INDEX; VFXCanvas.style.zIndex = MAX_Z_INDEX;
// Updating flag // Updating flag
isDrawingRect = true; isDrawingRect = true;
// Saving the start coords of the rect // Saving the start coords of the rect
let cursorPos = getCursorPosition(mouseEvent); let cursorPos = getCursorPosition(mouseEvent);
startRectX = Math.round(cursorPos[0] / zoom) - 0.5; startRectX = Math.floor(cursorPos[0] / zoom) + 0.5;
startRectY = Math.round(cursorPos[1] / zoom) - 0.5; startRectY = Math.floor(cursorPos[1] / zoom) + 0.5;
drawRectangle(startRectX, startRectY); drawRectangle(startRectX, startRectY);
} }
function updateRectDrawing(mouseEvent) { function updateRectDrawing(mouseEvent) {
@@ -101,20 +101,20 @@ function drawRectangle(x, y) {
vfxContext.setLineDash([]); vfxContext.setLineDash([]);
vfxContext.stroke(); vfxContext.stroke();
} }
function setRectToolSvg() { function setRectToolSvg() {
if (drawMode == 'empty') { if (drawMode == 'empty') {
emptySVG.setAttribute("display", "visible"); emptySVG.setAttribute('display', 'visible');
fullSVG.setAttribute("display", "none"); fullSVG.setAttribute('display', 'none');
} }
else { else {
emptySVG.setAttribute("display", "none"); emptySVG.setAttribute('display', 'none');
fullSVG.setAttribute("display", "visible"); fullSVG.setAttribute('display', 'visible');
} }
} }
function applyChanges() { function applyChanges() {
VFXCanvas.style.zIndex = MIN_Z_INDEX; VFXCanvas.style.zIndex = MIN_Z_INDEX;
} }

View File

@@ -1,25 +1,25 @@
//replaces all of a single color on the canvas with a different color //replaces all of a single color on the canvas with a different color
//input two rgb color objects {r:0,g:0,b:0} //input two rgb color objects {r:0,g:0,b:0}
function replaceAllOfColor (oldColor, newColor) { function replaceAllOfColor (oldColor, newColor) {
//convert strings to objects if nessesary //convert strings to objects if nessesary
if (typeof oldColor === 'string') oldColor = hexToRgb(oldColor); if (typeof oldColor === 'string') oldColor = hexToRgb(oldColor);
if (typeof newColor === 'string') newColor = hexToRgb(newColor); if (typeof newColor === 'string') newColor = hexToRgb(newColor);
//create temporary image from canvas to search through //create temporary image from canvas to search through
var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]); var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
//loop through all pixels //loop through all pixels
for (var i=0;i<tempImage.data.length;i+=4) { for (var i=0;i<tempImage.data.length;i+=4) {
//check if pixel matches old color //check if pixel matches old color
if(tempImage.data[i]==oldColor.r && tempImage.data[i+1]==oldColor.g && tempImage.data[i+2]==oldColor.b){ if(tempImage.data[i]==oldColor.r && tempImage.data[i+1]==oldColor.g && tempImage.data[i+2]==oldColor.b){
//change to new color //change to new color
tempImage.data[i]=newColor.r; tempImage.data[i]=newColor.r;
tempImage.data[i+1]=newColor.g; tempImage.data[i+1]=newColor.g;
tempImage.data[i+2]=newColor.b; tempImage.data[i+2]=newColor.b;
} }
} }
//put temp image back onto canvas //put temp image back onto canvas
currentLayer.context.putImageData(tempImage,0,0); currentLayer.context.putImageData(tempImage,0,0);
} }

View File

@@ -1,23 +1,23 @@
function setCanvasOffset (canvas, offsetLeft, offsetTop) { function setCanvasOffset (canvas, offsetLeft, offsetTop) {
//horizontal offset //horizontal offset
var minXOffset = -canvasSize[0]*zoom+ 164; var minXOffset = -canvasSize[0]*zoom+ 164;
var maxXOffset = window.innerWidth - 148; var maxXOffset = window.innerWidth - 148;
if (offsetLeft < minXOffset) if (offsetLeft < minXOffset)
canvas.style.left = minXOffset +'px'; canvas.style.left = minXOffset +'px';
else if (offsetLeft > maxXOffset) else if (offsetLeft > maxXOffset)
canvas.style.left = maxXOffset +'px'; canvas.style.left = maxXOffset +'px';
else else
canvas.style.left = offsetLeft +'px'; canvas.style.left = offsetLeft +'px';
//vertical offset //vertical offset
var minYOffset = -canvasSize[1]*zoom + 164; var minYOffset = -canvasSize[1]*zoom + 164;
var maxYOffset = window.innerHeight-100; var maxYOffset = window.innerHeight-100;
if (offsetTop < minYOffset) if (offsetTop < minYOffset)
canvas.style.top = minYOffset +'px'; canvas.style.top = minYOffset +'px';
else if (offsetTop > maxYOffset) else if (offsetTop > maxYOffset)
canvas.style.top = maxYOffset +'px'; canvas.style.top = maxYOffset +'px';
else else
canvas.style.top = offsetTop +'px'; canvas.style.top = offsetTop +'px';
} }

View File

@@ -1,45 +1,45 @@
var settings; var settings;
if (!Cookies.enabled) { if (!Cookies.enabled) {
document.getElementById('cookies-disabled-warning').style.display = 'block'; document.getElementById('cookies-disabled-warning').style.display = 'block';
} }
//try to load settings from cookie //try to load settings from cookie
var settingsFromCookie = Cookies.get('pixelEditorSettings'); var settingsFromCookie = Cookies.get('pixelEditorSettings');
if(!settingsFromCookie) { if(!settingsFromCookie) {
console.log('settings cookie not found') console.log('settings cookie not found');
settings = { settings = {
switchToChangedColor: true, switchToChangedColor: true,
enableDynamicCursorOutline: true, //unused - performance enableDynamicCursorOutline: true, //unused - performance
enableBrushPreview: true, //unused - performance enableBrushPreview: true, //unused - performance
enableEyedropperPreview: true, //unused - performance enableEyedropperPreview: true, //unused - performance
numberOfHistoryStates: 20, numberOfHistoryStates: 20,
maxColorsOnImportedImage: 128 maxColorsOnImportedImage: 128
}; };
} }
else{ else{
console.log('settings cookie found'); console.log('settings cookie found');
console.log(settingsFromCookie); console.log(settingsFromCookie);
var settings = JSON.parse(settingsFromCookie); var settings = JSON.parse(settingsFromCookie);
} }
console.log(settings); console.log(settings);
//on clicking the save button in the settings dialog //on clicking the save button in the settings dialog
on('click', 'save-settings', function (){ on('click', 'save-settings', function (){
//check if values are valid
if (isNaN(getValue('setting-numberOfHistoryStates'))) {
alert('Invalid value for numberOfHistoryStates')
return;
}
//save new settings to settings object //check if values are valid
settings.numberOfHistoryStates = getValue('setting-numberOfHistoryStates'); if (isNaN(getValue('setting-numberOfHistoryStates'))) {
alert('Invalid value for numberOfHistoryStates');
//save settings object to cookie return;
var cookieValue = JSON.stringify(settings); }
Cookies.set('pixelEditorSettings', cookieValue, { expires: Infinity });
//save new settings to settings object
//close window settings.numberOfHistoryStates = getValue('setting-numberOfHistoryStates');
closeDialogue();
}); //save settings object to cookie
var cookieValue = JSON.stringify(settings);
Cookies.set('pixelEditorSettings', cookieValue, { expires: Infinity });
//close window
closeDialogue();
});

View File

@@ -31,7 +31,7 @@ on('click',"eraser-smaller-button", function(e){
}, false); }, false);
// rectangle // rectangle
on('click',"rectangle-button", function(){ on('click','rectangle-button', function(){
// If the user clicks twice on the button, they change the draw mode // If the user clicks twice on the button, they change the draw mode
if (currentTool.name == 'rectangle') { if (currentTool.name == 'rectangle') {
if (drawMode == 'empty') { if (drawMode == 'empty') {
@@ -80,8 +80,8 @@ on('click',"zoom-button", function(){
}, false); }, false);
//zoom in button //zoom in button
on('click',"zoom-in-button", function(){ on('click','zoom-in-button', function(){
//changeZoom('in',[window.innerWidth/2-canvas.offsetLeft,window.innerHeight/2-canvas.offsetTop]); //changeZoom('in',[window.innerWidth/2-canvas.offsetLeft,window.innerHeight/2-canvas.offsetTop]);
changeZoom(layers[0],'in', [canvasSize[0] * zoom / 2, canvasSize[1] * zoom / 2]); changeZoom(layers[0],'in', [canvasSize[0] * zoom / 2, canvasSize[1] * zoom / 2]);
for (let i=1; i<layers.length; i++) { for (let i=1; i<layers.length; i++) {
@@ -90,7 +90,7 @@ on('click',"zoom-in-button", function(){
}, false); }, false);
//zoom out button //zoom out button
on('click',"zoom-out-button", function(){ on('click','zoom-out-button', function(){
changeZoom(layers[0],'out',[canvasSize[0]*zoom/2,canvasSize[1]*zoom/2]); changeZoom(layers[0],'out',[canvasSize[0]*zoom/2,canvasSize[1]*zoom/2]);
for (let i=1; i<layers.length; i++) { for (let i=1; i<layers.length; i++) {
@@ -103,4 +103,4 @@ on('click', "rectselect-button", function(){
tool.rectselect.switchTo(); tool.rectselect.switchTo();
}, false); }, false);
/*global on */ /*global on */

View File

@@ -33,4 +33,4 @@ Tool.prototype.updateCursor = function () {
} }
} }
/*global Tool, dragging, canvasView, brushPreview, canMoveSelection, cursorInSelectedArea, eyedropperPreview, zoom, currentTool */ /*global Tool, dragging, canvasView, brushPreview, canMoveSelection, cursorInSelectedArea, eyedropperPreview, zoom, currentTool */

View File

@@ -13,7 +13,7 @@ var secondCheckerBoardColor = 'rgba(204, 200, 206, 1)';
// Square size for the checkerboard // Square size for the checkerboard
var checkerBoardSquareSize = 16; var checkerBoardSquareSize = 16;
// Checkerboard canvas // Checkerboard canvas
var checkerBoardCanvas = document.getElementById("checkerboard"); var checkerBoardCanvas = document.getElementById('checkerboard');
//common elements //common elements
var brushPreview = document.getElementById("brush-preview"); var brushPreview = document.getElementById("brush-preview");
@@ -24,8 +24,8 @@ var colorsMenu = document.getElementById("colors-menu");
var popUpContainer = document.getElementById("pop-up-container"); var popUpContainer = document.getElementById("pop-up-container");
// main canvas // main canvas
var canvas = document.getElementById("pixel-canvas"); var canvas = document.getElementById('pixel-canvas');
var context = canvas.getContext("2d"); var context = canvas.getContext('2d');
var currentGlobalColor; var currentGlobalColor;
// Layers // Layers
@@ -36,9 +36,9 @@ var currentLayer;
// VFX layer used to draw previews of the selection and things like that // VFX layer used to draw previews of the selection and things like that
var VFXLayer; var VFXLayer;
// VFX canvas // VFX canvas
var VFXCanvas = document.getElementById("vfx-canvas"); var VFXCanvas = document.getElementById('vfx-canvas');
// TMP layer // TMP layer
var TMPLayer; var TMPLayer;
// TMP canvas // TMP canvas
var TMPCanvas = document.getElementById("tmp-canvas"); var TMPCanvas = document.getElementById('tmp-canvas');

2813
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,21 +4,22 @@
"description": "Online pixel art creation tool", "description": "Online pixel art creation tool",
"main": "build.js", "main": "build.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "build": "node ./build.js ./build",
"serve": "node ./server.js ./build 3000",
"test": "npm run build && npm run serve"
}, },
"author": "Lospec", "author": "Lospec",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.16.4", "express": "^4.16.4",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"glob": "^7.1.3", "gulp": "^4.0.2",
"gulp": "^4.0.0", "gulp-hb": "^8.0.0",
"gulp-include": "^2.3.1", "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": "git+https://bitbucket.org/skeddles/npm-handlebars-helper-svg-lospec-open-source.git",
"hbs": "^4.0.3", "open": "^6.0.0",
"hbs-register-helpers": "git+https://skeddles@bitbucket.org/skeddles/hbs-register-helpers.git",
"hbs-register-partials": "git+https://skeddles@bitbucket.org/skeddles/hbs-register-partials.git",
"opn": "^6.0.0",
"sass": "^1.17.3" "sass": "^1.17.3"
} }
} }

37
server.js Normal file
View File

@@ -0,0 +1,37 @@
const path = require('path');
const express = require('express');
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 {
setTimeout(()=>{
console.log('closing server');
server.close();
process.exit();
},1000*10);
}
});
});
//ROUTE - other files
app.use(express.static(path.join(__dirname, BUILDDIR)));
//start server
var server = app.listen(PORT, () => {
console.log(`\nTemp server started at http://localhost:${PORT}!`);
//console.log('press ctrl+c to stop ');
var opn = require('open');
// opens the url in the default browser
opn(`http://localhost:${PORT}`);
});