mirror of
https://github.com/javl/image2cpp.git
synced 2026-09-11 09:03:04 +00:00
layout tweaks
This commit is contained in:
+53
-38
@@ -39,6 +39,7 @@
|
|||||||
/* Fonts */
|
/* Fonts */
|
||||||
--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
|
--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
|
||||||
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||||
|
--font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -49,7 +50,7 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
font-size: 16px;
|
font-size: var(--font-size);
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
color: var(--on-background);
|
color: var(--on-background);
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
@@ -67,7 +68,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topnav-inner {
|
.topnav-inner {
|
||||||
max-width: 1400px;
|
max-width: 1200px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
padding: 0 var(--space-6);
|
padding: 0 var(--space-6);
|
||||||
@@ -96,7 +97,7 @@ body {
|
|||||||
.topnav-links a {
|
.topnav-links a {
|
||||||
color: var(--secondary);
|
color: var(--secondary);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ body {
|
|||||||
.layout {
|
.layout {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-7);
|
gap: var(--space-7);
|
||||||
max-width: 1400px;
|
max-width: 1200px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding: var(--space-7) var(--space-6) var(--space-9);
|
padding: var(--space-7) var(--space-6) var(--space-9);
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -353,6 +354,7 @@ code {
|
|||||||
.table-row {
|
.table-row {
|
||||||
display: table-row;
|
display: table-row;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell {
|
.table-cell {
|
||||||
@@ -370,66 +372,71 @@ code {
|
|||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell:first-child label {
|
.table-cell:first-child > label {
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 500;
|
/* font-weight: 500; */
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell:last-child label {
|
.table-cell:last-child > label {
|
||||||
margin-right: var(--space-2);
|
margin-right: var(--space-2);
|
||||||
color: var(--on-surface-variant);
|
color: var(--on-surface-variant);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-table {
|
.nested-table {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- Settings grid (step 2) ----
|
/* ---- Settings rows (step 2) ----
|
||||||
2-column min-width forces a predictable 2-up (or 1-up) grid instead of
|
Single-column label-left / value-right rows, hairline-divided. Denser
|
||||||
auto-fitting 3 columns, which paired short/tall fields at random and
|
than the old 2-up grid, and keeps each setting's note attached under
|
||||||
left ragged whitespace between rows. */
|
its label instead of floating below the control in the value column. */
|
||||||
|
|
||||||
.settings-grid {
|
.settings-grid {
|
||||||
display: grid;
|
display: block;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
||||||
gap: var(--space-6) var(--space-7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-grid.table {
|
|
||||||
margin: var(--space-2) 0 0;
|
margin: var(--space-2) 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-grid .table-row {
|
.settings-grid .table-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
align-items: flex-start;
|
||||||
gap: var(--space-2);
|
gap: var(--space-6);
|
||||||
|
padding: var(--space-1) 0;
|
||||||
|
border-top: 1px solid var(--border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-grid .table-row.full-row {
|
.settings-grid .table-row:first-child {
|
||||||
grid-column: 1 / -1;
|
border-top: none;
|
||||||
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-grid .table-cell {
|
.settings-grid .table-cell {
|
||||||
display: block;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-grid .table-cell:first-child {
|
.settings-grid .table-cell:first-child {
|
||||||
width: auto;
|
width: 34%;
|
||||||
padding-right: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-grid .table-cell:last-child {
|
.settings-grid .table-cell:last-child {
|
||||||
width: auto;
|
width: auto;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-grid .table-cell:first-child .note {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.45em;
|
||||||
|
margin: var(--space-1) 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-table .table-cell {
|
.nested-table .table-cell {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
width: 200px;
|
/* width: 200px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
#format-caption-container {
|
#format-caption-container {
|
||||||
@@ -442,14 +449,14 @@ code {
|
|||||||
/* Reserve space for the tallest combination (Adafruit GFX shows both its
|
/* Reserve space for the tallest combination (Adafruit GFX shows both its
|
||||||
own fields and the Arduino identifier fields) so the Generate/Copy/
|
own fields and the Arduino identifier fields) so the Generate/Copy/
|
||||||
Download buttons don't jump around when switching output format. */
|
Download buttons don't jump around when switching output format. */
|
||||||
min-height: 278px;
|
/* min-height: 278px; */
|
||||||
transition: min-height 0.15s ease;
|
transition: min-height 0.15s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
#format-caption-container div {
|
#format-caption-container div {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
display: none;
|
display: none;
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
padding: var(--space-2) 0 var(--space-4);
|
padding: var(--space-2) 0 var(--space-4);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -459,7 +466,7 @@ code {
|
|||||||
|
|
||||||
.note {
|
.note {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
margin: var(--space-1) 0;
|
margin: var(--space-1) 0;
|
||||||
}
|
}
|
||||||
@@ -468,9 +475,9 @@ code {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-note {
|
/* .upload-note {
|
||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
}
|
} */
|
||||||
|
|
||||||
#continue-note {
|
#continue-note {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -494,7 +501,7 @@ input[type="number"],
|
|||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
color: var(--on-surface-variant);
|
color: var(--on-surface-variant);
|
||||||
background: var(--surface-container);
|
background: var(--surface-container);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
@@ -530,13 +537,13 @@ input[type="radio"] {
|
|||||||
min-width: 360px;
|
min-width: 360px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
#text-input-error {
|
#text-input-error {
|
||||||
color: var(--error);
|
color: var(--error);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
margin-top: var(--space-2);
|
margin-top: var(--space-2);
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -558,7 +565,7 @@ input[type="radio"] {
|
|||||||
.text-input-size {
|
.text-input-size {
|
||||||
margin: var(--space-2) 0;
|
margin: var(--space-2) 0;
|
||||||
color: var(--on-surface-variant);
|
color: var(--on-surface-variant);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.size-input {
|
.size-input {
|
||||||
@@ -577,7 +584,10 @@ input[type="radio"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sub-field-label {
|
.sub-field-label {
|
||||||
min-width: 160px;
|
min-width: 200px;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.glyph-input {
|
.glyph-input {
|
||||||
@@ -618,7 +628,7 @@ input[type="file"] {
|
|||||||
color: var(--on-surface-variant);
|
color: var(--on-surface-variant);
|
||||||
/* border: 2px dashed var(--outline-variant); */
|
/* border: 2px dashed var(--outline-variant); */
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
margin: var(--space-2) 0 0;
|
margin: var(--space-2) 0 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -778,7 +788,7 @@ input[type="file"]::file-selector-button {
|
|||||||
border: 1px solid var(--on-surface-variant);
|
border: 1px solid var(--on-surface-variant);
|
||||||
border-radius: var(--radius-xl);
|
border-radius: var(--radius-xl);
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 14px;
|
font-size: var(--font-size);
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
@@ -870,6 +880,11 @@ input[type="file"]::file-selector-button {
|
|||||||
.table-cell:first-child {
|
.table-cell:first-child {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-grid .table-row {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- Dark theme ---- */
|
/* ---- Dark theme ---- */
|
||||||
|
|||||||
+45
-42
@@ -85,7 +85,7 @@
|
|||||||
<section class="sub-section">
|
<section class="sub-section">
|
||||||
<div class="table settings-grid">
|
<div class="table settings-grid">
|
||||||
|
|
||||||
<div class="table-row full-row">
|
<div class="table-row">
|
||||||
<div class="table-cell"><label>Canvas size(s): </label></div>
|
<div class="table-cell"><label>Canvas size(s): </label></div>
|
||||||
<div class="table-cell">
|
<div class="table-cell">
|
||||||
<ul id="image-size-settings"></ul>
|
<ul id="image-size-settings"></ul>
|
||||||
@@ -99,7 +99,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-row">
|
<div class="table-row">
|
||||||
<div class="table-cell"><label>Canvas background color:</label></div>
|
<div class="table-cell">
|
||||||
|
<label>Canvas background color:</label>
|
||||||
|
<div class="note">Used for parts of the canvas that are not covered by your image.</div>
|
||||||
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell">
|
||||||
<input id="backgroundColorWhite" type="radio" name="backgroundColor" value="white" checked="checked" onchange="updateRadio('backgroundColor')"/>
|
<input id="backgroundColorWhite" type="radio" name="backgroundColor" value="white" checked="checked" onchange="updateRadio('backgroundColor')"/>
|
||||||
<label for="backgroundColorWhite" class="smallLabel">White</label>
|
<label for="backgroundColorWhite" class="smallLabel">White</label>
|
||||||
@@ -107,43 +110,11 @@
|
|||||||
<label for="backgroundColorBlack" class="smallLabel">Black</label>
|
<label for="backgroundColorBlack" class="smallLabel">Black</label>
|
||||||
<input id="backgroundColorTransparent" type="radio" name="backgroundColor" value="transparent" onchange="updateRadio('backgroundColor')"/>
|
<input id="backgroundColorTransparent" type="radio" name="backgroundColor" value="transparent" onchange="updateRadio('backgroundColor')"/>
|
||||||
<label for="backgroundColorTransparent" class="smallLabel">Transparent</label>
|
<label for="backgroundColorTransparent" class="smallLabel">Transparent</label>
|
||||||
<div class="note">
|
|
||||||
<i>Used for parts of the canvas that are not covered by your image.</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-row">
|
|
||||||
<div class="table-cell"><label for="invertColors">Invert image colors</label></div>
|
|
||||||
<div class="table-cell">
|
|
||||||
<input id="invertColors" type="checkbox" onchange="updateBoolean('invertColors')" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-row">
|
<div class="table-row">
|
||||||
<div class="table-cell"><label for="ditheringMode">Dithering: </label></div>
|
<div class="table-cell"><label for="scale">Image Scaling:</label></div>
|
||||||
<div class="table-cell">
|
|
||||||
<select id="ditheringMode" onchange="updateInteger('ditheringMode')">
|
|
||||||
<option value="2">Floyd-Steinberg</option>
|
|
||||||
<option value="0">Binary</option>
|
|
||||||
<option value="1">Bayer</option>
|
|
||||||
<option value="3">Atkinson</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-row">
|
|
||||||
<div class="table-cell"><label for="ditheringThreshold">Brightness / alpha threshold: </label></div>
|
|
||||||
<div class="table-cell">
|
|
||||||
<input id="ditheringThreshold" class="size-input" type="number" min="0" max="255" name="ditheringThreshold" oninput="updateInteger('ditheringThreshold')" value="128"/>
|
|
||||||
<div class="note">
|
|
||||||
<i>0 - 255; if the brightness of a pixel is above the given level the pixel becomes white, otherwise they become black. When using alpha, opaque and transparent are used instead. Default is 128.</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-row">
|
|
||||||
<div class="table-cell"><label for="scale">Scaling:</label></div>
|
|
||||||
<div class="table-cell">
|
<div class="table-cell">
|
||||||
<select id="scale" name="scale" onchange="updateInteger('scale')">
|
<select id="scale" name="scale" onchange="updateInteger('scale')">
|
||||||
<option value="1">original size</option>
|
<option value="1">original size</option>
|
||||||
@@ -156,15 +127,46 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-row">
|
<div class="table-row">
|
||||||
<div class="table-cell"><label>Center image:</label></div>
|
<div class="table-cell"><label for="invertColors">Invert image colors</label></div>
|
||||||
|
<div class="table-cell">
|
||||||
|
<input id="invertColors" type="checkbox" onchange="updateBoolean('invertColors')" /> <label for="invertColors">Invert</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-row">
|
||||||
|
<div class="table-cell"><label for="ditheringMode">Dithering: </label>
|
||||||
|
<div class="note">Different dithering algorithms produce different results.</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-cell">
|
||||||
|
<select id="ditheringMode" onchange="updateInteger('ditheringMode')">
|
||||||
|
<option value="0">Binary</option>
|
||||||
|
<option value="1">Bayer</option>
|
||||||
|
<option value="2">Floyd-Steinberg</option>
|
||||||
|
<option value="3">Atkinson</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-row">
|
||||||
|
<div class="table-cell">
|
||||||
|
<label for="ditheringThreshold">Brightness / alpha threshold: </label>
|
||||||
|
<div class="note">0 - 255; if the brightness of a pixel is above the given level the pixel becomes white, otherwise they become black. When using alpha, opaque and transparent are used instead. Default is 128.</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-cell">
|
||||||
|
<input id="ditheringThreshold" class="size-input" type="number" min="0" max="255" name="ditheringThreshold" oninput="updateInteger('ditheringThreshold')" value="128"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-row">
|
||||||
|
<div class="table-cell">
|
||||||
|
<label>Center image:</label>
|
||||||
|
<div class="note">Centering the image only works when using a canvas larger than the original image.</div>
|
||||||
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell">
|
||||||
<input id="centerHorizontally" type="checkbox" onchange="updateBoolean('centerHorizontally')" />
|
<input id="centerHorizontally" type="checkbox" onchange="updateBoolean('centerHorizontally')" />
|
||||||
<label for="centerHorizontally">horizontally</label>
|
<label for="centerHorizontally">horizontally</label>
|
||||||
<input id="centerVertically" type="checkbox" onchange="updateBoolean('centerVertically')" />
|
<input id="centerVertically" type="checkbox" onchange="updateBoolean('centerVertically')" />
|
||||||
<label for="centerVertically">vertically</label>
|
<label for="centerVertically">vertically</label>
|
||||||
<div class="note">
|
|
||||||
<i>Centering the image only works when using a canvas larger than the original image.</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -288,7 +290,7 @@
|
|||||||
<div class="table-cell"><label for="esp32Format">ESP32 formatting:</label></div>
|
<div class="table-cell"><label for="esp32Format">ESP32 formatting:</label></div>
|
||||||
<div class="table-cell">
|
<div class="table-cell">
|
||||||
<input id="esp32Format" type="checkbox" onchange="updateBoolean('esp32Format')" />
|
<input id="esp32Format" type="checkbox" onchange="updateBoolean('esp32Format')" />
|
||||||
<i class="note">Uses <code>uint8_t</code> instead of <code>unsigned char</code> and drops <code>PROGMEM</code>, which is a no-op on ESP32.</i>
|
<i class="note">Use <code>uint8_t</code> instead of <code>unsigned char</code> and drops <code>PROGMEM</code>, which is a no-op on ESP32.</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -323,10 +325,11 @@
|
|||||||
<i class="note">Set to 0 to wrap using the image's width instead, e.g. an 8px wide image adds a newline every 8th byte.</i>
|
<i class="note">Set to 0 to wrap using the image's width instead, e.g. an 8px wide image adds a newline every 8th byte.</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-field">
|
<div class="sub-field">
|
||||||
|
<label for="showAsciiPreview" class="sub-field-label">Ascii preview:</label>
|
||||||
<input id="showAsciiPreview" type="checkbox" onchange="updateBoolean('showAsciiPreview')">
|
<input id="showAsciiPreview" type="checkbox" onchange="updateBoolean('showAsciiPreview')">
|
||||||
<label for="showAsciiPreview">Show ascii preview behind output</label>
|
<i class="note">Add an ascii-art comment after each row of bytes. Forces one image row per output line, regardless of "Bytes per row".</i>
|
||||||
<i class="note">Adds a dot/hash ascii-art comment after each row of bytes. Forces one image row per output line, regardless of "Bytes per row".</i>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ const settings = {
|
|||||||
drawMode: 'horizontal',
|
drawMode: 'horizontal',
|
||||||
prefix: '0x',
|
prefix: '0x',
|
||||||
ditheringThreshold: 128,
|
ditheringThreshold: 128,
|
||||||
ditheringMode: 2,
|
ditheringMode: 0,
|
||||||
outputFormat: 'plain',
|
outputFormat: 'plain',
|
||||||
separator: ', ',
|
separator: ', ',
|
||||||
outputComments: true,
|
outputComments: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user