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
96 changes: 62 additions & 34 deletions public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ const app = {
'PA-CF': { minTemp: 250, maxTemp: 280, bedTempMin: 70, bedTempMax: 90 }
},

// Primary color plus up to 4 extra colors
MAX_COLORS: 5,

palettes: {
material: {
paletteId: 'materialPalette',
Expand Down Expand Up @@ -129,15 +132,16 @@ const app = {
this.checkNFC();
// Removed preset swatch palette; using canvas pickers only
if (typeof ColorPicker !== 'undefined' && ColorPicker && typeof ColorPicker.init === 'function') {
ColorPicker.init(this);
ColorPicker.init(this, this.MAX_COLORS);
}
for (const name in this.palettes) this.initPalette(name);
this.populateFormats();
this.initEventListeners();
this.updateColorSlots();
this.updateFormat();
this.updateVisibility();
// Initialize all four colors
for (let i = 1; i <= 4; i++) {
// Initialize all colors
for (let i = 1; i <= this.MAX_COLORS; i++) {
this.updateColor('#FFFFFF', i);
}
this.applyTemperaturePreset();
Expand Down Expand Up @@ -310,8 +314,8 @@ const app = {
this.handleFileUpload(e.target.files[0]);
});

// Add event listeners for all four color inputs
for (let i = 1; i <= 4; i++) {
// Add event listeners for all color inputs
for (let i = 1; i <= this.MAX_COLORS; i++) {
document.getElementById(`colorHex${i}`).addEventListener('input', (e) => {
this.updateColor('#' + e.target.value, i);
this.updateRecordSize();
Expand All @@ -323,9 +327,12 @@ const app = {
this.updateVisibility();
});

document.getElementById('showAdditionalColors').addEventListener('change', (e) => {
this.toggleAdditionalColors(e.target.checked);
});
// Extra colors (2..MAX_COLORS) must be enabled before they can be set
for (let i = 2; i <= this.MAX_COLORS; i++) {
document.getElementById(`colorEnable${i}`).addEventListener('change', (e) => {
this.setColorEnabled(i, e.target.checked);
});
}

document.getElementById('brandInput').addEventListener('input', () => {
document.getElementById('brandValue').value = document.getElementById('brandInput').value || '';
Expand Down Expand Up @@ -390,25 +397,23 @@ const app = {
document.getElementById('formatSelect').value = data.format || format;
this.setPaletteValue('material', data.materialType || 'PLA');

// Populate all four color fields
document.getElementById('colorHex1').value = data.colorHex || 'FFFFFF';
this.updateColor('#' + (data.colorHex || 'FFFFFF'), 1);

document.getElementById('colorHex2').value = data.colorHex2 || 'FFFFFF';
this.updateColor('#' + (data.colorHex2 || 'FFFFFF'), 2);

document.getElementById('colorHex3').value = data.colorHex3 || 'FFFFFF';
this.updateColor('#' + (data.colorHex3 || 'FFFFFF'), 3);

document.getElementById('colorHex4').value = data.colorHex4 || 'FFFFFF';
this.updateColor('#' + (data.colorHex4 || 'FFFFFF'), 4);
// Populate all color fields
for (let i = 1; i <= this.MAX_COLORS; i++) {
const hex = data[i === 1 ? 'colorHex' : `colorHex${i}`] || 'FFFFFF';
document.getElementById(`colorHex${i}`).value = hex;
this.updateColor('#' + hex, i);
}

// Show additional colors if any are present
const hasAdditionalColors = (data.colorHex2 && data.colorHex2 !== 'FFFFFF') ||
(data.colorHex3 && data.colorHex3 !== 'FFFFFF') ||
(data.colorHex4 && data.colorHex4 !== 'FFFFFF');
document.getElementById('showAdditionalColors').checked = hasAdditionalColors;
this.toggleAdditionalColors(hasAdditionalColors);
// Enable each extra color present in the data. Colors are enabled in
// order, so a later color also enables any earlier gaps.
let enableUpTo = 1;
for (let i = 2; i <= this.MAX_COLORS; i++) {
if (data[`colorHex${i}`]) enableUpTo = i;
}
for (let i = 2; i <= this.MAX_COLORS; i++) {
document.getElementById(`colorEnable${i}`).checked = i <= enableUpTo;
}
this.updateColorSlots();

if (data.brand && this.palettes.brand.items.includes(data.brand)) {
this.setPaletteValue('brand', data.brand);
Expand Down Expand Up @@ -464,9 +469,10 @@ const app = {
materialType: document.getElementById('materialType').value,
brand: brand || 'Generic',
colorHex: document.getElementById('colorHex1').value.replace('#', ''),
colorHex2: document.getElementById('colorHex2').value.replace('#', ''),
colorHex3: document.getElementById('colorHex3').value.replace('#', ''),
colorHex4: document.getElementById('colorHex4').value.replace('#', ''),
colorHex2: this.getExtraColor(2),
colorHex3: this.getExtraColor(3),
colorHex4: this.getExtraColor(4),
colorHex5: this.getExtraColor(5),

// Temps/IDs
minTemp: document.getElementById('minTemp').value,
Expand Down Expand Up @@ -839,11 +845,33 @@ const app = {
return '#' + result.slice(0, 3).map(x => parseInt(x).toString(16).padStart(2, '0')).join('');
},

toggleAdditionalColors(show) {
const additionalColorFields = document.querySelectorAll('.additional-colors');
additionalColorFields.forEach(field => {
field.style.display = show ? 'block' : 'none';
});
// Extra color i's hex, or '' when it isn't enabled (so it isn't written)
getExtraColor(i) {
if (!document.getElementById(`colorEnable${i}`).checked) return '';
return document.getElementById(`colorHex${i}`).value.replace('#', '');
},

setColorEnabled(i, enabled) {
if (enabled) {
// Enabling a color also enables any earlier ones, keeping them in order
for (let j = 2; j <= i; j++) document.getElementById(`colorEnable${j}`).checked = true;
} else {
// Disabling a color also disables every later one
for (let j = i; j <= this.MAX_COLORS; j++) document.getElementById(`colorEnable${j}`).checked = false;
}
this.updateColorSlots();
this.updateRecordSize();
},

// Show each enabled color's fields, and offer the next color's checkbox
// only once the one before it is enabled.
updateColorSlots() {
for (let i = 2; i <= this.MAX_COLORS; i++) {
const enabled = document.getElementById(`colorEnable${i}`).checked;
const prevEnabled = i === 2 || document.getElementById(`colorEnable${i - 1}`).checked;
document.querySelector(`.extra-color[data-color-index="${i}"]`).style.display = prevEnabled ? '' : 'none';
document.getElementById(`colorFields${i}`).style.display = enabled ? '' : 'none';
}
},

showStatus(id, type, message) {
Expand Down
137 changes: 82 additions & 55 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,88 @@ <h2 class="section-title">✏️ <span id="formTitle">Create New Tag</span></h2>
<canvas id="colorHue1" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>

<!-- Extra colors for multi-color filament. Each one must be enabled
before it can be set, and only enabled colors are written. -->
<small data-field="colorHex2" style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin: 0 0 0.5rem;">
Multi-color filament: enable each extra color to set it
</small>
<div class="form-group extra-color" data-field="colorHex2" data-color-index="2">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="checkbox" id="colorEnable2" style="width: auto; cursor: pointer;">
<span>Color 2</span>
</label>
<div id="colorFields2" style="display: none; margin-top: 0.5rem;">
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex2" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview2" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV2" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue2" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>
</div>
<div class="form-group extra-color" data-field="colorHex3" data-color-index="3">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="checkbox" id="colorEnable3" style="width: auto; cursor: pointer;">
<span>Color 3</span>
</label>
<div id="colorFields3" style="display: none; margin-top: 0.5rem;">
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex3" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview3" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV3" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue3" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>
</div>
<div class="form-group extra-color" data-field="colorHex4" data-color-index="4">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="checkbox" id="colorEnable4" style="width: auto; cursor: pointer;">
<span>Color 4</span>
</label>
<div id="colorFields4" style="display: none; margin-top: 0.5rem;">
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex4" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview4" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV4" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue4" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>
</div>
<div class="form-group extra-color" data-field="colorHex5" data-color-index="5">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="checkbox" id="colorEnable5" style="width: auto; cursor: pointer;">
<span>Color 5</span>
</label>
<div id="colorFields5" style="display: none; margin-top: 0.5rem;">
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex5" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview5" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV5" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue5" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>
</div>

<div class="form-row">
<div class="form-group" data-field="minTemp">
<label>Min Nozzle Temp (°C)</label>
Expand Down Expand Up @@ -667,61 +749,6 @@ <h2 class="section-title">✏️ <span id="formTitle">Create New Tag</span></h2>
</small>
</div>

<div class="form-group">
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<input type="checkbox" id="showAdditionalColors" style="width: auto; cursor: pointer;">
<span>Additional Colors (Multi-color filament)</span>
</label>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Enable fields for colors 2, 3, and 4
</small>
</div>

<div class="form-group additional-colors" data-field="colorHex2" style="display: none;">
<label>Color 2 (Optional)</label>
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex2" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview2" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV2" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue2" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>

<div class="form-group additional-colors" data-field="colorHex3" style="display: none;">
<label>Color 3 (Optional)</label>
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex3" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview3" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV3" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue3" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>

<div class="form-group additional-colors" data-field="colorHex4" style="display: none;">
<label>Color 4 (Optional)</label>
<div style="display: flex; align-items: center; gap: 0.75rem;">
<input type="text" id="colorHex4" placeholder="FFFFFF" maxlength="6" pattern="[0-9A-Fa-f]{6}" style="flex: 1;">
<div id="colorPreview4" style="width: 60px; height: 40px; border-radius: 4px; border: 2px solid var(--border); background: #FFFFFF;"></div>
</div>
<small style="color: var(--text-secondary); font-size: 0.8rem; display: block; margin-top: 0.25rem;">
Hold and drag on the picker to choose, or enter hex without #
</small>
<div class="picker-row" style="display:flex; gap:0.5rem; margin-top:0.5rem; align-items:stretch;">
<canvas id="colorSV4" width="480" height="240" style="flex:1; height: 180px; border: 1px solid var(--border); border-radius: 4px; display:block;"></canvas>
</div>
<canvas id="colorHue4" width="480" height="24" style="width: 100%; height: 20px; border: 1px solid var(--border); border-radius: 4px; display:block; margin-top:0.5rem;"></canvas>
</div>

<div class="form-group" data-field="materialName">
<label>Material Name</label>
<input type="text" id="materialName" placeholder="e.g., Prusament PLA" maxlength="31">
Expand Down
Loading