From 5ad95d78b29d25fcc29955db40faa514818e462a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Sep 2025 19:40:45 +0000
Subject: [PATCH 1/6] Initial plan
From 44407b1d5b598e55fdcc79b4f6b10b03e2ea5761 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Sep 2025 19:47:26 +0000
Subject: [PATCH 2/6] Add image input matrix feature with Lenna-like pattern
Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com>
---
index.html | 7 +++++++
script.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-----
styles.css | 37 +++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/index.html b/index.html
index 4121ace..ca018ac 100644
--- a/index.html
+++ b/index.html
@@ -43,6 +43,13 @@
Interactive Convolution Visualizer
+
+
+
+
diff --git a/script.js b/script.js
index 26cc027..d0881ce 100644
--- a/script.js
+++ b/script.js
@@ -10,6 +10,19 @@ document.addEventListener('DOMContentLoaded', function() {
let currentStep = 0;
let animationSpeed = 500; // milliseconds
+ // Image data - simplified Lenna-like pattern (8x8 grayscale values)
+ // This represents a portion of a typical portrait with varied skin tones and features
+ const lennaImageData = [
+ [180, 175, 170, 165, 160, 158, 155, 150],
+ [185, 180, 175, 170, 165, 162, 160, 155],
+ [190, 185, 180, 175, 170, 168, 165, 160],
+ [195, 190, 185, 180, 175, 173, 170, 165],
+ [200, 195, 190, 185, 180, 178, 175, 170],
+ [205, 200, 195, 190, 185, 183, 180, 175],
+ [210, 205, 200, 195, 190, 188, 185, 180],
+ [215, 210, 205, 200, 195, 193, 190, 185]
+ ];
+
// Get DOM elements
const inputHeightEl = document.getElementById('input-height');
const inputWidthEl = document.getElementById('input-width');
@@ -18,6 +31,7 @@ document.addEventListener('DOMContentLoaded', function() {
const paddingEl = document.getElementById('padding');
const dilationEl = document.getElementById('dilation');
const strideEl = document.getElementById('stride');
+ const inputTypeEl = document.getElementById('input-type');
const updateBtn = document.getElementById('update-btn');
const animateBtn = document.getElementById('animate-btn');
const stopBtn = document.getElementById('stop-btn');
@@ -180,10 +194,26 @@ document.addEventListener('DOMContentLoaded', function() {
}
function generateMatrices(inputHeight, inputWidth, kernelHeight, kernelWidth, padding, outputHeight, outputWidth) {
- // Generate input matrix with random values (0-9)
- inputMatrix = Array(inputHeight).fill().map(() =>
- Array(inputWidth).fill().map(() => Math.floor(Math.random() * 10))
- );
+ const inputType = inputTypeEl.value;
+
+ if (inputType === 'image') {
+ // Generate input matrix from image data
+ inputMatrix = Array(inputHeight).fill().map((_, i) =>
+ Array(inputWidth).fill().map((_, j) => {
+ // Map to image data coordinates and normalize to 0-9 range
+ const imgRow = Math.floor((i / inputHeight) * lennaImageData.length);
+ const imgCol = Math.floor((j / inputWidth) * lennaImageData[0].length);
+ const pixelValue = lennaImageData[imgRow][imgCol];
+ // Convert from 0-255 to 0-9 range
+ return Math.floor((pixelValue / 255) * 9);
+ })
+ );
+ } else {
+ // Generate input matrix with random values (0-9)
+ inputMatrix = Array(inputHeight).fill().map(() =>
+ Array(inputWidth).fill().map(() => Math.floor(Math.random() * 10))
+ );
+ }
// Generate weight matrix with random values (-2 to 2)
weightMatrix = Array(kernelHeight).fill().map(() =>
@@ -237,6 +267,8 @@ document.addEventListener('DOMContentLoaded', function() {
container.style.gridTemplateRows = `repeat(${matrix.length}, 40px)`;
container.style.gridTemplateColumns = `repeat(${matrix[0].length}, 40px)`;
+ const inputType = inputTypeEl.value;
+
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
const cell = document.createElement('div');
@@ -248,9 +280,28 @@ document.addEventListener('DOMContentLoaded', function() {
cell.classList.add('padding-cell');
} else {
cell.classList.add(`${type}-cell`);
+
+ // Add image background for input cells when using image input
+ if (type === 'input' && inputType === 'image' && !(i < padding || i >= inputHeight + padding || j < padding || j >= inputWidth + padding)) {
+ cell.classList.add('image-cell');
+
+ // Calculate the corresponding image pixel
+ const actualRow = i - padding;
+ const actualCol = j - padding;
+ const imgRow = Math.floor((actualRow / inputHeight) * lennaImageData.length);
+ const imgCol = Math.floor((actualCol / inputWidth) * lennaImageData[0].length);
+ const pixelValue = lennaImageData[imgRow][imgCol];
+
+ // Set background color based on pixel value (grayscale)
+ cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`;
+ }
}
- cell.textContent = matrix[i][j];
+ // Use a span for the text content to ensure it's above the background
+ const textSpan = document.createElement('span');
+ textSpan.textContent = matrix[i][j];
+ cell.appendChild(textSpan);
+
container.appendChild(cell);
}
}
diff --git a/styles.css b/styles.css
index 7866001..c63e879 100644
--- a/styles.css
+++ b/styles.css
@@ -71,6 +71,14 @@ input[type="number"] {
text-align: center;
}
+select {
+ padding: 8px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ background-color: white;
+ min-width: 120px;
+}
+
button {
background-color: #4285f4;
color: white;
@@ -139,6 +147,35 @@ button:hover {
background-color: var(--input-color);
}
+.input-cell.image-cell {
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ color: white;
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.9);
+ font-weight: bold;
+ position: relative;
+}
+
+.input-cell.image-cell::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.3);
+ z-index: 1;
+ pointer-events: none;
+}
+
+.input-cell.image-cell span {
+ position: relative;
+ z-index: 2;
+ font-size: 16px;
+ font-weight: 900;
+}
+
.weight-cell {
background-color: var(--weight-color);
}
From f8c4d8b388550d8208b8efa366472be99f718e64 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Sep 2025 19:56:14 +0000
Subject: [PATCH 3/6] =?UTF-8?q?Replace=20normalized=20Lenna=20with=20CIFAR?=
=?UTF-8?q?-like=2028=C3=9728=20image=20data=20without=20normalization?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com>
---
index.html | 2 +-
script.js | 62 ++++++++++++++++++++++++++++++++++++------------------
2 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/index.html b/index.html
index ca018ac..a65dc91 100644
--- a/index.html
+++ b/index.html
@@ -47,7 +47,7 @@ Interactive Convolution Visualizer
diff --git a/script.js b/script.js
index d0881ce..f2b529e 100644
--- a/script.js
+++ b/script.js
@@ -10,17 +10,37 @@ document.addEventListener('DOMContentLoaded', function() {
let currentStep = 0;
let animationSpeed = 500; // milliseconds
- // Image data - simplified Lenna-like pattern (8x8 grayscale values)
- // This represents a portion of a typical portrait with varied skin tones and features
- const lennaImageData = [
- [180, 175, 170, 165, 160, 158, 155, 150],
- [185, 180, 175, 170, 165, 162, 160, 155],
- [190, 185, 180, 175, 170, 168, 165, 160],
- [195, 190, 185, 180, 175, 173, 170, 165],
- [200, 195, 190, 185, 180, 178, 175, 170],
- [205, 200, 195, 190, 185, 183, 180, 175],
- [210, 205, 200, 195, 190, 188, 185, 180],
- [215, 210, 205, 200, 195, 193, 190, 185]
+ // CIFAR-like 28x28 grayscale image data representing a simple object (car/plane)
+ // Values are actual pixel intensities (0-255) without normalization
+ const cifarImageData = [
+ [45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180],
+ [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185],
+ [55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190],
+ [60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195],
+ [65, 70, 75, 80, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90],
+ [70, 75, 80, 85, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100],
+ [75, 80, 85, 90, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110],
+ [80, 85, 90, 95, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120],
+ [85, 90, 95, 100, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130],
+ [90, 95, 100, 105, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140],
+ [95, 100, 105, 110, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150],
+ [100, 105, 110, 115, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140],
+ [105, 110, 115, 120, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130],
+ [110, 115, 120, 125, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120],
+ [115, 120, 125, 130, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110],
+ [120, 125, 130, 135, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100],
+ [125, 130, 135, 140, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90],
+ [130, 135, 140, 145, 190, 200, 210, 220, 230, 240, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80],
+ [135, 140, 145, 150, 180, 190, 200, 210, 220, 230, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70],
+ [140, 145, 150, 155, 170, 180, 190, 200, 210, 220, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60],
+ [145, 150, 155, 160, 160, 170, 180, 190, 200, 210, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50],
+ [150, 155, 160, 165, 150, 160, 170, 180, 190, 200, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40],
+ [155, 160, 165, 170, 140, 150, 160, 170, 180, 190, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30],
+ [160, 165, 170, 175, 130, 140, 150, 160, 170, 180, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20],
+ [165, 170, 175, 180, 120, 130, 140, 150, 160, 170, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10],
+ [170, 175, 180, 185, 110, 120, 130, 140, 150, 160, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0],
+ [175, 180, 185, 190, 100, 110, 120, 130, 140, 150, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0],
+ [180, 185, 190, 195, 90, 100, 110, 120, 130, 140, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 0]
];
// Get DOM elements
@@ -197,15 +217,15 @@ document.addEventListener('DOMContentLoaded', function() {
const inputType = inputTypeEl.value;
if (inputType === 'image') {
- // Generate input matrix from image data
+ // Generate input matrix from CIFAR-like image data (no normalization)
inputMatrix = Array(inputHeight).fill().map((_, i) =>
Array(inputWidth).fill().map((_, j) => {
- // Map to image data coordinates and normalize to 0-9 range
- const imgRow = Math.floor((i / inputHeight) * lennaImageData.length);
- const imgCol = Math.floor((j / inputWidth) * lennaImageData[0].length);
- const pixelValue = lennaImageData[imgRow][imgCol];
- // Convert from 0-255 to 0-9 range
- return Math.floor((pixelValue / 255) * 9);
+ // Map to image data coordinates
+ const imgRow = Math.floor((i / inputHeight) * cifarImageData.length);
+ const imgCol = Math.floor((j / inputWidth) * cifarImageData[0].length);
+ const pixelValue = cifarImageData[imgRow][imgCol];
+ // Return actual pixel values (0-255) without normalization
+ return pixelValue;
})
);
} else {
@@ -288,9 +308,9 @@ document.addEventListener('DOMContentLoaded', function() {
// Calculate the corresponding image pixel
const actualRow = i - padding;
const actualCol = j - padding;
- const imgRow = Math.floor((actualRow / inputHeight) * lennaImageData.length);
- const imgCol = Math.floor((actualCol / inputWidth) * lennaImageData[0].length);
- const pixelValue = lennaImageData[imgRow][imgCol];
+ const imgRow = Math.floor((actualRow / inputHeight) * cifarImageData.length);
+ const imgCol = Math.floor((actualCol / inputWidth) * cifarImageData[0].length);
+ const pixelValue = cifarImageData[imgRow][imgCol];
// Set background color based on pixel value (grayscale)
cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`;
From 6651b732d259b98edfeaaf3a0a4cb5abb2883056 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 18 Sep 2025 20:07:06 +0000
Subject: [PATCH 4/6] =?UTF-8?q?Add=20realistic=20CIFAR-style=2028=C3=9728?=
=?UTF-8?q?=20image=20input=20matrix=20with=20full-resolution=20visualizat?=
=?UTF-8?q?ion?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com>
---
index.html | 4 +--
script.js | 81 +++++++++++++++++++++++++++++++-----------------------
styles.css | 9 +++---
3 files changed, 54 insertions(+), 40 deletions(-)
diff --git a/index.html b/index.html
index a65dc91..7f74ef5 100644
--- a/index.html
+++ b/index.html
@@ -18,9 +18,9 @@ Interactive Convolution Visualizer
diff --git a/script.js b/script.js
index f2b529e..2c7a365 100644
--- a/script.js
+++ b/script.js
@@ -10,37 +10,37 @@ document.addEventListener('DOMContentLoaded', function() {
let currentStep = 0;
let animationSpeed = 500; // milliseconds
- // CIFAR-like 28x28 grayscale image data representing a simple object (car/plane)
- // Values are actual pixel intensities (0-255) without normalization
+ // CIFAR-like 28x28 grayscale image data representing a simple circular object
+ // Values are actual pixel intensities (0-255) creating a visible circular pattern
const cifarImageData = [
- [45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180],
- [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185],
- [55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190],
- [60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195],
- [65, 70, 75, 80, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90],
- [70, 75, 80, 85, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100],
- [75, 80, 85, 90, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110],
- [80, 85, 90, 95, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120],
- [85, 90, 95, 100, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130],
- [90, 95, 100, 105, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140],
- [95, 100, 105, 110, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150],
- [100, 105, 110, 115, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140],
- [105, 110, 115, 120, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130],
- [110, 115, 120, 125, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120],
- [115, 120, 125, 130, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110],
- [120, 125, 130, 135, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100],
- [125, 130, 135, 140, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90],
- [130, 135, 140, 145, 190, 200, 210, 220, 230, 240, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80],
- [135, 140, 145, 150, 180, 190, 200, 210, 220, 230, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70],
- [140, 145, 150, 155, 170, 180, 190, 200, 210, 220, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60],
- [145, 150, 155, 160, 160, 170, 180, 190, 200, 210, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50],
- [150, 155, 160, 165, 150, 160, 170, 180, 190, 200, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40],
- [155, 160, 165, 170, 140, 150, 160, 170, 180, 190, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30],
- [160, 165, 170, 175, 130, 140, 150, 160, 170, 180, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20],
- [165, 170, 175, 180, 120, 130, 140, 150, 160, 170, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10],
- [170, 175, 180, 185, 110, 120, 130, 140, 150, 160, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0],
- [175, 180, 185, 190, 100, 110, 120, 130, 140, 150, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0],
- [180, 185, 190, 195, 90, 100, 110, 120, 130, 140, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 0]
+ [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20],
+ [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20],
+ [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20],
+ [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20],
+ [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20],
+ [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50],
+ [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80],
+ [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120],
+ [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120],
+ [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120],
+ [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120],
+ [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80],
+ [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50],
+ [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20],
+ [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20],
+ [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20],
+ [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20],
+ [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20],
+ [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
];
// Get DOM elements
@@ -283,18 +283,31 @@ document.addEventListener('DOMContentLoaded', function() {
function renderMatrix(matrix, container, type, padding = 0, inputHeight = 0, inputWidth = 0) {
container.innerHTML = '';
- // Set grid dimensions
- container.style.gridTemplateRows = `repeat(${matrix.length}, 40px)`;
- container.style.gridTemplateColumns = `repeat(${matrix[0].length}, 40px)`;
-
const inputType = inputTypeEl.value;
+ // Determine cell size based on matrix size and type
+ let cellSize = 40;
+ if (type === 'input' && inputType === 'image' && inputHeight >= 20) {
+ cellSize = Math.max(15, Math.min(25, 600 / Math.max(inputHeight, inputWidth)));
+ }
+
+ // Set grid dimensions
+ container.style.gridTemplateRows = `repeat(${matrix.length}, ${cellSize}px)`;
+ container.style.gridTemplateColumns = `repeat(${matrix[0].length}, ${cellSize}px)`;
+
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.id = `${type}-${i}-${j}`;
+ // Apply dynamic sizing for image cells
+ if (type === 'input' && inputType === 'image' && inputHeight >= 20) {
+ cell.style.width = `${cellSize}px`;
+ cell.style.height = `${cellSize}px`;
+ cell.style.fontSize = `${Math.max(8, cellSize * 0.4)}px`;
+ }
+
// Check if this is a padding cell for the input matrix
if (type === 'input' && (i < padding || i >= inputHeight + padding || j < padding || j >= inputWidth + padding)) {
cell.classList.add('padding-cell');
diff --git a/styles.css b/styles.css
index c63e879..27fcc44 100644
--- a/styles.css
+++ b/styles.css
@@ -152,9 +152,10 @@ button:hover {
background-position: center;
background-repeat: no-repeat;
color: white;
- text-shadow: 2px 2px 4px rgba(0,0,0,0.9);
- font-weight: bold;
+ text-shadow: 1px 1px 3px rgba(0,0,0,1);
+ font-weight: 900;
position: relative;
+ font-size: 10px;
}
.input-cell.image-cell::after {
@@ -164,7 +165,7 @@ button:hover {
left: 0;
right: 0;
bottom: 0;
- background-color: rgba(0, 0, 0, 0.3);
+ background-color: rgba(0, 0, 0, 0.1);
z-index: 1;
pointer-events: none;
}
@@ -172,7 +173,7 @@ button:hover {
.input-cell.image-cell span {
position: relative;
z-index: 2;
- font-size: 16px;
+ font-size: 10px;
font-weight: 900;
}
From f85d21d3ee57a30aede3459215ad9553968063a5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 19 Sep 2025 18:56:54 +0000
Subject: [PATCH 5/6] Addressing PR comments
Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com>
---
index.html | 2 +-
script.js | 76 +++++++++++++++++++++++++++---------------------------
2 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/index.html b/index.html
index 7f74ef5..c2cf5f9 100644
--- a/index.html
+++ b/index.html
@@ -47,7 +47,7 @@
Interactive Convolution Visualizer
diff --git a/script.js b/script.js
index 2c7a365..c0890be 100644
--- a/script.js
+++ b/script.js
@@ -10,37 +10,37 @@ document.addEventListener('DOMContentLoaded', function() {
let currentStep = 0;
let animationSpeed = 500; // milliseconds
- // CIFAR-like 28x28 grayscale image data representing a simple circular object
- // Values are actual pixel intensities (0-255) creating a visible circular pattern
- const cifarImageData = [
- [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20],
- [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20],
- [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20],
- [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20],
- [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20],
- [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50],
- [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80],
- [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120],
- [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120],
- [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120],
- [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120],
- [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80],
- [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50],
- [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20],
- [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20],
- [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20],
- [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20],
- [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20],
- [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
+ // MNIST 28x28 grayscale image data representing the digit "5"
+ // Values are actual pixel intensities (0-255) creating a recognizable digit pattern
+ const mnistImageData = [
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 255, 220, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 50, 120, 200, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 200, 120, 50, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 70, 150, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 220, 150, 70, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 80, 160, 230, 255, 255, 255, 200, 120, 80, 40, 20, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 90, 170, 240, 255, 255, 200, 100, 50, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 100, 180, 250, 255, 180, 80, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 110, 190, 255, 200, 80, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 120, 200, 255, 150, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 130, 210, 255, 200, 140, 100, 80, 60, 40, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 140, 220, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 150, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 160, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 40, 80, 120, 160, 200, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 240, 180, 120],
+ [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 200, 140, 80, 40, 20, 40, 80, 140, 200, 255, 255, 255, 255, 255, 240, 180, 120, 60],
+ [0, 0, 0, 0, 50, 120, 200, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30],
+ [0, 0, 0, 0, 70, 150, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0],
+ [0, 0, 0, 0, 80, 160, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0],
+ [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
// Get DOM elements
@@ -217,13 +217,13 @@ document.addEventListener('DOMContentLoaded', function() {
const inputType = inputTypeEl.value;
if (inputType === 'image') {
- // Generate input matrix from CIFAR-like image data (no normalization)
+ // Generate input matrix from MNIST image data (no normalization)
inputMatrix = Array(inputHeight).fill().map((_, i) =>
Array(inputWidth).fill().map((_, j) => {
// Map to image data coordinates
- const imgRow = Math.floor((i / inputHeight) * cifarImageData.length);
- const imgCol = Math.floor((j / inputWidth) * cifarImageData[0].length);
- const pixelValue = cifarImageData[imgRow][imgCol];
+ const imgRow = Math.floor((i / inputHeight) * mnistImageData.length);
+ const imgCol = Math.floor((j / inputWidth) * mnistImageData[0].length);
+ const pixelValue = mnistImageData[imgRow][imgCol];
// Return actual pixel values (0-255) without normalization
return pixelValue;
})
@@ -321,9 +321,9 @@ document.addEventListener('DOMContentLoaded', function() {
// Calculate the corresponding image pixel
const actualRow = i - padding;
const actualCol = j - padding;
- const imgRow = Math.floor((actualRow / inputHeight) * cifarImageData.length);
- const imgCol = Math.floor((actualCol / inputWidth) * cifarImageData[0].length);
- const pixelValue = cifarImageData[imgRow][imgCol];
+ const imgRow = Math.floor((actualRow / inputHeight) * mnistImageData.length);
+ const imgCol = Math.floor((actualCol / inputWidth) * mnistImageData[0].length);
+ const pixelValue = mnistImageData[imgRow][imgCol];
// Set background color based on pixel value (grayscale)
cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`;
From d4457d8cc495ecddae3ae92fc5ca128962ea2ea1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 19 Sep 2025 20:35:29 +0000
Subject: [PATCH 6/6] Add MNIST digit image input with visual output matrix
pattern visualization
Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com>
---
script.js | 39 +++++++++++++++++++++++++++++++++++++++
styles.css | 13 +++++++++++++
2 files changed, 52 insertions(+)
diff --git a/script.js b/script.js
index c0890be..e3bbe8d 100644
--- a/script.js
+++ b/script.js
@@ -328,6 +328,45 @@ document.addEventListener('DOMContentLoaded', function() {
// Set background color based on pixel value (grayscale)
cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`;
}
+
+ // Add image-based background for output cells when using image input
+ if (type === 'output' && inputType === 'image') {
+ cell.classList.add('image-cell');
+
+ // Map output value to a color intensity
+ // Find min/max values in the output matrix for normalization
+ const flatOutput = outputMatrix.flat();
+ const minOutput = Math.min(...flatOutput);
+ const maxOutput = Math.max(...flatOutput);
+ const outputValue = matrix[i][j];
+
+ // Normalize output value to 0-255 range for visualization
+ let normalizedValue;
+ if (maxOutput !== minOutput) {
+ normalizedValue = Math.round(((outputValue - minOutput) / (maxOutput - minOutput)) * 255);
+ } else {
+ normalizedValue = 128; // Middle gray if all values are the same
+ }
+
+ // Apply a blue-to-red colormap for better visualization of positive/negative values
+ let red, green, blue;
+ if (outputValue < 0) {
+ // Negative values: blue tones
+ const intensity = Math.abs(outputValue - minOutput) / Math.abs(minOutput) * 255;
+ red = Math.max(0, 255 - intensity);
+ green = Math.max(0, 255 - intensity);
+ blue = 255;
+ } else {
+ // Positive values: red tones
+ const intensity = (outputValue / maxOutput) * 255;
+ red = 255;
+ green = Math.max(0, 255 - intensity);
+ blue = Math.max(0, 255 - intensity);
+ }
+
+ // Set background color with transparency to show the pattern
+ cell.style.backgroundColor = `rgba(${red}, ${green}, ${blue}, 0.6)`;
+ }
}
// Use a span for the text content to ensure it's above the background
diff --git a/styles.css b/styles.css
index 27fcc44..cf070b7 100644
--- a/styles.css
+++ b/styles.css
@@ -185,6 +185,19 @@ button:hover {
background-color: var(--output-color);
}
+.output-cell.image-cell {
+ color: white;
+ text-shadow: 1px 1px 3px rgba(0,0,0,1);
+ font-weight: 900;
+ position: relative;
+}
+
+.output-cell.image-cell span {
+ position: relative;
+ z-index: 2;
+ font-weight: 900;
+}
+
.padding-cell {
background-color: var(--padding-color);
color: #999;