Browse Source

lazygit

main
Gregory Leeman 7 months ago
parent
commit
9c057113b5
  1. 1
      archive/temp.js
  2. 237
      render.js
  3. 95
      style.css

1
archive/temp.js

@ -37,7 +37,6 @@ function createPuck(c) {
dragHandle.innerHTML = '<i class="fa-solid fa-bars"></i>'; dragHandle.innerHTML = '<i class="fa-solid fa-bars"></i>';
puckMenu.appendChild(dragHandle); puckMenu.appendChild(dragHandle);
well.addEventListener('mousedown', (e) => { well.addEventListener('mousedown', (e) => {
let isMixing = true; let isMixing = true;
let startX = e.clientX; let startX = e.clientX;

237
render.js

@ -9,12 +9,11 @@ const canvasContainer = document.getElementById('canvas-container');
const brushPreview = document.getElementById('brush-preview'); const brushPreview = document.getElementById('brush-preview');
const canvas = document.getElementById('canvas'); const canvas = document.getElementById('canvas');
// canvas.style.imageRendering = 'pixelated';
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false; ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false; ctx.mozImageSmoothingEnabled = false;
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas.width = 800; canvas.width = 800;
canvas.height = 600; canvas.height = 600;
@ -31,6 +30,7 @@ let zoom = 1;
let brushSize = 5; let brushSize = 5;
let dBrushSize = 0.5; let dBrushSize = 0.5;
let maxBrushSize = 500; let maxBrushSize = 500;
let backgroundColor = 'rgb(255, 255, 255)';
let color = 'rgb(0, 0, 0)'; let color = 'rgb(0, 0, 0)';
let tool let tool
@ -247,7 +247,7 @@ canvasArea.addEventListener('mousedown', (e) => {
isMouseDown = true; isMouseDown = true;
if ( if (
tool === 'draw' || tool === 'brush' ||
tool === 'content-move' || tool === 'content-move' ||
tool === 'resize' || tool === 'resize' ||
tool === 'zoom' || tool === 'zoom' ||
@ -256,7 +256,7 @@ canvasArea.addEventListener('mousedown', (e) => {
saveState(); saveState();
} }
if (tool === 'draw') { if (tool === 'brush') {
drawCircle(canvasStartX, canvasStartY); drawCircle(canvasStartX, canvasStartY);
} else if (tool === 'bucket-fill') { } else if (tool === 'bucket-fill') {
floodFill(canvasStartX, canvasStartY, color); floodFill(canvasStartX, canvasStartY, color);
@ -305,7 +305,7 @@ canvasArea.addEventListener('mousemove', (e) => {
if (brushSize < 1) brushSize = 1; if (brushSize < 1) brushSize = 1;
if (brushSize > maxBrushSize) brushSize = maxBrushSize; if (brushSize > maxBrushSize) brushSize = maxBrushSize;
startX = endX; startX = endX;
} else if (tool === 'draw') { } else if (tool === 'brush') {
drawLineWithCircles(canvasStartX, canvasStartY, canvasEndX, canvasEndY); drawLineWithCircles(canvasStartX, canvasStartY, canvasEndX, canvasEndY);
canvasStartX = canvasEndX; canvasStartX = canvasEndX;
@ -313,6 +313,8 @@ canvasArea.addEventListener('mousemove', (e) => {
} else if (tool === 'content-move') { } else if (tool === 'content-move') {
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(tempCanvas, dX, dY); ctx.drawImage(tempCanvas, dX, dY);
} else if (tool === 'move') { } else if (tool === 'move') {
canvasContainer.style.left = dX + 'px'; canvasContainer.style.left = dX + 'px';
@ -332,6 +334,8 @@ canvasArea.addEventListener('mousemove', (e) => {
canvas.style.width = newWidth * zoom + 'px'; canvas.style.width = newWidth * zoom + 'px';
canvas.style.height = newHeight * zoom + 'px'; canvas.style.height = newHeight * zoom + 'px';
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(tempCanvas, 0, 0); ctx.drawImage(tempCanvas, 0, 0);
} }
} else if (tool === 'color-mix') { } else if (tool === 'color-mix') {
@ -362,7 +366,7 @@ canvasArea.addEventListener('mousemove', (e) => {
canvasArea.addEventListener('mouseup', (e) => { canvasArea.addEventListener('mouseup', (e) => {
isMouseDown = false; isMouseDown = false;
if (tool === 'draw') { if (tool === 'brush') {
ctx.closePath(); ctx.closePath();
} else if (tool === 'resize') { } else if (tool === 'resize') {
canvasWidth = canvas.width; canvasWidth = canvas.width;
@ -377,6 +381,7 @@ canvasArea.addEventListener('mouseup', (e) => {
// mouseleave {{{ // mouseleave {{{
canvasArea.addEventListener('mouseleave', (e) => { canvasArea.addEventListener('mouseleave', (e) => {
isMouseDown = false;
brushPreview.style.display = 'none'; brushPreview.style.display = 'none';
}); });
@ -386,32 +391,49 @@ canvasArea.addEventListener('mouseleave', (e) => {
var toolButtons = []; var toolButtons = [];
function createToolButton(icon, buttonTool) { function changeTool(toolName) {
toolButtons.forEach(button => button.button.classList.remove('active'));
toolButtons.find(button => button.name === toolName).button.classList.add('active');
tool = toolName;
brushPreview.style.display = 'none';
updateInfos();
}
function createToolButton(displayName, icon, toolName, jumpKey=undefined, temporaryKey=undefined) {
const button = document.createElement('div'); const button = document.createElement('div');
button.classList.add('button'); button.classList.add('button');
button.classList.add('tool'); button.classList.add('tool');
button.innerHTML = icon; button.innerHTML = icon;
button.title = buttonTool; button.title = displayName;
button.addEventListener('click', () => { button.addEventListener('click', () => {
buttons = document.getElementsByClassName('tool-button'); changeTool(toolName);
toolButtons.forEach(button => button.button.classList.remove('active'));
button.classList.add('active');
tool = buttonTool;
updateInfos();
}); });
if (jumpKey) {
const jumpKeyHint = document.createElement('span');
jumpKeyHint.className = 'jump-key-hint';
jumpKeyHint.innerHTML = jumpKey;
button.appendChild(jumpKeyHint);
}
if (temporaryKey) {
const temporaryKeyHint = document.createElement('span');
temporaryKeyHint.className = 'temporary-key-hint';
temporaryKeyHint.innerHTML = temporaryKey;
button.appendChild(temporaryKeyHint);
}
toolBar.appendChild(button); toolBar.appendChild(button);
return button; return button;
} }
toolButtons.push({'name': 'draw', 'button': createToolButton('<i class="fa-solid fa-paintbrush"></i>', 'draw')}); toolButtons.push({'name': 'brush', 'button': createToolButton('Brush', '<i class="fa-solid fa-paintbrush"></i>', 'brush', 'e', undefined)});
toolButtons.push({'name': 'content-move', 'button': createToolButton('<i class="fa-regular fa-hand"></i>', 'content-move')}); toolButtons.push({'name': 'content-move', 'button': createToolButton('Move Content', '<i class="fa-regular fa-hand"></i>', 'content-move', 'h', undefined)});
toolButtons.push({'name': 'move', 'button': createToolButton('<i class="fa-solid fa-arrows-up-down-left-right"></i>', 'move')}); toolButtons.push({'name': 'move', 'button': createToolButton('Move Canvas', '<i class="fa-solid fa-arrows-up-down-left-right"></i>', 'move', 'm', undefined)});
toolButtons.push({'name': 'zoom', 'button': createToolButton('<i class="fa-solid fa-magnifying-glass"></i>', 'zoom')}); toolButtons.push({'name': 'zoom', 'button': createToolButton('Zoom', '<i class="fa-solid fa-magnifying-glass"></i>', 'zoom', 'z', undefined)});
toolButtons.push({'name': 'resize', 'button': createToolButton('<i class="fa-solid fa-ruler-combined"></i>', 'resize')}); toolButtons.push({'name': 'resize', 'button': createToolButton('Resize', '<i class="fa-solid fa-ruler-combined"></i>', 'resize', 'r', undefined)});
toolButtons.push({'name': 'color-picker', 'button': createToolButton('<i class="fa-solid fa-eye-dropper"></i>', 'color-picker')}); toolButtons.push({'name': 'color-picker', 'button': createToolButton('Color Picker', '<i class="fa-solid fa-eye-dropper"></i>', 'color-picker', 'a', undefined)});
toolButtons.push({'name': 'color-mix', 'button': createToolButton('<i class="fa-solid fa-mortar-pestle"></i>', 'color-mix')}); toolButtons.push({'name': 'color-mix', 'button': createToolButton('Color Mix', '<i class="fa-solid fa-mortar-pestle"></i>', 'color-mix', 's', undefined)});
toolButtons.push({'name': 'brush-size', 'button': createToolButton('<i class="fa-regular fa-circle-dot"></i>', 'brush-size')}); toolButtons.push({'name': 'brush-size', 'button': createToolButton('Brush Size', '<i class="fa-regular fa-circle-dot"></i>', 'brush-size', 'd', undefined)});
toolButtons.push({'name': 'bucket-fill', 'button': createToolButton('<i class="fa-solid fa-fill"></i>', 'bucket-fill')}); toolButtons.push({'name': 'bucket-fill', 'button': createToolButton('Bucket Fill', '<i class="fa-solid fa-fill"></i>', 'bucket-fill', 'f', undefined)});
// }}} // }}}
@ -497,8 +519,8 @@ function createMenuButton(icon, name, clickFunction) {
button.innerHTML = icon; button.innerHTML = icon;
button.title = name; button.title = name;
if (clickFunction) { if (clickFunction) {
button.addEventListener('click', (e) => { button.addEventListener('click', () => {
clickFunction(e) clickFunction()
updateInfos(); updateInfos();
}); });
} }
@ -513,34 +535,127 @@ menuButtons.push(createMenuButton('<i class="fa-solid fa-up-down"></i>', 'Flip V
menuButtons.push(createMenuButton('<i class="fa-solid fa-undo"></i>', 'Undo', undo)); menuButtons.push(createMenuButton('<i class="fa-solid fa-undo"></i>', 'Undo', undo));
menuButtons.push(createMenuButton('<i class="fa-solid fa-redo"></i>', 'Redo', redo)); menuButtons.push(createMenuButton('<i class="fa-solid fa-redo"></i>', 'Redo', redo));
menuButtons.push(createMenuButton('<i class="fa-regular fa-trash-can"></i>', 'Clear', clearCanvas)); menuButtons.push(createMenuButton('<i class="fa-regular fa-trash-can"></i>', 'Clear', clearCanvas));
menuButtons.push(createMenuButton('<i class="fa-solid fa-search-minus"></i>', 'Reset Zoom', resetZoom)); menuButtons.push(createMenuButton('<i class="fa-solid fa-house"></i>', 'Reset', resetZoom));
menuButtons.push(createMenuButton('<i class="fa-solid fa-plus"></i>', 'Add Color', createPuck));
// }}} // }}}
// pucks {{{ // pucks {{{
function createPuck(c) { function createPuck(c, editable=true) {
if (c === undefined) {
c = color;
}
const puck = document.createElement('div'); const puck = document.createElement('div');
puck.className = 'puck'; puck.className = 'puck';
puck.style.backgroundColor = c; puck.style.backgroundColor = c;
puck.addEventListener('click', () => { const selectHandle = document.createElement('div');
color = c; selectHandle.className = 'select-handle';
selectHandle.innerHTML = '<i class="fa-solid fa-droplet"></i>';
puck.appendChild(selectHandle);
selectHandle.addEventListener('click', () => {
color = puck.style.backgroundColor;
updateColorPreview(); updateColorPreview();
updateInfos(); updateInfos();
}); });
if (editable) {
const updateHandle = document.createElement('div');
updateHandle.className = 'update-handle';
updateHandle.innerHTML = '<i class="fa-solid fa-fill"></i>';
puck.appendChild(updateHandle);
updateHandle.addEventListener('click', () => {
puck.style.backgroundColor = color;
});
const deleteHandle = document.createElement('div');
deleteHandle.className = 'delete-handle';
deleteHandle.innerHTML = '<i class="fa-solid fa-trash-can"></i>';
puck.appendChild(deleteHandle);
deleteHandle.addEventListener('click', () => {
console.log("test");
puck.remove();
});
}
puck.addEventListener('mousedown', (e) => {
let isMixing = true;
const startTime = Date.now(); // Record the time when the mouse is pressed
// Interval to update the color based on time
const interval = setInterval(() => {
if (isMixing) {
const elapsedTime = Date.now() - startTime;
const t = Math.min(1, elapsedTime / 10000);
const mixedColor = mixbox.lerp(color, puck.style.backgroundColor, t);
color = mixedColor;
updateColorPreview();
updateInfos();
}
}, 50); // Update every 50ms
document.addEventListener('mouseup', onMouseUp);
function onMouseUp() {
isMixing = false;
clearInterval(interval); // Stop the interval when the mouse is released
document.removeEventListener('mouseup', onMouseUp);
}
});
// puck.addEventListener('mousedown', (e) => {
// let isMixing = true;
// let startX = e.clientX;
// let startY = e.clientY;
// document.addEventListener('mousemove', onMouseMove);
// document.addEventListener('mouseup', onMouseUp);
// function onMouseMove(e) {
// if (isMixing) {
// const distance = Math.sqrt(Math.pow(e.clientX - startX, 2) + Math.pow(e.clientY - startY, 2));
// const t = Math.min(1, distance / 300);
// const mixedColor = mixbox.lerp(color, puck.style.backgroundColor, t);
// color = mixedColor;
// startX = e.clientX;
// startY = e.clientY;
// updateColorPreview();
// updateInfos();
// }
// }
// function onMouseUp() {
// isMixing = false;
// document.removeEventListener('mousemove', onMouseMove);
// document.removeEventListener('mouseup', onMouseUp);
// }
// });
menuBar.appendChild(puck); menuBar.appendChild(puck);
} }
createPuck('rgb(255, 0, 0)'); createPuck(c='rgb(0, 0, 0)', editable=false);
createPuck('rgb(0, 255, 0)'); createPuck(c='rgb(255, 255, 255)', editale=false);
createPuck('rgb(0, 0, 255)'); createPuck(c='rgb(0, 255, 0)', editale=false);
createPuck('rgb(255, 255, 0)'); createPuck(c='rgb(0, 0, 255)', editale=false);
createPuck('rgb(255, 0, 255)'); createPuck(c='rgb(255, 255, 0)', editale=false);
createPuck('rgb(0, 255, 255)'); createPuck(c='rgb(255, 0, 0)', editale=false);
createPuck('rgb(0, 0, 0)'); createPuck(c='rgb(255, 0, 255)', editale=false);
createPuck('rgb(255, 255, 255)'); createPuck(c='rgb(0, 255, 255)', editale=false);
// }}} // }}}
@ -568,7 +683,6 @@ function createInfo(name, updateFunction) {
return update; return update;
} }
infos.push(createInfo('tool', function() { return tool; }));
infos.push(createInfo('zoom', function() { infos.push(createInfo('zoom', function() {
var percent = zoom * 100; var percent = zoom * 100;
return percent.toFixed(0) + '%'; return percent.toFixed(0) + '%';
@ -586,10 +700,59 @@ function updateInfos() {
// }}} // }}}
// keybindings {{{
let keyDown = false;
let oldTool = tool;
const toolBindings = [
{'key': 'e', 'tool': 'brush', 'persistent': true},
{'key': 'h', 'tool': 'content-move', 'persistent': true},
{'key': 'm', 'tool': 'move', 'persistent': true},
{'key': 'z', 'tool': 'zoom', 'persistent': true},
{'key': 'r', 'tool': 'resize', 'persistent': true},
{'key': 'a', 'tool': 'color-picker', 'persistent': false},
{'key': 's', 'tool': 'color-mix', 'persistent': false},
{'key': 'd', 'tool': 'brush-size', 'persistent': false},
]
const functionBindings = [
{'key': 'u', 'function': undo},
{'key': 'y', 'function': redo},
{'key': 'backspace', 'function': clearCanvas},
]
document.addEventListener('keydown', (e) => {
if (keyDown) return;
if (toolBindings.map(b => b.key).includes(e.key)) {
oldTool = tool;
keyDown = true;
changeTool(toolBindings.find(b => b.key === e.key).tool);
return;
}
if (functionBindings.map(b => b.key).includes(e.key)) {
functionBindings.find(b => b.key === e.key).function();
}
});
document.addEventListener('keyup', (e) => {
keyDown = false;
if (toolBindings.filter(b => !b.persistent).map(b => b.key).includes(e.key)) {
changeTool(oldTool);
}
});
// }}}
// start {{{ // start {{{
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
updateInfos(); updateInfos();
toolButtons[0]['button'].click(); toolButtons[0]['button'].click();
resetZoom();
// }}} // }}}

95
style.css

@ -15,6 +15,18 @@ body {
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
font-family: 'VT323', monospace; font-family: 'VT323', monospace;
background-color: darkgray;
}
#menu-bar,
#info-bar,
#tool-bar,
#layer-bar {
z-index: 2;
}
#menu-bar {
justify-content: space-between;
} }
#menu-bar, #info-bar { #menu-bar, #info-bar {
@ -24,6 +36,7 @@ body {
flex-direction: row; flex-direction: row;
gap: 10px; gap: 10px;
justify-content: flex-start; justify-content: flex-start;
flex-wrap: wrap;
} }
#menu-bar { #menu-bar {
@ -53,7 +66,6 @@ body {
} }
#canvas-area { #canvas-area {
background-color: darkgray;
flex-grow: 1; flex-grow: 1;
height: 100%; height: 100%;
border: 1px solid; border: 1px solid;
@ -63,7 +75,7 @@ body {
#canvas-container { #canvas-container {
position: absolute; position: absolute;
border: 1px solid; border: 1px solid;
background-color: white; z-index: -1;
} }
@ -72,6 +84,8 @@ body {
} }
.button { .button {
position: relative;
flex-shrink: 0;
background-color: #ddd; background-color: #ddd;
border: 1px solid; border: 1px solid;
border-radius: 2px; border-radius: 2px;
@ -82,15 +96,92 @@ body {
flex-direction: column; flex-direction: column;
text-align: center; text-align: center;
justify-content: center; justify-content: center;
cursor: pointer;
} }
.puck { .puck {
position: relative;
flex-shrink: 0;
width: 30px; width: 30px;
height: 30px; height: 30px;
border: 1px solid; border: 1px solid;
border-radius: 2px; border-radius: 2px;
} }
.select-handle {
position: absolute;
bottom: 0;
right: 0;
font-size: .5em;
background-color: black;
color: white;
padding: 3px 0 1px 4px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 10px 0 0 0;
border-left: 1px solid white;
border-top: 1px solid white;
cursor: pointer;
}
.update-handle {
position: absolute;
top: 0;
right: 0;
font-size: .5em;
background-color: black;
color: white;
padding: 1px 0 3px 4px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 0 0 0 10px;
border-left: 1px solid white;
border-bottom: 1px solid white;
cursor: pointer;
}
.delete-handle {
position: absolute;
top: 0;
left: 0;
font-size: .5em;
background-color: black;
color: white;
padding: 1px 4px 3px 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 0 0 10px 0;
border-right: 1px solid white;
border-bottom: 1px solid white;
cursor: pointer;
}
.jump-key-hint {
display: block;
height: 12px;
width: 8px;
line-height: 8px;
/* width: 12px; */
position: absolute;
top: 0;
left: 0;
font-size: 1em;
/* padding: 2px 2px 2px 2px; */
/* display: flex; */
/* align-items: center; */
justify-content: center;
text-align: center;
border-radius: 0 0 5px 0;
/* border-right: 1px solid; */
/* border-bottom: 1px solid; */
}
.button.active, .button:active { .button.active, .button:active {
background-color: darkgray; background-color: darkgray;
} }

Loading…
Cancel
Save