Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
562 changes: 303 additions & 259 deletions .history/src/index_20250519130637.html

Large diffs are not rendered by default.

582 changes: 316 additions & 266 deletions .history/src/index_20250519140924.html

Large diffs are not rendered by default.

614 changes: 332 additions & 282 deletions .history/src/index_20250519141013.html

Large diffs are not rendered by default.

622 changes: 338 additions & 284 deletions .history/src/index_20250519141039.html

Large diffs are not rendered by default.

642 changes: 348 additions & 294 deletions .history/src/index_20250519142527.html

Large diffs are not rendered by default.

622 changes: 337 additions & 285 deletions .history/src/index_20250519142541.html

Large diffs are not rendered by default.

622 changes: 337 additions & 285 deletions .history/src/index_20250519173726.html

Large diffs are not rendered by default.

622 changes: 337 additions & 285 deletions .history/src/index_20250519173805.html

Large diffs are not rendered by default.

630 changes: 341 additions & 289 deletions .history/src/index_20250519181803.html

Large diffs are not rendered by default.

636 changes: 347 additions & 289 deletions .history/src/index_20250519193347.html

Large diffs are not rendered by default.

646 changes: 357 additions & 289 deletions .history/src/index_20250519193401.html

Large diffs are not rendered by default.

711 changes: 422 additions & 289 deletions .history/src/index_20250519193438.html

Large diffs are not rendered by default.

724 changes: 435 additions & 289 deletions .history/src/index_20250519193541.html

Large diffs are not rendered by default.

724 changes: 435 additions & 289 deletions .history/src/index_20250519193607.html

Large diffs are not rendered by default.

724 changes: 435 additions & 289 deletions .history/src/index_20250519193626.html

Large diffs are not rendered by default.

733 changes: 444 additions & 289 deletions .history/src/index_20250519193658.html

Large diffs are not rendered by default.

741 changes: 452 additions & 289 deletions .history/src/index_20250519193722.html

Large diffs are not rendered by default.

755 changes: 466 additions & 289 deletions .history/src/index_20250519193743.html

Large diffs are not rendered by default.

755 changes: 466 additions & 289 deletions .history/src/index_20250519193807.html

Large diffs are not rendered by default.

759 changes: 470 additions & 289 deletions .history/src/index_20250519193841.html

Large diffs are not rendered by default.

761 changes: 472 additions & 289 deletions .history/src/index_20250519193903.html

Large diffs are not rendered by default.

763 changes: 474 additions & 289 deletions .history/src/index_20250519193917.html

Large diffs are not rendered by default.

763 changes: 474 additions & 289 deletions .history/src/index_20250519194439.html

Large diffs are not rendered by default.

763 changes: 474 additions & 289 deletions .history/src/index_20250519222641.html

Large diffs are not rendered by default.

347 changes: 185 additions & 162 deletions .history/src/scripts/app_20250519133340.js

Large diffs are not rendered by default.

257 changes: 140 additions & 117 deletions .history/src/scripts/app_20250519140104.js

Large diffs are not rendered by default.

305 changes: 166 additions & 139 deletions .history/src/scripts/app_20250519140204.js

Large diffs are not rendered by default.

309 changes: 168 additions & 141 deletions .history/src/scripts/app_20250519141105.js

Large diffs are not rendered by default.

317 changes: 172 additions & 145 deletions .history/src/scripts/app_20250519141133.js

Large diffs are not rendered by default.

321 changes: 174 additions & 147 deletions .history/src/scripts/app_20250519142105.js

Large diffs are not rendered by default.

321 changes: 174 additions & 147 deletions .history/src/scripts/app_20250519142753.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519142822.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519143718.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519150611.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519152152.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519152216.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519152227.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519173906.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519181515.js

Large diffs are not rendered by default.

376 changes: 214 additions & 162 deletions .history/src/scripts/app_20250519181559.js

Large diffs are not rendered by default.

410 changes: 233 additions & 177 deletions .history/src/scripts/app_20250519181852.js

Large diffs are not rendered by default.

416 changes: 236 additions & 180 deletions .history/src/scripts/app_20250519182000.js

Large diffs are not rendered by default.

416 changes: 236 additions & 180 deletions .history/src/scripts/app_20250519194532.js

Large diffs are not rendered by default.

646 changes: 356 additions & 290 deletions .history/src/scripts/app_20250519222947.js

Large diffs are not rendered by default.

658 changes: 362 additions & 296 deletions .history/src/scripts/app_20250519223028.js

Large diffs are not rendered by default.

658 changes: 362 additions & 296 deletions .history/src/scripts/app_20250602183532.js

Large diffs are not rendered by default.

676 changes: 371 additions & 305 deletions .history/src/scripts/app_20250602183633.js

