First draft
This commit is contained in:
121
index.html
Normal file
121
index.html
Normal file
@ -0,0 +1,121 @@
|
||||
<!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>
|
Reference in New Issue
Block a user