modularize
This commit is contained in:
243
webroot/js/calculator.js
Normal file
243
webroot/js/calculator.js
Normal file
@@ -0,0 +1,243 @@
|
||||
// Hex calculator functionality
|
||||
|
||||
export class Calculator {
|
||||
constructor() {
|
||||
this.state = {
|
||||
currentValue: 0,
|
||||
previousValue: 0,
|
||||
operation: null,
|
||||
waitingForOperand: false
|
||||
};
|
||||
}
|
||||
|
||||
updateDisplay() {
|
||||
const value = Math.max(0, Math.min(Math.floor(this.state.currentValue), Number.MAX_SAFE_INTEGER));
|
||||
|
||||
const hexStr = '0x' + value.toString(16).toUpperCase();
|
||||
const decStr = value.toString(10);
|
||||
const binStr = '0b' + value.toString(2);
|
||||
|
||||
// Update all calculator displays (for current active tab)
|
||||
const inputs = document.querySelectorAll('[id*="calcInput"]');
|
||||
const hexElements = document.querySelectorAll('[id*="hexValue"]');
|
||||
const decElements = document.querySelectorAll('[id*="decValue"]');
|
||||
const binElements = document.querySelectorAll('[id*="binValue"]');
|
||||
|
||||
inputs.forEach(input => input.value = hexStr);
|
||||
hexElements.forEach(el => el.textContent = hexStr);
|
||||
decElements.forEach(el => el.textContent = decStr);
|
||||
binElements.forEach(el => el.textContent = binStr);
|
||||
}
|
||||
|
||||
input(digit) {
|
||||
if (this.state.waitingForOperand) {
|
||||
this.state.currentValue = 0;
|
||||
this.state.waitingForOperand = false;
|
||||
}
|
||||
|
||||
const digitValue = parseInt(digit, 16);
|
||||
if (isNaN(digitValue)) return;
|
||||
|
||||
const newValue = this.state.currentValue * 16 + digitValue;
|
||||
if (newValue <= Number.MAX_SAFE_INTEGER && newValue >= 0) {
|
||||
this.state.currentValue = newValue;
|
||||
}
|
||||
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
operation(operation) {
|
||||
if (this.state.previousValue !== 0 && !this.state.waitingForOperand) {
|
||||
this.equals(false);
|
||||
}
|
||||
|
||||
this.state.previousValue = this.state.currentValue;
|
||||
this.state.operation = operation;
|
||||
this.state.waitingForOperand = true;
|
||||
}
|
||||
|
||||
equals(updateDisplay = true) {
|
||||
if (this.state.operation && this.state.previousValue !== null) {
|
||||
const prev = Math.floor(this.state.previousValue);
|
||||
const curr = Math.floor(this.state.currentValue);
|
||||
|
||||
try {
|
||||
let result = 0;
|
||||
switch (this.state.operation) {
|
||||
case '+':
|
||||
result = prev + curr;
|
||||
break;
|
||||
case '-':
|
||||
result = prev - curr;
|
||||
break;
|
||||
case '*':
|
||||
result = prev * curr;
|
||||
break;
|
||||
case '/':
|
||||
if (curr === 0) {
|
||||
alert('Division durch Null!');
|
||||
return;
|
||||
}
|
||||
result = Math.floor(prev / curr);
|
||||
break;
|
||||
case 'MOD':
|
||||
if (curr === 0) {
|
||||
alert('Modulo durch Null!');
|
||||
return;
|
||||
}
|
||||
result = prev % curr;
|
||||
break;
|
||||
}
|
||||
|
||||
this.state.currentValue = Math.max(0, Math.min(result, Number.MAX_SAFE_INTEGER));
|
||||
|
||||
} catch (error) {
|
||||
alert('Berechnungsfehler: ' + error.message);
|
||||
this.state.currentValue = 0;
|
||||
}
|
||||
|
||||
this.state.operation = null;
|
||||
this.state.previousValue = 0;
|
||||
this.state.waitingForOperand = true;
|
||||
}
|
||||
|
||||
if (updateDisplay) {
|
||||
this.updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.state.currentValue = 0;
|
||||
this.state.previousValue = 0;
|
||||
this.state.operation = null;
|
||||
this.state.waitingForOperand = false;
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
backspace() {
|
||||
if (!this.state.waitingForOperand) {
|
||||
this.state.currentValue = Math.floor(this.state.currentValue / 16);
|
||||
this.updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
// Button clicks
|
||||
document.addEventListener('click', (e) => {
|
||||
if (e.target.classList.contains('calc-btn')) {
|
||||
const action = e.target.getAttribute('onclick');
|
||||
if (action) {
|
||||
// Parse the onclick attribute to determine the action
|
||||
if (action.includes('calcInput')) {
|
||||
const match = action.match(/calcInput\('([^']+)'\)/);
|
||||
if (match) this.input(match[1]);
|
||||
} else if (action.includes('calcOperation')) {
|
||||
const match = action.match(/calcOperation\('([^']+)'\)/);
|
||||
if (match) this.operation(match[1]);
|
||||
} else if (action.includes('calcEquals')) {
|
||||
this.equals();
|
||||
} else if (action.includes('calcClear')) {
|
||||
this.clear();
|
||||
} else if (action.includes('calcBackspace')) {
|
||||
this.backspace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard support
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.target.tagName === 'INPUT' && !e.target.readOnly) return;
|
||||
|
||||
const key = e.key.toUpperCase();
|
||||
|
||||
if (/^[0-9A-F]$/.test(key)) {
|
||||
e.preventDefault();
|
||||
this.input(key);
|
||||
} else if (key === '+') {
|
||||
e.preventDefault();
|
||||
this.operation('+');
|
||||
} else if (key === '-') {
|
||||
e.preventDefault();
|
||||
this.operation('-');
|
||||
} else if (key === '*') {
|
||||
e.preventDefault();
|
||||
this.operation('*');
|
||||
} else if (key === '/') {
|
||||
e.preventDefault();
|
||||
this.operation('/');
|
||||
} else if (key === 'ENTER' || key === '=') {
|
||||
e.preventDefault();
|
||||
this.equals();
|
||||
} else if (key === 'ESCAPE' || key === 'C') {
|
||||
e.preventDefault();
|
||||
this.clear();
|
||||
} else if (key === 'BACKSPACE') {
|
||||
e.preventDefault();
|
||||
this.backspace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
generateHTML() {
|
||||
return `
|
||||
<div class="calculator-container">
|
||||
<div class="calc-display">
|
||||
<div class="calc-input">
|
||||
<input type="text" id="calcInput" placeholder="0x0" readonly>
|
||||
</div>
|
||||
<div class="calc-conversions">
|
||||
<div class="conversion-row">
|
||||
<span class="conv-label">HEX:</span>
|
||||
<span class="conv-value" id="hexValue">0x0</span>
|
||||
</div>
|
||||
<div class="conversion-row">
|
||||
<span class="conv-label">DEC:</span>
|
||||
<span class="conv-value" id="decValue">0</span>
|
||||
</div>
|
||||
<div class="conversion-row">
|
||||
<span class="conv-label">BIN:</span>
|
||||
<span class="conv-value" id="binValue">0b0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calc-buttons">
|
||||
<div class="calc-row">
|
||||
<button class="calc-btn number" onclick="calcInput('A')">A</button>
|
||||
<button class="calc-btn number" onclick="calcInput('B')">B</button>
|
||||
<button class="calc-btn number" onclick="calcInput('C')">C</button>
|
||||
<button class="calc-btn number" onclick="calcInput('D')">D</button>
|
||||
<button class="calc-btn clear" onclick="calcClear()">C</button>
|
||||
</div>
|
||||
<div class="calc-row">
|
||||
<button class="calc-btn number" onclick="calcInput('E')">E</button>
|
||||
<button class="calc-btn number" onclick="calcInput('F')">F</button>
|
||||
<button class="calc-btn number" onclick="calcInput('7')">7</button>
|
||||
<button class="calc-btn number" onclick="calcInput('8')">8</button>
|
||||
<button class="calc-btn operation" onclick="calcOperation('/')">/</button>
|
||||
</div>
|
||||
<div class="calc-row">
|
||||
<button class="calc-btn number" onclick="calcInput('4')">4</button>
|
||||
<button class="calc-btn number" onclick="calcInput('5')">5</button>
|
||||
<button class="calc-btn number" onclick="calcInput('6')">6</button>
|
||||
<button class="calc-btn operation" onclick="calcOperation('*')">*</button>
|
||||
<button class="calc-btn operation" onclick="calcOperation('MOD')">MOD</button>
|
||||
</div>
|
||||
<div class="calc-row">
|
||||
<button class="calc-btn number" onclick="calcInput('1')">1</button>
|
||||
<button class="calc-btn number" onclick="calcInput('2')">2</button>
|
||||
<button class="calc-btn number" onclick="calcInput('3')">3</button>
|
||||
<button class="calc-btn operation" onclick="calcOperation('-')">-</button>
|
||||
<button class="calc-btn operation" onclick="calcOperation('+')">+</button>
|
||||
</div>
|
||||
<div class="calc-row">
|
||||
<button class="calc-btn number wide" onclick="calcInput('0')">0</button>
|
||||
<button class="calc-btn number" onclick="calcInput('9')">9</button>
|
||||
<button class="calc-btn backspace" onclick="calcBackspace()">⌫</button>
|
||||
<button class="calc-btn equals" onclick="calcEquals()">=</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user