Large diffs are not rendered by default.

420 changes: 249 additions & 171 deletions .history/src/scripts/app_20250605021544.js

Large diffs are not rendered by default.

417 changes: 245 additions & 172 deletions .history/src/scripts/app_20250605030646.js

Large diffs are not rendered by default.

430 changes: 253 additions & 177 deletions .history/src/scripts/app_20250617123815.js

Large diffs are not rendered by default.

435 changes: 256 additions & 179 deletions .history/src/scripts/app_20250617124102.js

Large diffs are not rendered by default.

444 changes: 263 additions & 181 deletions .history/src/scripts/app_20250617124427.js

Large diffs are not rendered by default.

444 changes: 263 additions & 181 deletions .history/src/scripts/app_20250617124617.js

Large diffs are not rendered by default.

470 changes: 279 additions & 191 deletions .history/src/scripts/app_20250617124803.js

Large diffs are not rendered by default.

516 changes: 308 additions & 208 deletions .history/src/scripts/app_20250617124923.js

Large diffs are not rendered by default.

562 changes: 337 additions & 225 deletions .history/src/scripts/app_20250617125036.js

Large diffs are not rendered by default.

345 changes: 191 additions & 154 deletions .history/src/scripts/canvas/PixelCanvas_20250519133458.js

Large diffs are not rendered by default.

