diff --git a/css/style.css b/css/style.css
index 2480a87..35a8da2 100644
--- a/css/style.css
+++ b/css/style.css
@@ -796,13 +796,18 @@ input[type="file"]::file-selector-button {
/* background: var(--primary-container); */
margin: var(--space-2) var(--space-4) var(--space-2) 0;
max-width: 100%;
- /* Display width/height/aspect-ratio are set in JS (setCanvasDisplaySize)
- so small glyphs get enlarged without distorting their aspect ratio;
- independent min-width/min-height here would stretch non-square canvases. */
+ cursor: pointer;
+ /* Display width/height are set in JS (setCanvasDisplaySize), capped to
+ 128px on the largest side while preserving aspect ratio, and never
+ scaled up beyond the canvas' actual pixel size. */
image-rendering: crisp-edges;
image-rendering: pixelated;
}
+#preview-note {
+ display: none;
+}
+
.inlineImg {
border-radius: var(--radius-lg);
margin-top: var(--space-2);
diff --git a/index.html b/index.html
index f058c87..b2ae168 100644
--- a/index.html
+++ b/index.html
@@ -59,6 +59,7 @@
1. Select image
You can import multiple images at once. All processing is done locally in your browser: your images are not uploaded or stored anywhere online.
+ Only images file type are allowed
@@ -122,7 +123,6 @@
- Only images file type are allowed
Select one or more images at
step 1 first.
Apply first image size to all images
@@ -230,6 +230,7 @@
Preview
+ Click image to view at actual size
No files selected
diff --git a/js/script.js b/js/script.js
index 9c6ae08..db2e4bf 100644
--- a/js/script.js
+++ b/js/script.js
@@ -260,17 +260,32 @@ function invert(canvas, ctx) {
ctx.putImageData(imageData, 0, 0);
}
-// Size the on-screen canvas so tiny glyphs stay legible without distorting
-// their aspect ratio (independent min-width/min-height would stretch them).
+// Open the canvas' current contents as a full-size image in a new tab,
+// like a right-click "open image in new tab" on a regular .
+function openCanvasInNewTab(canvas) {
+ canvas.toBlob((blob) => {
+ const url = URL.createObjectURL(blob);
+ window.open(url, '_blank');
+ // Give the new tab time to load the image before freeing the blob.
+ setTimeout(() => URL.revokeObjectURL(url), 30000);
+ });
+}
+
+// Size the on-screen canvas, preserving aspect ratio: shown at its actual
+// pixel size up to 128px on its largest side, scaled down to fit within
+// 128px otherwise. Never scaled up. Wires up click-to-open-in-new-tab
+// (the "click to open at actual size" hint lives once in the Preview
+// header, not per canvas).
function setCanvasDisplaySize(canvas) {
- const minVisibleSize = 96;
- const scale = Math.max(1, minVisibleSize / Math.min(canvas.width, canvas.height));
- // eslint-disable-next-line no-param-reassign
- canvas.style.aspectRatio = `${canvas.width} / ${canvas.height}`;
+ const maxPreviewSize = 128;
+ const largestSide = Math.max(canvas.width, canvas.height);
+ const scale = largestSide > maxPreviewSize ? maxPreviewSize / largestSide : 1;
// eslint-disable-next-line no-param-reassign
canvas.style.width = `${Math.round(canvas.width * scale)}px`;
// eslint-disable-next-line no-param-reassign
- canvas.style.height = 'auto';
+ canvas.style.height = `${Math.round(canvas.height * scale)}px`;
+ // eslint-disable-next-line no-param-reassign
+ canvas.onclick = () => openCanvasInNewTab(canvas);
}
// Draw the image onto the canvas, taking into account color and scaling
@@ -655,9 +670,11 @@ function setTextInputSize(width, height) {
function checkImagesAvailable() {
const error = document.getElementById('no-images-error');
const glyphNameNote = document.getElementById('glyph-name-note');
+ const previewNote = document.getElementById('preview-note');
const hasImages = images.length() > 0;
error.style.display = hasImages ? 'none' : 'block';
glyphNameNote.style.display = hasImages ? 'block' : 'none';
+ previewNote.style.display = hasImages ? 'block' : 'none';
return hasImages;
}
@@ -712,6 +729,7 @@ function handleTextInput(drawMode) {
: listToImageVertical(list, canvas);
if (success) {
+ setCanvasDisplaySize(canvas);
document.getElementById('text-input-error').style.display = 'none';
document.querySelectorAll('.no-file-selected').forEach((el) => {
// eslint-disable-next-line no-param-reassign
@@ -927,32 +945,34 @@ function wrapFullExample(arrayCode, varName, width, height) {
#include
#include
-#define OLED_RESET 4
-Adafruit_SSD1306 display(OLED_RESET);
+#define SCREEN_WIDTH 128
+#define SCREEN_HEIGHT 64
-#if (SSD1306_LCDHEIGHT != ${settings.screenHeight})
-#error("Height incorrect, please fix Adafruit_SSD1306.h!");
-#endif
+// Initialize display with standard I2C reset pin config (-1)
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
${arrayCode}
void setup() {
- // initialize with the I2C addr 0x3D for the 128x64
- // replace with 0x3C for the 128x32
- display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
+ Serial.begin(9600);
+
+ // Initialize with I2C address 0x3C. You might have to change this to 0x3D for your display.
+ if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
+ Serial.println(F("SSD1306 allocation failed. Check your wiring or I2C address!"));
+ for(;;);
+ }
display.clearDisplay(); // Make sure the display is cleared
- // Draw the bitmap:
- // drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
- display.drawBitmap(0, 0, ${varName}, ${width}, ${height}, WHITE);
- // Update the display
+ // drawBitmap(x_coordinate, y_coordinate, array_name, width, height, color)
+ display.drawBitmap(0, 0, ${varName}, ${width}, ${height}, SSD1306_WHITE);
+
+ // Push the memory buffer out to the physical display
display.display();
}
void loop() {
-}
-`;
+}`;
}
// Removes the trailing separator comma left after the last byte value.