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: 92 additions & 4 deletions app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { exportTo3MF } from './export';
import { setupPreview } from "./preview";
import { createBracket, defaultParams } from "./psu-bracket";

// Bambu X1C textured plate defaults
const DEFAULT_PLATE_WIDTH = 256;
const DEFAULT_PLATE_DEPTH = 256;

interface BracketParams {
width: number;
depth: number;
Expand All @@ -12,6 +16,8 @@ interface BracketParams {
holeDiameter: number;
earWidth: number;
hasBottom: boolean;
plateWidth: number;
plateDepth: number;
}

// Initialize the preview
Expand Down Expand Up @@ -41,14 +47,58 @@ function parseFormData(data: FormData) {
}


function calculateTotalWidth(params: BracketParams) {
return params.width + (params.bracketThickness * 2) + (params.earWidth * 2);
}

function calculateMaxInnerWidth(earWidth: number, bracketThickness: number, plateWidth: number) {
return plateWidth - (earWidth * 2) - (bracketThickness * 2);
}

function displayValues(params: BracketParams) {
const plateWidth = params.plateWidth || DEFAULT_PLATE_WIDTH;

// Update the max width based on ear width and bracket thickness FIRST
const widthInput = document.getElementById('width') as HTMLInputElement;
const maxWidth = calculateMaxInnerWidth(params.earWidth, params.bracketThickness, plateWidth);
if (widthInput) {
widthInput.max = maxWidth.toString();
// Clamp current value if it exceeds new max
if (params.width > maxWidth) {
params.width = maxWidth; // Update params so total width calculation is correct
widthInput.value = maxWidth.toString();
const widthValueInput = document.getElementById('widthValue') as HTMLInputElement;
if (widthValueInput) {
widthValueInput.value = maxWidth.toString();
}
}
}

for(const input of inputs) {
const label = input.nextElementSibling as HTMLDivElement;
const unit = input.getAttribute("data-unit") ?? 'mm';
if(label && label.classList.contains('value-display')) {
label.value = `${input.value}`;
// Find the value display - could be direct sibling or inside a wrapper
let valueDisplay = input.nextElementSibling as HTMLElement;
if (valueDisplay?.classList.contains('value-with-unit')) {
valueDisplay = valueDisplay.querySelector('.value-display') as HTMLInputElement;
}
if(valueDisplay && valueDisplay.classList.contains('value-display')) {
(valueDisplay as HTMLInputElement).value = `${input.value}`;
}
}

// Calculate and display total width (after clamping)
const totalWidth = calculateTotalWidth(params);
const totalWidthDisplay = document.getElementById('totalWidth');
if (totalWidthDisplay) {
totalWidthDisplay.textContent = `${totalWidth}mm`;
totalWidthDisplay.classList.toggle('over-limit', totalWidth > plateWidth);
}

// Update plate limit display
const plateLimitDisplay = document.getElementById('plateLimitDisplay');
if (plateLimitDisplay) {
plateLimitDisplay.textContent = plateWidth.toString();
}

// Also pop the color on the root so we can use in css
document.documentElement.style.setProperty('--color', params.color);
}
Expand All @@ -75,6 +125,44 @@ function updateUrl() {
controls.addEventListener("input", handleInput);
controls.addEventListener("change", updateUrl);

// Plate preset buttons
const presetButtons = document.querySelectorAll<HTMLButtonElement>('.plate-preset-btn');
const plateWidthInput = document.getElementById('plateWidth') as HTMLInputElement;
const plateDepthInput = document.getElementById('plateDepth') as HTMLInputElement;

function updateActivePreset() {
const currentWidth = parseInt(plateWidthInput.value);
const currentDepth = parseInt(plateDepthInput.value);

presetButtons.forEach(btn => {
const btnWidth = parseInt(btn.dataset.width || '0');
const btnDepth = parseInt(btn.dataset.depth || '0');
btn.classList.toggle('active', btnWidth === currentWidth && btnDepth === currentDepth);
});
}

presetButtons.forEach(btn => {
btn.addEventListener('click', () => {
const width = btn.dataset.width;
const depth = btn.dataset.depth;
if (width && depth) {
plateWidthInput.value = width;
plateDepthInput.value = depth;
// Trigger input event to update the UI
controls?.dispatchEvent(new Event('input', { bubbles: true }));
controls?.dispatchEvent(new Event('change', { bubbles: true }));
updateActivePreset();
}
});
});

// Update active preset when plate dimensions change manually
plateWidthInput.addEventListener('input', updateActivePreset);
plateDepthInput.addEventListener('input', updateActivePreset);

// Initialize active preset on page load
updateActivePreset();

// On page load, check if there is a url param and parse it
function restoreState() {

Expand Down
159 changes: 111 additions & 48 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,68 @@ <h1>Bracket.Engineer</h1>
<canvas id="preview"></canvas>
</div>
<form class="controls" id="controls">
<fieldset class="plate-settings">
<legend>Build Plate</legend>
<div class="plate-inputs">
<div class="plate-input-group">
<input
type="number"
id="plateWidth"
name="plateWidth"
min="100"
max="500"
step="1"
value="256"
/>
<span class="unit">mm</span>
</div>
<span class="plate-divider">×</span>
<div class="plate-input-group">
<input
type="number"
id="plateDepth"
name="plateDepth"
min="100"
max="500"
step="1"
value="256"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="plate-presets">
<button type="button" class="plate-preset-btn active" data-width="256" data-depth="256">Bambu X1C</button>
<button type="button" class="plate-preset-btn" data-width="180" data-depth="180">A1 Mini</button>
<button type="button" class="plate-preset-btn" data-width="250" data-depth="210">Prusa MK4</button>
<button type="button" class="plate-preset-btn" data-width="220" data-depth="220">Ender 3</button>
<button type="button" class="plate-preset-btn" data-width="350" data-depth="350">Voron 350</button>
</div>
</fieldset>
<div class="control-group">
<label for="width">Width</label>
<input
type="range"
id="width"
name="width"
min="10"
max="200"
max="236"
step="0.5"
value="86"
/>
<input
type="number"
id="widthValue"
class="value-display"
value="57"
value="200"
/>
<div class="value-with-unit">
<input
type="number"
id="widthValue"
class="value-display"
value="200"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="control-group total-width-display">
<label>Total Width</label>
<span id="totalWidth">--</span>
<span class="plate-limit">/ <span id="plateLimitDisplay">256</span>mm plate</span>
</div>
<div class="control-group">
<label for="height">Height</label>
Expand All @@ -76,12 +121,15 @@ <h1>Bracket.Engineer</h1>
step="0.5"
value="16"
/>
<input
type="number"
id="heightValue"
class="value-display"
value="15"
/>
<div class="value-with-unit">
<input
type="number"
id="heightValue"
class="value-display"
value="15"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="control-group">
<label for="depth">Depth</label>
Expand All @@ -94,12 +142,15 @@ <h1>Bracket.Engineer</h1>
step="1"
value="25"
/>
<input
type="number"
id="depthValue"
class="value-display"
value="33"
/>
<div class="value-with-unit">
<input
type="number"
id="depthValue"
class="value-display"
value="33"
/>
<span class="unit">mm</span>
</div>
</div>

<div class="control-group">
Expand All @@ -113,12 +164,15 @@ <h1>Bracket.Engineer</h1>
step="0.5"
value="3"
/>
<input
type="number"
id="bracketThicknessValue"
class="value-display"
value="3"
/>
<div class="value-with-unit">
<input
type="number"
id="bracketThicknessValue"
class="value-display"
value="3"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="control-group">
<label for="ribbingCount">Rib Count</label>
Expand All @@ -135,7 +189,7 @@ <h1>Bracket.Engineer</h1>
<input
type="number"
id="ribbingCountValue"
class="value-display"
class="value-display no-unit"
value="3"
/>
</div>
Expand All @@ -150,12 +204,15 @@ <h1>Bracket.Engineer</h1>
step="0.5"
value="2"
/>
<input
type="number"
id="ribbingThicknessValue"
class="value-display"
value="2"
/>
<div class="value-with-unit">
<input
type="number"
id="ribbingThicknessValue"
class="value-display"
value="2"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="control-group">
<label for="holeDiameter">Hole Diameter</label>
Expand All @@ -168,12 +225,15 @@ <h1>Bracket.Engineer</h1>
step="0.5"
value="2"
/>
<input
type="number"
id="holeDiameterValue"
class="value-display"
value="4"
/>
<div class="value-with-unit">
<input
type="number"
id="holeDiameterValue"
class="value-display"
value="4"
/>
<span class="unit">mm</span>
</div>
</div>
<div class="control-group">
<label for="holeCount">Hole Count</label>
Expand All @@ -189,7 +249,7 @@ <h1>Bracket.Engineer</h1>
<input
type="number"
id="holeCountValue"
class="value-display"
class="value-display no-unit"
value="1"
/>
</div>
Expand All @@ -200,16 +260,19 @@ <h1>Bracket.Engineer</h1>
id="earWidth"
name="earWidth"
min="5"
max="30"
max="40"
step="1"
value="15"
/>
<input
type="number"
id="earWidthValue"
class="value-display"
value="15"
value="10"
/>
<div class="value-with-unit">
<input
type="number"
id="earWidthValue"
class="value-display"
value="10"
/>
<span class="unit">mm</span>
</div>
</div>

<div class="control-group collection">
Expand Down
14 changes: 7 additions & 7 deletions psu-bracket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,15 @@ function calculateSpacing({
}

export const defaultParams: BracketParams = {
width: 35.5,
depth: 16,
height: 15,
width: 200,
depth: 25,
height: 16,
holeDiameter: 2,
earWidth: 10,
bracketThickness: 1,
ribbingThickness: 1,
ribbingCount: 0,
bracketThickness: 3,
ribbingThickness: 2,
ribbingCount: 3,
hasBottom: false,
holeCount: 2,
holeCount: 1,
keyHole: false,
};
Loading