141 changes: 89 additions & 52 deletions .history/src/scripts/canvas/PixelCanvas_20250519135800.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class PixelCanvas {
this.uiCanvas = document.getElementById(options.uiCanvasId);

// Canvas contexts
this.ctx = this.canvas.getContext('2d');
this.effectsCtx = this.effectsCanvas.getContext('2d');
this.uiCtx = this.uiCanvas.getContext('2d');
this.ctx = this.canvas.getContext("2d");
this.effectsCtx = this.effectsCanvas.getContext("2d");
this.uiCtx = this.uiCanvas.getContext("2d");

// Canvas dimensions
this.width = options.width || 64;
Expand All @@ -34,7 +34,7 @@ class PixelCanvas {
this.zoom = 1;

// Pixel data
this.pixels = new Array(this.width * this.height).fill('#000000');
this.pixels = new Array(this.width * this.height).fill("#000000");

// Undo/Redo history
this.history = [];
Expand All @@ -54,7 +54,7 @@ class PixelCanvas {
vignette: false,
noise: false,
pixelate: false,
intensity: 0.5
intensity: 0.5,
};

// Animation frame for effects
Expand Down Expand Up @@ -113,21 +113,24 @@ class PixelCanvas {
*/
setupEventListeners() {
// Mouse events
this.canvas.addEventListener('mousedown', this.handleMouseDown.bind(this));
document.addEventListener('mousemove', this.handleMouseMove.bind(this));
document.addEventListener('mouseup', this.handleMouseUp.bind(this));
this.canvas.addEventListener("mousedown", this.handleMouseDown.bind(this));
document.addEventListener("mousemove", this.handleMouseMove.bind(this));
document.addEventListener("mouseup", this.handleMouseUp.bind(this));

// Prevent context menu on right-click
this.canvas.addEventListener('contextmenu', (e) => {
this.canvas.addEventListener("contextmenu", (e) => {
e.preventDefault();
});

// Update cursor position display
this.canvas.addEventListener('mousemove', this.updateCursorPosition.bind(this));
this.canvas.addEventListener(
"mousemove",
this.updateCursorPosition.bind(this),
);

// Mouse leave
this.canvas.addEventListener('mouseleave', () => {
document.getElementById('cursor-position').textContent = 'X: - Y: -';
this.canvas.addEventListener("mouseleave", () => {
document.getElementById("cursor-position").textContent = "X: - Y: -";
});
}

Expand All @@ -140,15 +143,17 @@ class PixelCanvas {

// Get pixel coordinates
const rect = this.canvas.getBoundingClientRect();
const x = Math.floor((e.clientX - rect.left) / (this.pixelSize * this.zoom));
const x = Math.floor(
(e.clientX - rect.left) / (this.pixelSize * this.zoom),
);
const y = Math.floor((e.clientY - rect.top) / (this.pixelSize * this.zoom));

// Store last position
this.lastX = x;
this.lastY = y;

// Draw a single pixel
this.drawPixel(x, y, e.buttons === 2 ? '#000000' : '#ffffff');
this.drawPixel(x, y, e.buttons === 2 ? "#000000" : "#ffffff");

// Render the canvas
this.render();
Expand All @@ -163,13 +168,21 @@ class PixelCanvas {

// Get pixel coordinates
const rect = this.canvas.getBoundingClientRect();
const x = Math.floor((e.clientX - rect.left) / (this.pixelSize * this.zoom));
const x = Math.floor(
(e.clientX - rect.left) / (this.pixelSize * this.zoom),
);
const y = Math.floor((e.clientY - rect.top) / (this.pixelSize * this.zoom));

// Only draw if the position has changed
if (x !== this.lastX || y !== this.lastY) {
// Draw a line from last position to current position
this.drawLine(this.lastX, this.lastY, x, y, e.buttons === 2 ? '#000000' : '#ffffff');
this.drawLine(
this.lastX,
this.lastY,
x,
y,
e.buttons === 2 ? "#000000" : "#ffffff",
);

// Update last position
this.lastX = x;
Expand All @@ -193,13 +206,16 @@ class PixelCanvas {
*/
updateCursorPosition(e) {
const rect = this.canvas.getBoundingClientRect();
const x = Math.floor((e.clientX - rect.left) / (this.pixelSize * this.zoom));
const x = Math.floor(
(e.clientX - rect.left) / (this.pixelSize * this.zoom),
);
const y = Math.floor((e.clientY - rect.top) / (this.pixelSize * this.zoom));

if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
document.getElementById('cursor-position').textContent = `X: ${x} Y: ${y}`;
document.getElementById("cursor-position").textContent =
`X: ${x} Y: ${y}`;
} else {
document.getElementById('cursor-position').textContent = 'X: - Y: -';
document.getElementById("cursor-position").textContent = "X: - Y: -";
}
}

Expand Down Expand Up @@ -344,21 +360,21 @@ class PixelCanvas {
// Don't fill if the target color is the same as the fill color
if (targetColor === fillColor) return;

const queue = [{x, y}];
const queue = [{ x, y }];

while (queue.length > 0) {
const {x, y} = queue.shift();
const { x, y } = queue.shift();

// Check if this pixel is the target color
if (this.getPixel(x, y) === targetColor) {
// Set the pixel to the fill color
this.drawPixel(x, y, fillColor);

// Add adjacent pixels to the queue
if (x > 0) queue.push({x: x - 1, y});
if (x < this.width - 1) queue.push({x: x + 1, y});
if (y > 0) queue.push({x, y: y - 1});
if (y < this.height - 1) queue.push({x, y: y + 1});
if (x > 0) queue.push({ x: x - 1, y });
if (x < this.width - 1) queue.push({ x: x + 1, y });
if (y > 0) queue.push({ x, y: y - 1 });
if (y < this.height - 1) queue.push({ x, y: y + 1 });
}
}
}
Expand All @@ -382,14 +398,19 @@ class PixelCanvas {
*/
clear() {
// Clear pixel data
this.pixels.fill('#000000');
this.pixels.fill("#000000");

// Clear canvas
this.ctx.fillStyle = '#000000';
this.ctx.fillStyle = "#000000";
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

// Clear effects canvas
this.effectsCtx.clearRect(0, 0, this.effectsCanvas.width, this.effectsCanvas.height);
this.effectsCtx.clearRect(
0,
0,
this.effectsCanvas.width,
this.effectsCanvas.height,
);

// Clear UI canvas
this.uiCtx.clearRect(0, 0, this.uiCanvas.width, this.uiCanvas.height);
Expand All @@ -400,7 +421,7 @@ class PixelCanvas {
*/
render() {
// Clear canvas
this.ctx.fillStyle = '#000000';
this.ctx.fillStyle = "#000000";
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

// Draw pixels
Expand All @@ -414,7 +435,7 @@ class PixelCanvas {
x * this.pixelSize * this.zoom,
y * this.pixelSize * this.zoom,
this.pixelSize * this.zoom,
this.pixelSize * this.zoom
this.pixelSize * this.zoom,
);
}
}
Expand All @@ -432,7 +453,7 @@ class PixelCanvas {
this.uiCtx.clearRect(0, 0, this.uiCanvas.width, this.uiCanvas.height);

if (this.zoom >= 4) {
this.uiCtx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
this.uiCtx.strokeStyle = "rgba(255, 255, 255, 0.1)";
this.uiCtx.lineWidth = 1;

// Draw vertical lines
Expand All @@ -458,15 +479,20 @@ class PixelCanvas {
* @param {Object} effects - Effects settings
*/
setEffects(effects) {
this.effects = {...this.effects, ...effects};
this.effects = { ...this.effects, ...effects };
}

/**
* Animate the effects
*/
animateEffects() {
// Clear effects canvas
this.effectsCtx.clearRect(0, 0, this.effectsCanvas.width, this.effectsCanvas.height);
this.effectsCtx.clearRect(
0,
0,
this.effectsCanvas.width,
this.effectsCanvas.height,
);

// Apply grain effect
if (this.effects.grain) {
Expand All @@ -489,7 +515,9 @@ class PixelCanvas {
}

// Request next frame
this.effectsAnimationFrame = requestAnimationFrame(this.animateEffects.bind(this));
this.effectsAnimationFrame = requestAnimationFrame(
this.animateEffects.bind(this),
);
}

/**
Expand All @@ -498,7 +526,7 @@ class PixelCanvas {
applyGrainEffect() {
const intensity = this.effects.intensity * 0.1;

this.effectsCtx.fillStyle = 'rgba(0, 0, 0, 0.5)';
this.effectsCtx.fillStyle = "rgba(0, 0, 0, 0.5)";

for (let y = 0; y < this.height; y++) {
for (let x = 0; x < this.width; x++) {
Expand All @@ -507,7 +535,7 @@ class PixelCanvas {
x * this.pixelSize * this.zoom,
y * this.pixelSize * this.zoom,
this.pixelSize * this.zoom,
this.pixelSize * this.zoom
this.pixelSize * this.zoom,
);
}
}
Expand All @@ -520,7 +548,7 @@ class PixelCanvas {
applyStaticEffect() {
const intensity = this.effects.intensity * 0.05;

this.effectsCtx.fillStyle = 'rgba(255, 255, 255, 0.1)';
this.effectsCtx.fillStyle = "rgba(255, 255, 255, 0.1)";

for (let y = 0; y < this.canvas.height; y += 2) {
if (Math.random() < intensity) {
Expand All @@ -545,24 +573,29 @@ class PixelCanvas {
const offset = (Math.random() - 0.5) * 10 * intensity;

// Create a temporary canvas to hold the row
const tempCanvas = document.createElement('canvas');
const tempCanvas = document.createElement("canvas");
tempCanvas.width = this.canvas.width;
tempCanvas.height = this.pixelSize * this.zoom;
const tempCtx = tempCanvas.getContext('2d');
const tempCtx = tempCanvas.getContext("2d");

// Copy the row from the main canvas
tempCtx.drawImage(
this.canvas,
0, y * this.pixelSize * this.zoom,
this.canvas.width, this.pixelSize * this.zoom,
0, 0,
this.canvas.width, this.pixelSize * this.zoom
0,
y * this.pixelSize * this.zoom,
this.canvas.width,
this.pixelSize * this.zoom,
0,
0,
this.canvas.width,
this.pixelSize * this.zoom,
);

// Draw the row with offset
this.effectsCtx.drawImage(
tempCanvas,
offset * this.pixelSize * this.zoom, y * this.pixelSize * this.zoom
offset * this.pixelSize * this.zoom,
y * this.pixelSize * this.zoom,
);
}
}
Expand All @@ -575,17 +608,21 @@ class PixelCanvas {
const intensity = this.effects.intensity;

// Scanlines
this.effectsCtx.fillStyle = 'rgba(0, 0, 0, 0.1)';
this.effectsCtx.fillStyle = "rgba(0, 0, 0, 0.1)";
for (let y = 0; y < this.canvas.height; y += 2) {
this.effectsCtx.fillRect(0, y, this.canvas.width, 1);
}

// Vignette
const gradient = this.effectsCtx.createRadialGradient(
this.canvas.width / 2, this.canvas.height / 2, 0,
this.canvas.width / 2, this.canvas.height / 2, this.canvas.width / 1.5
this.canvas.width / 2,
this.canvas.height / 2,
0,
this.canvas.width / 2,
this.canvas.height / 2,
this.canvas.width / 1.5,
);
gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
gradient.addColorStop(0, "rgba(0, 0, 0, 0)");
gradient.addColorStop(1, `rgba(0, 0, 0, ${intensity * 0.7})`);

this.effectsCtx.fillStyle = gradient;
Expand All @@ -600,7 +637,7 @@ class PixelCanvas {
setDimensions(width, height) {
this.width = width;
this.height = height;
this.pixels = new Array(this.width * this.height).fill('#000000');
this.pixels = new Array(this.width * this.height).fill("#000000");
this.initCanvas();
}

Expand Down Expand Up @@ -648,10 +685,10 @@ class PixelCanvas {
*/
exportToPNG() {
// Create a temporary canvas for export
const exportCanvas = document.createElement('canvas');
const exportCanvas = document.createElement("canvas");
exportCanvas.width = this.width;
exportCanvas.height = this.height;
const exportCtx = exportCanvas.getContext('2d');
const exportCtx = exportCanvas.getContext("2d");

// Draw pixels at 1:1 scale
for (let y = 0; y < this.height; y++) {
Expand All @@ -665,7 +702,7 @@ class PixelCanvas {
}

// Return data URL
return exportCanvas.toDataURL('image/png');
return exportCanvas.toDataURL("image/png");
}

/**
Expand Down
Loading