dry-fire-target-maker/index.html

121 lines
2.8 KiB
HTML
Raw Normal View History

2023-02-14 06:21:19 +00:00
<!DOCTYPE html>
<html>
<head>
<title>Target scaler</title>
<style>
body {
max-width: 70em;
}
input {
margin-left: 1em;
}
.complex-radio {
display: inline-block;
text-align: center;
vertical-align: top;
}
.complex-radio img {
width: 10em;
}
#print {
width: 100%;
}
#print .target {
display: block;
margin-left: auto;
margin-right: auto;
}
@media screen {
#print {
display: none;
}
}
@media print {
#ui {
display: none;
}
}
</style>
</head>
<body>
<div id="ui">
<h1>Dry Fire Target Maker</h1>
<p>
Scale the target by setting the simulated and actual distances to the target in any unit of length.
For example, if you want the target to appear as if it is 15 yards away when you are actually
only 3 yards from the target, set <em>Simulated distance</em> to 15 and <em>Actual distance</em>
to 3.
</p>
<p>
<label>Simulated distance<input id="simulated-range" type="number" value="40"></label>
</p>
<p>
<label>Actual distance<input id="actual-range" type="number" value="3"></label>
</p>
<fieldset role="radiogroup" id="target-styles">
<legend>Target style</legend>
<label><input type="radio" name="target-style" checked>
<div class="complex-radio">
<div>USPSA</div><img class="target" src="uspsa.svg">
</div>
</label>
<label><input type="radio" name="target-style">
<div class="complex-radio">
<div>IDPA</div><img class="target" src="idpa.svg">
</div>
</label>
<label><input type="radio" name="target-style">
<div class="complex-radio">
<div>IPSC</div><img class="target" src="ipsc.svg">
</div>
</label>
</fieldset>
<p>
<button id="print-button">Print</button>
</p>
</div>
<div id="print">
<img class="target">
</div>
<script>
{
let target = document.querySelector("#print .target");
let simulatedRange = document.getElementById("simulated-range");
let actualRange = document.getElementById("actual-range");
const updateScale = () => {
let scale = actualRange.value / simulatedRange.value;
target.style.width = target.naturalWidth * scale + "mm";
}
simulatedRange.addEventListener("change", updateScale);
actualRange.addEventListener("change", updateScale);
target.addEventListener("load", updateScale);
document.getElementById("print-button").addEventListener("click", print.bind(window));
const updateTargetStyle = () => {
const checked = document.querySelector("#target-styles input[type=radio]:checked");
const src = checked.labels[0].getElementsByTagName("img")[0].src;
target.src = src;
};
document.querySelectorAll("#target-styles label").forEach((label) => {
label.addEventListener("change", updateTargetStyle);
});
updateTargetStyle();
}
</script>
</body>
</html>