Skip to content

Instantly share code, notes, and snippets.

@HenkPoley
Created August 5, 2025 16:55
Show Gist options
  • Save HenkPoley/699fff468dd952bb5089fbab5ce92d90 to your computer and use it in GitHub Desktop.
Save HenkPoley/699fff468dd952bb5089fbab5ce92d90 to your computer and use it in GitHub Desktop.
'49m2 vloer-, muur-, en plafondoppervlakte!'
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<title>Kamer Afmetingen</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; max-width: 600px; margin: auto; }
.slider-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 5px; }
input[type=range] { width: 100%; }
input[type=range]:disabled { opacity: 0.5; }
/* Subtiel bewerkbaar target zonder spinner */
#target-input {
border: none;
background: transparent;
font-family: inherit;
font-size: inherit;
text-align: center;
padding: 0;
margin: 0 4px;
width: auto;
}
#target-input::-webkit-outer-spin-button,
#target-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
#target-input[type=number] { -moz-appearance: textfield; }
</style>
</head>
<body>
<h1>
Kameroppervlak Instellen (
<input type="number" id="target-input" min="0" step="0.1" value="49">
m²)
</h1>
<div class="slider-group">
<label for="fixed-select">Vaste dimensie:</label>
<select id="fixed-select">
<option value="none">Geen</option>
<option value="h" selected>Hoogte (h)</option>
<option value="b">Breedte (b)</option>
<option value="d">Diepte (d)</option>
</select>
</div>
<div class="slider-group">
<label>Hoogte h: <span id="h-val">2.2</span> m</label>
<input type="range" id="h-slider" min="1" max="5" step="0.1" value="2.2">
</div>
<div class="slider-group">
<label>Breedte b: <span id="b-val">2.0</span> m</label>
<input type="range" id="b-slider" min="1" max="5" step="0.1" value="2.0">
</div>
<div class="slider-group">
<label>Diepte d: <span id="d-val">3.5</span> m</label>
<input type="range" id="d-slider" min="1" max="5" step="0.1" value="3.5">
</div>
<h2>Totaal Oppervlak: <span id="total-val"></span> m²</h2>
<h2>Vloeroppervlak: <span id="floor-val"></span> m²</h2>
<script>
const targetInput = document.getElementById('target-input');
const fixedSelect = document.getElementById('fixed-select');
const sliders = {
h: document.getElementById('h-slider'),
b: document.getElementById('b-slider'),
d: document.getElementById('d-slider')
};
const displays = {
h: document.getElementById('h-val'),
b: document.getElementById('b-val'),
d: document.getElementById('d-val'),
total: document.getElementById('total-val'),
floor: document.getElementById('floor-val')
};
let TARGET = parseFloat(targetInput.value);
let lastChanged = null;
function resizeInput() {
const length = targetInput.value.length;
targetInput.style.width = `${Math.max(length, 1)}ch`;
}
function updateDisplay(type) {
displays[type].textContent = parseFloat(sliders[type].value).toFixed(1);
}
function computeTotal(h, b, d) {
return 2 * b * d + 2 * h * (b + d);
}
function computeFloor(b, d) {
return b * d;
}
function applyFixed() {
const fixed = fixedSelect.value;
Object.keys(sliders).forEach(key => {
sliders[key].disabled = (key === fixed);
});
}
function adjustSliderMax() {
// dynamische max: minstens 5, of sqrt(TARGET)+1
const dynMax = Math.max(5, Math.ceil(Math.sqrt(TARGET) + 1));
Object.values(sliders).forEach(slider => slider.max = dynMax);
}
function solveThird() {
const fixed = fixedSelect.value;
let h = parseFloat(sliders.h.value);
let b = parseFloat(sliders.b.value);
let d = parseFloat(sliders.d.value);
if (fixed === 'h' && lastChanged) {
if (lastChanged === 'b') {
d = (TARGET - 2 * h * b) / (2 * (b + h));
sliders.d.value = d;
} else if (lastChanged === 'd') {
b = (TARGET - 2 * h * d) / (2 * (d + h));
sliders.b.value = b;
}
} else if (fixed === 'b' && lastChanged) {
if (lastChanged === 'h') {
d = (TARGET - 2 * h * b) / (2 * (b + h));
sliders.d.value = d;
} else if (lastChanged === 'd') {
h = (TARGET - 2 * b * d) / (2 * (b + d));
sliders.h.value = h;
}
} else if (fixed === 'd' && lastChanged) {
if (lastChanged === 'h') {
b = (TARGET - 2 * h * d) / (2 * (d + h));
sliders.b.value = b;
} else if (lastChanged === 'b') {
h = (TARGET - 2 * b * d) / (2 * (b + d));
sliders.h.value = h;
}
}
updateDisplay('h'); updateDisplay('b'); updateDisplay('d');
}
function updateAll(e) {
TARGET = parseFloat(targetInput.value) || 0;
resizeInput();
adjustSliderMax();
if (e.target && ['h-slider','b-slider','d-slider'].includes(e.target.id)) {
lastChanged = e.target.id.charAt(0);
}
applyFixed();
solveThird();
const h = parseFloat(sliders.h.value);
const b = parseFloat(sliders.b.value);
const d = parseFloat(sliders.d.value);
displays.total.textContent = computeTotal(h, b, d).toFixed(2);
displays.floor.textContent = computeFloor(b, d).toFixed(2);
}
Object.values(sliders).forEach(slider => slider.addEventListener('input', updateAll));
fixedSelect.addEventListener('change', updateAll);
targetInput.addEventListener('input', updateAll);
// initial setup
resizeInput();
updateAll({});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment