This commit is contained in:
pxlvxl 2022-02-25 09:49:30 -05:00
parent ca32746d48
commit 012f96ae8d
24 changed files with 139 additions and 71 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ build
node_modules
.idea
.history
*.css
*.map

30
file_copier.js Normal file
View File

@ -0,0 +1,30 @@
const fs = require('fs');
const fileArr = walk("./",n => !n.includes("node_modules")
&& !n.includes(".git")
&& !n.includes(".vscode")
&& !n.includes("build")
);
const destPath = `C:/Users/jaman/OneDrive/Documents/GitHub/pixel-editor/`;
console.log('fileArr === ',fileArr);
fileArr.forEach(pathStr=>{
const fileStr = fs.readFileSync(pathStr, "utf8");
const destFilePathStr = destPath + pathStr;
console.log('destFilePathStr, fileStr.length === ',destFilePathStr, fileStr.length);
fs.writeFileSync(destFilePathStr, fileStr);
})
function walk(dir, condition = () => true ) {
// console.log('dir === ',dir);
let results = [];
for (let file of fs.readdirSync(dir)) {
file = dir + '/' + file;
const stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
results = results.concat(walk(file, condition));
} else {
if(condition(file))results.push(file);
}
}
return results;
}

View File

@ -148,6 +148,18 @@ const FileManager = (() => {
]
}));
}
function defaultLPE(w,h,colors) {
return {
"canvasWidth":w,
"canvasHeight":h,
"editorMode":"Advanced",
colors,
"selectedLayer":0,
"layers":[
{"canvas":{},"context":{"mozImageSmoothingEnabled":false},"isSelected":true,"isVisible":true,"isLocked":false,"oldLayerName":null,"menuEntry":{},"id":"layer0","name":"Layer 0","src":emptyCanvasSrc(w,h)}
]
};
}
function localStorageLoad() {
////console.log("loading from localStorage");
////console.log('JSON.parse(localStorage.getItem("lpe-cache") ?? "{}") === ',JSON.parse(localStorage.getItem("lpe-cache") ?? "{}"));
@ -185,7 +197,10 @@ const FileManager = (() => {
img.onload = function() {
//create a new pixel with the images dimentions
Startup.newPixel(this.width, this.height);
Startup.newPixel({
canvasWidth: this.width,
canvasHeight: this.height
});
EditorState.switchMode('Advanced');
//draw the image onto the canvas
@ -218,7 +233,7 @@ const FileManager = (() => {
}
function _parseLPE(dictionary) {
Startup.newPixel(dictionary['canvasWidth'], dictionary['canvasHeight'], dictionary, true);
Startup.newPixel(dictionary, true);
}
}
function loadFromLPE(dictionary) {
@ -361,20 +376,42 @@ const FileManager = (() => {
}
return dictionary;
}
function emptyCanvasSrc(w,h) {
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
return canvas.toDataURL();
}
function toggleCache(elm){
console.log('elm === ',elm);
FileManager.cacheEnabled = !FileManager.cacheEnabled;
localStorage.setItem("lpe-cache-enabled",FileManager.cacheEnabled ? "1" : "0");
elm.textContent = cacheBtnText(FileManager.cacheEnabled);
}
function cacheBtnText(cacheEnabled) {
return `${cacheEnabled ? "Disable" : "Enable"} auto-cache`;
}
const cacheEnabled = !!Number(localStorage.getItem("lpe-cache-enabled"));
document.getElementById("auto-cache-button").textContent = cacheBtnText(cacheEnabled);
return {
cacheEnabled,
loadFromLPE,
toggleCache,
getProjectData,
localStorageReset,
localStorageCheck,
localStorageSave,
localStorageLoad,
upgradeLPE,
defaultLPE,
saveProject,
openProject,
exportProject,
openPixelExportWindow,
openSaveProjectWindow,
open
}
};
})();

View File

@ -71,7 +71,7 @@ const LayerList = (() => {
// Basically "if I'm not adding a layer because redo() is telling meto do so", then I can save the history
if (saveHistory) {
new HistoryState().AddLayer(newLayer, index);
FileManager.localStorageSave();
if(FileManager.cacheEnabled)FileManager.localStorageSave();
}
return newLayer;
@ -155,7 +155,7 @@ const LayerList = (() => {
currFile.layers[i].isSelected = i===selectedIdx;
});
FileManager.localStorageSave();
if(FileManager.cacheEnabled)FileManager.localStorageSave();
}
/** Saves the layer that is being moved when the dragging starts

View File

@ -17,10 +17,7 @@ const Startup = (() => {
var height = Util.getValue('size-height' + splashPostfix);
var selectedPalette = Util.getText('palette-button' + splashPostfix);
newPixel({
canvasWidth: width,
canvasHeight: height,
});
newPixel(FileManager.defaultLPE(width,height));
resetInput();
//track google event
@ -34,8 +31,8 @@ const Startup = (() => {
* @param {*} skipModeConfirm If skipModeConfirm == true, then the mode switching confirmation will be skipped
*/
function newPixel (fileContent = null, skipModeConfirm = false) {
//console.log('called newPixel');
//console.trace();
console.log('called newPixel');
console.trace();
// The palette is empty, at the beginning
ColorModule.resetPalette();
@ -75,14 +72,14 @@ const Startup = (() => {
//console.group('called initLayers');
//console.log('currFile.layers === ',currFile.layers);
const width = lpe.canvasWidth;
const height = lpe.canvasHeight;
const width = lpe.canvasWidth = Number(lpe.canvasWidth);
const height = lpe.canvasHeight = Number(lpe.canvasHeight);
clearLayers();
// debugger;
//
currFile.canvasSize = [width, height];
console.log('lpe === ',lpe);
if( lpe.layers && lpe.layers.length ) {
currFile.currentLayer = new Layer(width, height, `pixel-canvas`,"","layer-li-template");
currFile.currentLayer.canvas.style.zIndex = 2;
@ -215,7 +212,8 @@ const Startup = (() => {
x = presetProperties.width;
y = presetProperties.height;
}
newPixel(x, y);
newPixel(FileManager.defaultLPE(x,y));
}
function splashEditorMode(mode) {

View File

@ -162,6 +162,6 @@ class Tool {
onEnd(mousePos, mouseTarget) {
this.endMousePos = mousePos;
FileManager.localStorageSave();
if(FileManager.cacheEnabled)FileManager.localStorageSave();
}
}

View File

@ -247,7 +247,7 @@ class Layer {
this.menuEntry.classList.add("selected-layer");
currFile.currentLayer = this;
FileManager.localStorageSave();
if(FileManager.cacheEnabled)FileManager.localStorageSave();
}
toggleLock() {

View File

@ -77,6 +77,9 @@ window.onload = function () {
ToolManager.currentTool().updateCursor();
// Apply checkboxes
////console.log('window.location.pathname === ',window.location.pathname);
////console.log('window.location === ',window.location);
let args = window.location.pathname.split('/');
let paletteSlug = args[2];
let dimensions = args[3];
@ -93,22 +96,29 @@ window.onload = function () {
//palette loaded successfully
palettes[paletteSlug] = data;
palettes[paletteSlug].specified = true;
////console.log('palettes[paletteSlug] === ',palettes[paletteSlug]);
//refresh list of palettes
document.getElementById('palette-menu-splash').refresh();
console.log('paletteSlug === ',paletteSlug);
console.log('dimensions === ',dimensions);
//if the dimensions were specified
if (dimensions && dimensions.length >= 3 && dimensions.includes('x')) {
let width = dimensions.split('x')[0];
let height = dimensions.split('x')[1];
const layers = [];
let selectedLayer;
Startup.newPixel({
canvasWidth: width,
canvasHeight: height,
selectedLayer,
colors: data.colors.map(n=>"#"+n),
layers
});
let selectedLayer = 0;
// if(prefill && prefillWidth){ // TODO
// layers.push({
// id: "layer0",
// name: "Layer 0",
// prefillWidth,
// prefill
// });
// selectedLayer = 0;
// }
let _lpe = FileManager.defaultLPE(width, height, (data.colors ?? []).map(n=>"#"+n));
console.log('_lpe === ',_lpe);
Startup.newPixel(_lpe);
}
//dimensions were not specified -- show splash screen with palette preselected
else {
@ -123,7 +133,7 @@ window.onload = function () {
Dialogue.showDialogue('splash', false);
});
} else {
if(FileManager.localStorageCheck()) {
if(FileManager.cacheEnabled && FileManager.localStorageCheck()) {
//load cached document
const lpe = FileManager.localStorageLoad();

View File

@ -12,7 +12,7 @@ class BrushTool extends ResizableTool {
this.addTutorialKey("Left drag", " to draw a stroke");
this.addTutorialKey("Right drag", " to resize the brush");
this.addTutorialKey("+ or -", " to resize the brush");
this.addTutorialImg("/images/ToolTutorials/brush-tutorial.gif");
this.addTutorialImg("/brush-tutorial.gif");
}
onStart(mousePos, cursorTarget) {

View File

@ -25,7 +25,7 @@ class EllipseTool extends ResizableTool {
this.addTutorialKey("Left drag", " to draw an ellipse");
this.addTutorialKey("Right drag", " to resize the brush");
this.addTutorialKey("+ or -", " to resize the brush");
this.addTutorialImg("/images/ToolTutorials/ellipse-tutorial.gif");
this.addTutorialImg("/ellipse-tutorial.gif");
}
changeFillType() {

View File

@ -12,7 +12,7 @@ class EraserTool extends ResizableTool {
this.addTutorialKey("Left drag", " to erase an area");
this.addTutorialKey("Right drag", " to resize the eraser");
this.addTutorialKey("+ or -", " to resize the eraser");
this.addTutorialImg("/images/ToolTutorials/eraser-tutorial.gif");
this.addTutorialImg("/eraser-tutorial.gif");
}
onStart(mousePos) {

View File

@ -14,7 +14,7 @@ class EyeDropperTool extends Tool {
this.addTutorialKey("Aòt + left drag", " to preview the picked colour");
this.addTutorialKey("Left click", " to select a colour");
this.addTutorialKey("Alt + click", " to select a colour");
this.addTutorialImg("/images/ToolTutorials/eyedropper-tutorial.gif");
this.addTutorialImg("/eyedropper-tutorial.gif");
}
onStart(mousePos, target) {

View File

@ -8,7 +8,7 @@ class FillTool extends DrawingTool {
this.addTutorialTitle("Fill tool");
this.addTutorialKey("F", " to select the fill tool");
this.addTutorialKey("Left click", " to fill a contiguous area");
this.addTutorialImg("/images/ToolTutorials/fill-tutorial.gif");
this.addTutorialImg("/fill-tutorial.gif");
}
onStart(mousePos, target) {

View File

@ -15,7 +15,7 @@ class LassoSelectionTool extends SelectionTool {
this.addTutorialKey("CTRL+C", " to copy a selection")
this.addTutorialKey("CTRL+V", " to paste a selection")
this.addTutorialKey("CTRL+X", " to cut a selection")
this.addTutorialImg("/images/ToolTutorials/lassoselect-tutorial.gif");
this.addTutorialImg("/lassoselect-tutorial.gif");
}
onStart(mousePos, mouseTarget) {

View File

@ -12,7 +12,7 @@ class LineTool extends ResizableTool {
this.addTutorialKey("Left drag", " to draw a line");
this.addTutorialKey("Right drag", " to resize the brush");
this.addTutorialKey("+ or -", " to resize the brush");
this.addTutorialImg("/images/ToolTutorials/line-tutorial.gif");
this.addTutorialImg("/line-tutorial.gif");
}
onStart(mousePos) {

View File

@ -13,7 +13,7 @@ class MagicWandTool extends SelectionTool {
this.addTutorialKey("CTRL+C", " to copy a selection");
this.addTutorialKey("CTRL+V", " to paste a selection");
this.addTutorialKey("CTRL+X", " to cut a selection");
this.addTutorialImg("/images/ToolTutorials/magicwand-tutorial.gif");
this.addTutorialImg("/magicwand-tutorial.gif");
}
onEnd(mousePos, mouseTarget) {

View File

@ -10,7 +10,7 @@ class PanTool extends Tool {
this.addTutorialKey("P", " to select the lasso selection tool");
this.addTutorialKey("Left drag", " to move the viewport");
this.addTutorialKey("Space + drag", " to move the viewport");
this.addTutorialImg("/images/ToolTutorials/pan-tutorial.gif");
this.addTutorialImg("/pan-tutorial.gif");
}
onStart(mousePos, target) {

View File

@ -23,7 +23,7 @@ class RectangleTool extends ResizableTool {
this.addTutorialKey("Left drag", " to draw a rectangle");
this.addTutorialKey("Right drag", " to resize the brush");
this.addTutorialKey("+ or -", " to resize the brush");
this.addTutorialImg("/images/ToolTutorials/rectangle-tutorial.gif");
this.addTutorialImg("/rectangle-tutorial.gif");
}
changeFillType() {

View File

@ -14,7 +14,7 @@ class RectangularSelectionTool extends SelectionTool {
this.addTutorialKey("CTRL+C", " to copy a selection");
this.addTutorialKey("CTRL+V", " to paste a selection");
this.addTutorialKey("CTRL+X", " to cut a selection");
this.addTutorialImg("/images/ToolTutorials/rectselect-tutorial.gif");
this.addTutorialImg("/rectselect-tutorial.gif");
}
onStart(mousePos, mouseTarget) {

View File

@ -44,7 +44,11 @@
00111000
00000010
00000000
`;
`
.replaceAll("\n","")
.replaceAll(" ","")
.replaceAll("\t","")
;
const ASSET_CACHE = {};
const TOOL_ARR = [
// {name:"Pencil",hotkey:"B",art:{img: icons_img1,idx:0}},
@ -55,27 +59,13 @@
{name:"Line",hotkey:"S",art:{img: icons_img1,idx:2}},
];
window.onload = () => {
insertTools(TOOL_ARR);
const columns = 8;
const tilesetsArr = imageChopper(tiles_image,32,32);
const tilesetsCanvasArrArr = tilesetsArr.map((canvas)=>{
return imageChopper(canvas,8,8);
});
////console.log('tilesetsCanvasArrArr === ', tilesetsCanvasArrArr);
const data = `
10000000
00100000
01110010
00100010
00000010
00111000
00000010
00000000
`
.replaceAll("\n","")
.replaceAll(" ","")
.replaceAll("\t","")
;
////console.log('data === ',data);
let i = 0;
const width = columns;

View File

@ -9,7 +9,7 @@ const FULLBUILDPATH = path.join(__dirname, BUILDDIR)
//LOGGING
app.use((req, res, next)=> {
//console.log('REQUEST', req.method+' '+req.originalUrl, res.statusCode);
//////console.log('REQUEST', req.method+' '+req.originalUrl, res.statusCode);
next();
});
@ -29,29 +29,29 @@ app.use((req, res, next) => {
app.use('/', express.static(FULLBUILDPATH, {
//custom function required for logging static files
setHeaders: (res, filePath, fileStats) => {
console.info('GET', '/'+path.relative(FULLBUILDPATH, filePath), res.statusCode);
//console.info('GET', '/'+path.relative(FULLBUILDPATH, filePath), res.statusCode);
}
}));
//ROUTE - match / or any route with just numbers letters and dashes, and return index.htm (all other routes should have been handled already)
app.get('/', (req, res, next) => {
//console.log('root')
////console.log('root')
res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) {
//console.log('sent file');
////console.log('sent file');
return next();
});
});
app.get('/pixel-editor', (req, res, next) => {
//console.log('root')
////console.log('root')
res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) {
//console.log('sent file');
////console.log('sent file');
return next();
});
});
app.get('/pixel-editor/?:palette/?:resolution/?:patternWidth/?:patternBinStr', (req, res, next) => {
//console.log('root')
////console.log('root')
res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) {
//console.log('sent file');
////console.log('sent file');
return next();
});
});
@ -64,13 +64,13 @@ if (process.env.RELOAD === "yes") {
reload(app).then(() => {
//start server
app.server = app.listen(PORT, () => {
console.log(`Web server listening on port ${PORT} (with reload module)`);
////console.log(`Web server listening on port ${PORT} (with reload module)`);
})
});
} else {
app.listen(PORT, () => {
console.log(`Web server listening on port ${PORT}`);
////console.log(`Web server listening on port ${PORT}`);
})
}
@ -82,5 +82,5 @@ app.use(function(req, res, next) {
//LOGGING
app.use((req, res, next)=> {
console.log(req.method+' '+req.originalUrl, res.statusCode);
////console.log(req.method+' '+req.originalUrl, res.statusCode);
});

View File

@ -5,21 +5,21 @@ Heyo! New pixel editor update, with some very requested changes. After the code
Finally! With the lasso tool you're not forced to select rectangular areas anymore. Have fun selecting, cutting,
copying and pasting any kind of selection with pixel-perfect precision.
</br><img src="/images/ToolTutorials/lassoselect-tutorial.gif"/>
</br><img src="/lassoselect-tutorial.gif"/>
<h2>Magic wand</h2>
In addition to the lasso tool, we added a new selection tool: the magic wand. You can use it to select
contiguous areas of the same colour! If you need to exactly select the pixels of a certain colour, you're
probably going to find the magic wand useful.
</br><img src="/images/ToolTutorials/magicwand-tutorial.gif"/>
</br><img src="/magicwand-tutorial.gif"/>
<h2>Ellipse tool</h2>
I added a cute friend for the rectangle tool: with the ellipse tool you'll be able to draw circles and
ellipses of all sizes. The tool works similarly to the rectangle tool: select it to draw empty ellipses,
click on the ellipse button again to draw filled ellipses.
</br><img src="/images/ToolTutorials/ellipse-tutorial.gif"/>
</br><img src="/ellipse-tutorial.gif"/>
<h2>Tool tutorials</h2>
I know what you're thinking, "wow those gifs are so cute, that guy must have put a lot of love in them".
@ -27,7 +27,7 @@ Well, I'm glad you like them, and I have good news for you: there are more! Move
button: after a little a small tutorial explaining how to use the tool will appear. Hope it's useful for
everyone who's new to the editor!
</br><img src="/images/ToolTutorials/tool-tutorials.gif"/>
</br><img src="/tool-tutorials.gif"/>
<h2>Top bar info</h2>
Depending on the tool you're using, you'll notice that the top right part of the editor will slightly change.

View File

@ -53,6 +53,7 @@
<ul>
<li><button id="switch-mode-button">Switch to basic mode</button></li>
<li><button onclick="Dialogue.showDialogue('splash', false)">Splash page</button></li>
<li><button id="auto-cache-button" onclick="FileManager.toggleCache(this)">Enable auto-cache</button></li>
<li><button>Settings</button></li>
</ul>
</li>