JSFiddle - React, Tailwind, and code Playground
by AntowaKartowa
HTML
<div class="container">
<form name="calcCup">
<h3>Base Angle</h3>
<div class="checkbox-box">
<input type="checkbox" name="apply-base-angle" id="сBaseAngle" class="checkbox-input" />Use base angle
</div>
<input type="number" step="0.1" name="base-angle" id="nBaseAngle" placeholder="Base Angle" />
<hr>
<h3>Base Cup</h3>
<div class="checkbox-box">
<input type="checkbox" name="apply-base-dimensions" id="cBaseDimensions" class="checkbox-input" />Use base cup dimensions
</div>
<input type="number" step="0.25" name="base-bottom-radius" id="nBaseBottomR" placeholder="Bottom Radius (mm)" value="18" />
<input type="number" step="0.25" name="base-top-radius" id="nBaseTopR" placeholder="Top Radius (mm)" value="24.5" />
<input type="number" step="0.05" name="base-height" id="nBaseHeight" placeholder="Height (mm)" value="56" />
<hr>
<h3>New Cup Dimensions</h3>
<input type="number" step="0.25" name="bottom-radius" id="nBottomR" placeholder="Bottom Radius (mm)">
<input type="number" step="0.25" name="top-radius" id="nTopR" placeholder="Top Radius (mm)">
<input type="number" step="0.05" name="height" id="nHeight" placeholder="Full Height (mm)">
<hr>
<h3>Inner Step</h3>
<div class="checkbox-box">
<input type="checkbox" name="apply-inner-step" id="cInnerStep" class="checkbox-input" />Add inner step
</div>
<input type="number" step="0.25" name="inner-step-height" id="nInnerStepH" placeholder="Inner Step Height (mm) - Excluding from Full Height" value="0" />
<input type="number" step="0.25" name="inner-step-angle" id="nInnerStepA" placeholder="Inner Step Angle" value="0" />
<hr>
<h3>Desired Volume</h3>
<div class="checkbox-box">
<input type="checkbox" name="apply-volume-constraints" id="cVolume" class="checkbox-input" />Calculate by volume
</div>
<input type="number" step="0.05" name="desired-volume" id="nVolume" placeholder="Volume (ml)" />
<hr>
...
SCSS
.checkbox {
&-box {
margin-bottom: 10px;
}
&-input {
vertical-align: middle;
margin: 0 5px 0 0;
}
}
input[type="number"] {
margin: 0 10px 10px 0;
}
JavaScript 1.7
const form = document.forms.calcCup;
form.onsubmit = e => {
e.preventDefault();
e.stopPropagation();
};
const {
сBaseAngle, nBaseAngle,
cBaseDimensions, nBaseBottomR, nBaseTopR, nBaseHeight,
nBottomR, nTopR, nHeight,
cInnerStep, nInnerStepH, nInnerStepA,
cVolume, nVolume,
calc, clear,
results,
} = [...form].reduce((result, ctrl) => ({ ...result, [ctrl.id]: ctrl }), {});
const getAngle = (h, R, r) => {
const diff = R - r;
return (Math.atan2(diff, h) * 180) / Math.PI;
};
const getGreaterRadius = (height, deg, base = 0) => {
const rad = deg * Math.PI/180;
return Math.tan(rad) * height + parseFloat(base);
};
const getTruncConeVolume = (h, R, r) => {
// V = 1/3 * Pi * h * (R^2+Rr+r^2)
if (!h || !R) {
return 0;
} else if (r === undefined) {
return (Math.PI * Math.pow(R, 2) * h) / 1000;
} else {
return ((1 / 3) * Math.PI * h * (Math.pow(R, 2) + R * r + Math.pow(r, 2))) / 1000;
}
};
const getBaseAngle = () => {
return (сBaseAngle.checked || cBaseDimensions.checked)
? сBaseAngle.checked && nBaseAngle.value || getAngle(nBaseHeight.value, nBaseTopR.value, nBaseBottomR.value)
: getAngle(nHeight.value, nTopR.value, nBottomR.value);
};
const getTopRadius = (height, deg, base) => {
return (сBaseAngle.checked || cBaseDimensions.checked)
? getGreaterRadius(height, deg, base)
: nTopR.value || nBaseTopR.value;
};
const printResulst = (result) => {
results.value += result;
};
const clearHandler = () => results.value = '';
const calcHandler = () => {
const baseAngle = getBaseAngle(),
stepAngle = cInnerStep.checked && nInnerStepA.value || baseAngle,
bottomRadius = nBottomR.value || nBaseBottomR.value,
stepHeight = cInnerStep.checked ? (nInnerStepH.value || 0) : 0,
height = (nHeight.value || nBaseHeight.value) - stepHeight,
topRadius = getTopRadius(height, baseAngle, bottomRadius),
stepTopRadius = getTopRadius(stepHeight, stepAngle, topRadius + 1),
...