Files
bowlingManager/frontend/public/bowlspeed/index.html
T

553 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>볼링공 속도 계산기</title>
<style>
body {
font-family: 'Nanum Gothic', Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 20px;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2c3e50;
text-align: center;
margin-bottom: 30px;
}
.description {
background-color: #eaf2f8;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
line-height: 1.6;
}
.calculator {
background-color: #f9f9f9;
padding: 20px;
border-radius: 5px;
border: 1px solid #ddd;
}
.input-group {
margin-bottom: 15px;
}
label {
display: inline-block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"], input[type="number"] {
width: 100px;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
text-align: right;
}
.result-input {
width: 100px;
text-align: right;
}
.distance-container {
display: flex;
justify-content: space-between;
gap: 20px;
}
.distance-half {
flex: 1;
}
.buttons {
margin: 20px 0;
text-align: center;
}
button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin: 0 10px;
}
button:hover {
background-color: #2980b9;
}
.results {
margin-top: 20px;
background-color: #f0f8ff;
padding: 15px;
border-radius: 5px;
border: 1px solid #b3d8ff;
}
.result-item {
margin-bottom: 10px;
font-size: 16px;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.result-item span:first-child {
min-width: 120px;
margin-right: 5px;
}
.result-item .unit {
min-width: 40px;
text-align: left;
margin-left: 5px;
}
@media (max-width: 480px) {
.result-item {
font-size: 14px;
}
.result-item span:first-child {
min-width: 100px;
}
input[type="text"], input[type="number"], .result-input {
width: 90px;
}
}
.result-value {
font-weight: bold;
color: #2980b9;
margin-left: 10px;
}
footer {
margin-top: 30px;
text-align: center;
font-size: 14px;
color: #777;
}
.stopwatch {
background-color: #e8f4fc;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
border: 1px solid #b3d8ff;
}
.stopwatch-display {
font-size: 24px;
font-weight: bold;
text-align: center;
margin: 10px 0;
color: #2c3e50;
font-family: monospace;
}
.stopwatch-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
.toggle-btn {
width: 120px;
height: 120px;
border-radius: 50%;
background-color: #27ae60;
font-size: 22px;
font-weight: bold;
margin-bottom: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
}
.toggle-btn.running {
background-color: #e74c3c;
}
.toggle-btn:hover {
background-color: #219653;
transform: scale(1.05);
}
.toggle-btn.running:hover {
background-color: #c0392b;
}
.reset-btn {
background-color: #f39c12;
font-size: 16px;
padding: 8px 16px;
margin-top: 10px;
}
.reset-btn:hover {
background-color: #d35400;
}
</style>
</head>
<body>
<div class="container">
<h1>볼링공 속도 계산기</h1>
<div class="description">
<p>이 계산기는 볼링공이 파울라인에서 헤드핀까지 이동하는 속도를 계산합니다.</p>
<p>시간 입력 또는 원하는 속도 입력으로 양방향 계산이 가능합니다. 볼링 레인의 기본 거리는 60피트(18.288미터)입니다.</p>
</div>
<div class="stopwatch">
<h3>스톱워치</h3>
<p>볼링공이 파울라인을 지날 때 '시작'을 누르고, 헤드핀에 도달할 때 '정지'를 누르세요.</p>
<div class="stopwatch-display" id="stopwatch-display">00:00.000</div>
<div class="stopwatch-container">
<button class="toggle-btn" id="toggle-btn">시작</button>
<button class="reset-btn" id="reset-btn">초기화</button>
</div>
</div>
<div class="calculator">
<div class="input-group">
<label for="time">볼링공 이동 시간:</label>
<input type="number" id="time" step="0.001" value="2.000" min="0.001">
</div>
<div class="input-group distance-container">
<div class="distance-half">
<label for="distance-meters">거리 (미터):</label>
<input type="number" id="distance-meters" value="18.288" step="0.001" min="0.1" onchange="updateFeet()"> 미터
</div>
<div class="distance-half">
<label for="distance-feet">거리 (피트):</label>
<input type="number" id="distance-feet" value="60.00" step="0.01" min="1" onchange="updateMeters()"> 피트
</div>
</div>
<div class="buttons">
<button onclick="calculateSpeed()">계산하기</button>
<button onclick="resetValues()">초기화</button>
</div>
<div class="results" id="results">
<div class="result-item">
<span>시속 (킬로미터):</span>
<input type="number" class="result-input" id="kph" value="0" step="0.01" min="0" onchange="calculateTimeFromKPH()">
<span class="unit">KPH</span>
</div>
<div class="result-item">
<span>시속 (마일):</span>
<input type="number" class="result-input" id="mph" value="0" step="0.01" min="0" onchange="calculateTimeFromMPH()">
<span class="unit">MPH</span>
</div>
<div class="result-item">
<span>초속 (피트):</span>
<input type="number" class="result-input" id="fps" value="0" step="0.01" min="0" onchange="calculateTimeFromFPS()">
<span class="unit">FPS</span>
</div>
<div class="result-item">
<span>초속 (미터):</span>
<input type="number" class="result-input" id="mps" value="0" step="0.01" min="0" onchange="calculateTimeFromMPS()">
<span class="unit">MPS</span>
</div>
</div>
</div>
<footer>
<p> 2025 볼링공 속도 계산기</p>
</footer>
</div>
<script>
// 소수점 자릿수 반올림 함수
function perRound(num, precision) {
precision = precision || 3;
precision = parseInt(precision);
var result1 = num * Math.pow(10, precision);
var result2 = Math.round(result1);
var result3 = result2 / Math.pow(10, precision);
return zerosPad(result3, precision);
}
// 소수점 자릿수 0 채우기 함수
function zerosPad(rndVal, decPlaces) {
var valStrg = rndVal.toString();
var decLoc = valStrg.indexOf(".");
if (decLoc == -1) {
decPartLen = 0;
valStrg += decPlaces > 0 ? "." : "";
} else {
decPartLen = valStrg.length - decLoc - 1;
}
var totalPad = decPlaces - decPartLen;
if (totalPad > 0) {
for (var i = 1; i <= totalPad; i++) {
valStrg += "0";
}
}
return valStrg;
}
// 미터를 피트로 변환
function updateFeet() {
var meters = document.getElementById("distance-meters").value;
var feet = perRound(meters * 3.2808399, 2);
document.getElementById("distance-feet").value = feet;
}
// 피트를 미터로 변환
function updateMeters() {
var feet = document.getElementById("distance-feet").value;
var meters = perRound(feet * 0.3048, 3);
document.getElementById("distance-meters").value = meters;
}
// 속도 계산 함수
function calculateSpeed() {
var time = parseFloat(document.getElementById("time").value);
var distance = parseFloat(document.getElementById("distance-feet").value);
if (time <= 0) {
alert("시간은 0보다 커야 합니다.");
return;
}
if (distance <= 0) {
alert("거리는 0보다 커야 합니다.");
return;
}
// 속도 계산 (원본 코드의 공식 사용)
var mph = perRound((distance / time) * (3600 / 5280), 2);
var kph = perRound((distance / time) * (3600 * 0.0003048), 2);
var fps = perRound(distance / time, 2);
var mps = perRound((distance * 0.3048) / time, 2);
// 결과 표시 (입력 필드에 값 설정)
document.getElementById("mph").value = mph;
document.getElementById("kph").value = kph;
document.getElementById("fps").value = fps;
document.getElementById("mps").value = mps;
}
// 시속(KPH)에서 시간 계산
function calculateTimeFromKPH() {
var kph = parseFloat(document.getElementById("kph").value);
var distance = parseFloat(document.getElementById("distance-meters").value);
if (kph <= 0) {
alert("속도는 0보다 커야 합니다.");
return;
}
// KPH에서 시간(초) 계산: 거리(m) / 속도(m/s) = 시간(s)
// KPH를 m/s로 변환: kph * 1000 / 3600
var speedInMps = kph * 1000 / 3600;
var time = distance / speedInMps;
// 시간 설정 및 다른 속도 값 업데이트
document.getElementById("time").value = perRound(time, 3);
// 다른 속도 단위 계산
var distanceFeet = parseFloat(document.getElementById("distance-feet").value);
var mph = perRound((distanceFeet / time) * (3600 / 5280), 2);
var fps = perRound(distanceFeet / time, 2);
var mps = perRound(speedInMps, 2);
// 다른 속도 필드 업데이트 (무한 루프 방지를 위해 이벤트 발생 없이)
document.getElementById("mph").value = mph;
document.getElementById("fps").value = fps;
document.getElementById("mps").value = mps;
}
// 시속(MPH)에서 시간 계산
function calculateTimeFromMPH() {
var mph = parseFloat(document.getElementById("mph").value);
var distance = parseFloat(document.getElementById("distance-feet").value);
if (mph <= 0) {
alert("속도는 0보다 커야 합니다.");
return;
}
// MPH에서 시간(초) 계산: 거리(feet) / 속도(feet/s) = 시간(s)
// MPH를 feet/s로 변환: mph * 5280 / 3600
var speedInFps = mph * 5280 / 3600;
var time = distance / speedInFps;
// 시간 설정 및 다른 속도 값 업데이트
document.getElementById("time").value = perRound(time, 3);
// 다른 속도 단위 계산
var kph = perRound(mph * 1.60934, 2);
var fps = perRound(speedInFps, 2);
var mps = perRound(speedInFps * 0.3048, 2);
// 다른 속도 필드 업데이트
document.getElementById("kph").value = kph;
document.getElementById("fps").value = fps;
document.getElementById("mps").value = mps;
}
// 초속(FPS)에서 시간 계산
function calculateTimeFromFPS() {
var fps = parseFloat(document.getElementById("fps").value);
var distance = parseFloat(document.getElementById("distance-feet").value);
if (fps <= 0) {
alert("속도는 0보다 커야 합니다.");
return;
}
// FPS에서 시간(초) 계산: 거리(feet) / 속도(feet/s) = 시간(s)
var time = distance / fps;
// 시간 설정 및 다른 속도 값 업데이트
document.getElementById("time").value = perRound(time, 3);
// 다른 속도 단위 계산
var mph = perRound(fps * 3600 / 5280, 2);
var kph = perRound(fps * 0.3048 * 3.6, 2);
var mps = perRound(fps * 0.3048, 2);
// 다른 속도 필드 업데이트
document.getElementById("mph").value = mph;
document.getElementById("kph").value = kph;
document.getElementById("mps").value = mps;
}
// 초속(MPS)에서 시간 계산
function calculateTimeFromMPS() {
var mps = parseFloat(document.getElementById("mps").value);
var distance = parseFloat(document.getElementById("distance-meters").value);
if (mps <= 0) {
alert("속도는 0보다 커야 합니다.");
return;
}
// MPS에서 시간(초) 계산: 거리(m) / 속도(m/s) = 시간(s)
var time = distance / mps;
// 시간 설정 및 다른 속도 값 업데이트
document.getElementById("time").value = perRound(time, 3);
// 다른 속도 단위 계산
var distanceFeet = parseFloat(document.getElementById("distance-feet").value);
var fps = perRound(mps / 0.3048, 2);
var mph = perRound(mps * 2.23694, 2);
var kph = perRound(mps * 3.6, 2);
// 다른 속도 필드 업데이트
document.getElementById("mph").value = mph;
document.getElementById("kph").value = kph;
document.getElementById("fps").value = fps;
}
// 초기화 함수
function resetValues() {
document.getElementById("time").value = "2.000";
document.getElementById("distance-feet").value = "60.00";
document.getElementById("distance-meters").value = "18.288";
document.getElementById("mph").value = "0";
document.getElementById("kph").value = "0";
document.getElementById("fps").value = "0";
document.getElementById("mps").value = "0";
}
// 스톱워치 관련 변수
let stopwatchInterval;
let startTime;
let elapsedTime = 0;
let isRunning = false;
// 스톱워치 시작/정지 토글 함수
function toggleStopwatch() {
const toggleBtn = document.getElementById('toggle-btn');
if (!isRunning) {
// 시작
startTime = Date.now() - elapsedTime;
stopwatchInterval = setInterval(updateStopwatch, 10);
isRunning = true;
// 버튼 상태 변경
toggleBtn.textContent = '정지';
toggleBtn.classList.add('running');
} else {
// 정지
clearInterval(stopwatchInterval);
elapsedTime = Date.now() - startTime;
isRunning = false;
// 버튼 상태 변경
toggleBtn.textContent = '시작';
toggleBtn.classList.remove('running');
// 자동으로 시간 입력 및 계산
const seconds = elapsedTime / 1000;
document.getElementById('time').value = perRound(seconds, 3);
calculateSpeed();
}
}
// 스톱워치 초기화 함수
function resetStopwatch() {
clearInterval(stopwatchInterval);
elapsedTime = 0;
isRunning = false;
updateStopwatchDisplay();
// 버튼 상태 변경
const toggleBtn = document.getElementById('toggle-btn');
toggleBtn.textContent = '시작';
toggleBtn.classList.remove('running');
}
// 스톱워치 표시 업데이트 함수
function updateStopwatch() {
elapsedTime = Date.now() - startTime;
updateStopwatchDisplay();
}
// 스톱워치 시간 표시 형식 변환 함수
function updateStopwatchDisplay() {
const minutes = Math.floor(elapsedTime / 60000);
const seconds = Math.floor((elapsedTime % 60000) / 1000);
const milliseconds = elapsedTime % 1000;
const display = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(3, '0')}`;
document.getElementById('stopwatch-display').textContent = display;
}
// 페이지 로드 시 초기 계산 및 이벤트 리스너 설정
document.addEventListener("DOMContentLoaded", function() {
calculateSpeed();
// 스톱워치 버튼에 이벤트 리스너 추가
const toggleBtn = document.getElementById('toggle-btn');
const resetBtn = document.getElementById('reset-btn');
// mousedown과 touchstart 이벤트를 모두 추가하여 모바일과 데스크톱 모두 지원
toggleBtn.addEventListener('mousedown', toggleStopwatch);
toggleBtn.addEventListener('touchstart', function(e) {
e.preventDefault(); // 화면 스크롤 방지
toggleStopwatch();
});
resetBtn.addEventListener('mousedown', resetStopwatch);
resetBtn.addEventListener('touchstart', function(e) {
e.preventDefault();
resetStopwatch();
});
});
</script>
</body>
</html>