junkerstock
 簡易的な計算機5 

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>単位固定電卓</title>
<style>
/* 基本設定 */
* {
box-sizing: border-box;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
body {
margin: 0;
padding: 0;
height: 100dvh;
width: 100vw;
display: flex;
flex-direction: column;
background-color: #000;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
overflow: hidden;
}

/* 計算結果画面 */
#display-container {
flex: 0 0 25%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
padding: 20px;
padding-top: 50px;
position: relative;
}

/* 画面右上の単位表示 */
#unit-label {
color: #ff9f0a;
font-size: 1.2rem;
margin-bottom: 5px;
/* 最初から表示しておく */
opacity: 1;
transition: opacity 0.3s;
}

#display {
width: 100%;
background: transparent;
border: none;
color: white;
font-size: 4rem;
text-align: right;
outline: none;
font-weight: 300;
padding: 0;
margin: 0;
}

/* ボタンエリア */
.buttons {
flex: 1;
padding-bottom: calc(40px + env(safe-area-inset-bottom));
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(5, 1fr);
gap: 12px;
padding-left: 15px;
padding-right: 15px;
}

button {
border: none;
font-size: 2rem;
border-radius: 1000px;
cursor: pointer;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.1s;
height: 100%;
}

button:active {
filter: brightness(0.8);
transform: scale(0.98);
}

.number { background-color: #333333; }
.operator { background-color: #ff9f0a; font-size: 2.5rem; }
.func { background-color: #a5a5a5; color: black; font-weight: 500; }

.zero-btn {
grid-column: span 2;
justify-content: flex-start;
padding-left: 35px;
}

.time-btn {
background-color: #a5a5a5;
color: black;
font-size: 1.4rem;
font-weight: bold;
}

</style>
</head>
<body>

<div id="display-container">
<div id="unit-label">分</div>
<input type="text" id="display" readonly value="0">
</div>

<div class="buttons">
<button class="func" onclick="clearDisplay()">C</button>
<button class="func" onclick="deleteLast()">←</button>

<button class="time-btn" id="btn-time" onclick="cycleTime()">分</button>

<button class="operator" onclick="appendDisplay('/')">÷</button>

<button class="number" onclick="appendDisplay('7')">7</button>
<button class="number" onclick="appendDisplay('8')">8</button>
<button class="number" onclick="appendDisplay('9')">9</button>
<button class="operator" onclick="appendDisplay('*')">×</button>

<button class="number" onclick="appendDisplay('4')">4</button>
<button class="number" onclick="appendDisplay('5')">5</button>
<button class="number" onclick="appendDisplay('6')">6</button>
<button class="operator" onclick="appendDisplay('-')">−</button>

<button class="number" onclick="appendDisplay('1')">1</button>
<button class="number" onclick="appendDisplay('2')">2</button>
<button class="number" onclick="appendDisplay('3')">3</button>
<button class="operator" onclick="appendDisplay('+')">+</button>

<button class="number zero-btn" onclick="appendDisplay('0')">0</button>
<button class="number" onclick="appendDisplay('.')">.</button>
<button class="operator" onclick="calculateResult()">=</button>
</div>

<script>
const display = document.getElementById('display');
const unitLabel = document.getElementById('unit-label');
const btnTime = document.getElementById('btn-time');
const operators = ['/', '*', '-', '+'];

// 順番を変更しました:分スタート
// 0:分 -> 1:時間 -> 2:日 -> 3:年 -> 4:秒 -> (戻る)0:分
const unitNames = ["分", "時間", "日", "年", "秒"];
let timeState = 0;

function appendDisplay(input) {
// ★以前あった resetTimeMode() を削除しました
// これにより、数字を押しても単位が維持されます

const currentVal = display.value;
const lastChar = currentVal.slice(-1);

if (currentVal === '0' && !operators.includes(input) && input !== '.') {
display.value = input;
return;
}

if (operators.includes(input) && operators.includes(lastChar)) {
return;
}

display.value += input;
}

function clearDisplay() {
display.value = "0";
// Cを押しても単位は変えない
}

function deleteLast() {
if (display.value.length > 1) {
display.value = display.value.slice(0, -1);
} else {
display.value = "0";
}
}

function cycleTime() {
try {
let val = parseFloat(eval(display.value));

// 現在の単位(timeState)から、次の単位へ変換する処理

if (timeState === 0) {
// 分 → 時間
val = val / 60;
} else if (timeState === 1) {
// 時間 → 日
val = val / 24;
} else if (timeState === 2) {
// 日 → 年
val = val / 365;
} else if (timeState === 3) {
// 年 → 秒 (365日*24時間*60分*60秒)
val = val * 365 * 24 * 60 * 60;
} else if (timeState === 4) {
// 秒 → 分
val = val / 60;
}

// 次のステートへ進める
timeState++;
if (timeState >= unitNames.length) {
timeState = 0;
}

display.value = val;
updateUnitDisplay();

} catch (e) {
display.value = "Error";
}
}

function updateUnitDisplay() {
btnTime.innerText = unitNames[timeState];
unitLabel.innerText = unitNames[timeState];
}

function calculateResult() {
try {
let expression = display.value;
display.value = new Function('return ' + expression)();
// 計算後も単位は維持
} catch (error) {
display.value = "Error";
}
}
</script>
</body>
</html>


使用変数

appendDisplay -------( Function )
btnTime
calculateResult -------( Function )
charset
class
clearDisplay -------( Function )
content
currentVal
cycleTime -------( Function )
deleteLast -------( Function )
display
expression
fit
id
innerText
lang
lastChar
name
onclick
operators
scalable
scale
timeState
type
unitLabel
unitNames
updateUnitDisplay -------( Function )
val
value
width