238 lines
11 KiB
HTML
238 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Ballistics Calculator – ShooterHub</title>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||
<link rel="stylesheet" href="/css/app.css">
|
||
<style>
|
||
.input-section { background: #f8f9fa; border-radius: 8px; padding: .9rem 1rem; margin-bottom: .6rem; }
|
||
.input-section h6 { margin-bottom: .6rem; }
|
||
.traj-table td, .traj-table th { font-size: .8rem; white-space: nowrap; padding: .25rem .5rem; }
|
||
.traj-table tr.zero-row td { background: #fff3cd; font-weight: 600; }
|
||
.traj-table tr.subsonic td { color: #868e96; font-style: italic; }
|
||
.legend-dot-zero { display: inline-block; width: 12px; height: 12px; background: #fff3cd; border: 1px solid #ffc107; border-radius: 2px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="navbar"></div>
|
||
|
||
<div class="container-fluid py-3">
|
||
<div class="row g-3">
|
||
|
||
<!-- ══ Input panel ══════════════════════════════════════════════════════ -->
|
||
<div class="col-md-4 col-xl-3">
|
||
<h5 class="fw-bold mb-3">
|
||
<i class="bi bi-bullseye me-2 text-primary"></i>Ballistics Calculator
|
||
</h5>
|
||
|
||
<!-- Bullet -->
|
||
<div class="input-section">
|
||
<h6 class="fw-semibold"><i class="bi bi-dot me-1"></i>Bullet</h6>
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">Muzzle velocity *</label>
|
||
<input type="number" class="form-control form-control-sm" id="v0" value="823" min="100" max="2000" step="1">
|
||
</div>
|
||
<div class="col-5">
|
||
<label class="form-label form-label-sm mb-1">Unit</label>
|
||
<select class="form-select form-select-sm" id="v0Unit">
|
||
<option value="ms">m/s</option>
|
||
<option value="fps">fps</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">BC *</label>
|
||
<input type="number" class="form-control form-control-sm" id="bc" value="0.279" min="0.01" max="2" step="0.001">
|
||
</div>
|
||
<div class="col-5">
|
||
<label class="form-label form-label-sm mb-1">Drag model</label>
|
||
<select class="form-select form-select-sm" id="dragModel">
|
||
<option value="G7">G7</option>
|
||
<option value="G1">G1</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">Weight (gr) — for energy</label>
|
||
<input type="number" class="form-control form-control-sm" id="bulletWeight" placeholder="optional" min="1" max="1000" step="1">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Rifle Setup -->
|
||
<div class="input-section">
|
||
<h6 class="fw-semibold"><i class="bi bi-crosshair me-1"></i>Rifle Setup</h6>
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">Zero distance *</label>
|
||
<input type="number" class="form-control form-control-sm" id="zeroDist" value="100" min="10" max="1000" step="5">
|
||
</div>
|
||
<div class="col-5">
|
||
<label class="form-label form-label-sm mb-1">Unit</label>
|
||
<select class="form-select form-select-sm" id="zeroUnit">
|
||
<option value="m">m</option>
|
||
<option value="yd">yd</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">Scope height (mm)</label>
|
||
<input type="number" class="form-control form-control-sm" id="scopeHeight" value="50" min="0" max="200" step="1">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Atmosphere (collapsible) -->
|
||
<div class="input-section">
|
||
<h6 class="fw-semibold" role="button" data-bs-toggle="collapse" data-bs-target="#atmoCollapse" style="cursor:pointer">
|
||
<i class="bi bi-cloud me-1"></i>Atmosphere
|
||
<i class="bi bi-chevron-down small ms-1"></i>
|
||
</h6>
|
||
<div id="atmoCollapse" class="collapse show">
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Temperature</label>
|
||
<div class="input-group input-group-sm">
|
||
<input type="number" class="form-control" id="temp" value="15" step="1">
|
||
<select class="form-select" id="tempUnit" style="max-width:52px">
|
||
<option value="c">°C</option>
|
||
<option value="f">°F</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Pressure (hPa)</label>
|
||
<input type="number" class="form-control form-control-sm" id="pressure" value="1013.25" min="700" max="1100" step="1">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2">
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Humidity (%)</label>
|
||
<input type="number" class="form-control form-control-sm" id="humidity" value="50" min="0" max="100" step="5">
|
||
</div>
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Altitude (m)</label>
|
||
<input type="number" class="form-control form-control-sm" id="altitude" placeholder="0" min="0" max="5000" step="100">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Wind -->
|
||
<div class="input-section">
|
||
<h6 class="fw-semibold"><i class="bi bi-wind me-1"></i>Wind</h6>
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-7">
|
||
<label class="form-label form-label-sm mb-1">Speed</label>
|
||
<input type="number" class="form-control form-control-sm" id="windSpeed" value="0" min="0" step="0.5">
|
||
</div>
|
||
<div class="col-5">
|
||
<label class="form-label form-label-sm mb-1">Unit</label>
|
||
<select class="form-select form-select-sm" id="windUnit">
|
||
<option value="ms">m/s</option>
|
||
<option value="kph">km/h</option>
|
||
<option value="mph">mph</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label class="form-label form-label-sm mb-1">
|
||
Direction
|
||
<span class="text-muted small">(0° = head · 90° = from right · 180° = tail)</span>
|
||
</label>
|
||
<div class="input-group input-group-sm">
|
||
<input type="number" class="form-control" id="windDir" value="90" min="0" max="360" step="15">
|
||
<span class="input-group-text">°</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Output -->
|
||
<div class="input-section">
|
||
<h6 class="fw-semibold"><i class="bi bi-table me-1"></i>Output</h6>
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Correction unit</label>
|
||
<select class="form-select form-select-sm" id="outputUnit">
|
||
<option value="MRAD">MRAD (mil)</option>
|
||
<option value="MOA">MOA</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">Step</label>
|
||
<div class="input-group input-group-sm">
|
||
<input type="number" class="form-control" id="distStep" value="25" min="5" max="200" step="5">
|
||
<span class="input-group-text" id="distStepUnit">m</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2">
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">From</label>
|
||
<input type="number" class="form-control form-control-sm" id="distFrom" value="0" min="0" step="25">
|
||
</div>
|
||
<div class="col-6">
|
||
<label class="form-label form-label-sm mb-1">To</label>
|
||
<input type="number" class="form-control form-control-sm" id="distTo" value="800" min="25" max="3000" step="25">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="calcAlert" class="alert alert-danger d-none small py-2 mb-2"></div>
|
||
<button class="btn btn-primary w-100 fw-semibold" onclick="calculate()">
|
||
<i class="bi bi-calculator me-1"></i>Calculate
|
||
</button>
|
||
</div>
|
||
|
||
<!-- ══ Results panel ═════════════════════════════════════════════════════ -->
|
||
<div class="col-md-8 col-xl-9">
|
||
<!-- Placeholder -->
|
||
<div id="resultsPlaceholder" class="d-flex align-items-center justify-content-center text-muted" style="min-height:400px">
|
||
<div class="text-center">
|
||
<i class="bi bi-bullseye display-3 mb-3 d-block opacity-25"></i>
|
||
<p class="mb-0">Fill in the parameters on the left and click <strong>Calculate</strong>.</p>
|
||
<p class="small text-muted mt-1">No account required — all computation is done locally in the browser.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Trajectory output -->
|
||
<div id="resultsSection" class="d-none">
|
||
<div class="d-flex align-items-center gap-3 mb-2 flex-wrap">
|
||
<h6 class="fw-semibold mb-0">Trajectory</h6>
|
||
<span class="text-muted small" id="resultsSummary"></span>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-hover traj-table align-middle mb-1" id="trajTable">
|
||
<thead class="table-dark sticky-top">
|
||
<tr id="trajHead"></tr>
|
||
</thead>
|
||
<tbody id="trajBody"></tbody>
|
||
</table>
|
||
</div>
|
||
<div class="d-flex gap-3 small text-muted mt-1 flex-wrap">
|
||
<span><span class="legend-dot-zero me-1"></span>★ Zero distance</span>
|
||
<span><em>Italic</em> = subsonic (< 340 m/s)</span>
|
||
<span>Drop: negative = bullet below LOS; correction = dial/hold up (+)</span>
|
||
<span>Wind: L / R indicates drift direction</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||
<script src="/js/api.js"></script>
|
||
<script src="/js/i18n.js"></script>
|
||
<script src="/js/nav.js"></script>
|
||
<script src="/js/ballistics.js"></script>
|
||
</body>
|
||
</html>
|