First draft
This commit is contained in:
commit
7efceaa6c1
31
idpa.svg
Normal file
31
idpa.svg
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<svg version="1.1" width="446" height="767" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(2.5, 2.5)">
|
||||||
|
<g stroke-width="2.5" stroke="black" fill-opacity="0">
|
||||||
|
<!-- IDPA is specified in inches. Coords are rounded to the nearest mm because I'm lazy. -->
|
||||||
|
<!-- Outer border -->
|
||||||
|
<polygon points="144,0 297,0 297,152 391,152 441,229 441,635 373,762 68,762 0,635 0,229 51,152 144,152" />
|
||||||
|
|
||||||
|
<!-- Inner border -->
|
||||||
|
<polygon points="144,152 297,152 373,229 373,483 297,610 144,610 68,483 68,229" />
|
||||||
|
|
||||||
|
<!-- Lower circle -->
|
||||||
|
<circle cx="221" cy="330" r="102" />
|
||||||
|
|
||||||
|
<!-- Upper circle -->
|
||||||
|
<circle cx="221" cy="76" r="51" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g text-anchor="middle" dominant-baseline="middle" font-size="24" font-weight="bold" font-family="sans-serif">
|
||||||
|
<text x="221" y="76">−0</text>
|
||||||
|
<text x="221" y="330">−0</text>
|
||||||
|
|
||||||
|
<text x="272" y="22">−1</text>
|
||||||
|
<text x="221" y="191">−1</text>
|
||||||
|
<text x="221" y="521">−1</text>
|
||||||
|
|
||||||
|
<text x="34" y="330">−3</text>
|
||||||
|
<text x="407" y="330">−3</text>
|
||||||
|
<text x="221" y="685">−0</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
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>
|
22
ipsc.svg
Normal file
22
ipsc.svg
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<svg version="1.1" width="455" height="575" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(2.5, 2.5)">
|
||||||
|
<g stroke-width="2.5" stroke="black" fill-opacity="0">
|
||||||
|
<!-- D zone -->
|
||||||
|
<polygon points="150,0 300,0 450,190 450,380 300,570 150,570 0,380 0,190" />
|
||||||
|
|
||||||
|
<!-- C zone -->
|
||||||
|
<polygon points="150,0 300,0 375,190 375,335 275,450 175,450 75,335 75,190" />
|
||||||
|
|
||||||
|
<!-- A zone -->
|
||||||
|
<polygon points="200,25 250,25 300,190 300,275 250,350 200,350 150,275 150,190" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g text-anchor="middle" font-size="24" font-weight="bold" font-family="sans-serif">
|
||||||
|
<text x="38" y="190">D</text>
|
||||||
|
<text x="115" y="190">C</text>
|
||||||
|
<text x="225" y="190">A</text>
|
||||||
|
<text x="335" y="190">C</text>
|
||||||
|
<text x="412" y="190">D</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 763 B |
28
uspsa.svg
Normal file
28
uspsa.svg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<svg version="1.1" width="455" height="755" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="translate(2.5, 2.5)">
|
||||||
|
<g stroke-width="2.5" stroke="black" fill-opacity="0">
|
||||||
|
<!-- D/B zones -->
|
||||||
|
<polygon points="150,0 300,0 300,150 400,150 450,200 450,600 375,750 75,750 0,600 0,200 50,150 150,150" />
|
||||||
|
|
||||||
|
<!-- C zone -->
|
||||||
|
<polygon points="150,150 300,150 375,200 375,480 325,600 125,600 75,480 75,200" />
|
||||||
|
|
||||||
|
<!-- A zone body -->
|
||||||
|
<rect x="150" y="200" width="150" height="280" />
|
||||||
|
|
||||||
|
<!-- A zone head -->
|
||||||
|
<rect x="175" y="25" width="100" height="50" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g text-anchor="middle" dominant-baseline="middle" font-size="24" font-weight="bold" font-family="sans-serif">
|
||||||
|
<text x="225" y="50">A</text>
|
||||||
|
<text x="225" y="112.5">B</text>
|
||||||
|
|
||||||
|
<text x="37.5" y="340">D</text>
|
||||||
|
<text x="112.5" y="340">C</text>
|
||||||
|
<text x="225" y="340">A</text>
|
||||||
|
<text x="337.5" y="340">C</text>
|
||||||
|
<text x="412.5" y="340">D</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 953 B |
Loading…
Reference in New Issue
Block a user