Calculator Script

class Calculator { constructor() { this.display = document.getElementById('display'); this.previousOperation = document.getElementById('previousOperation'); this.currentInput = '0'; this.previousInput = ''; this.operator = null; this.waitingForOperand = false; this.justCalculated = false; this.initializeEventListeners(); this.initializeKeyboardSupport(); } initializeEventListeners() { // Button click events document.querySelectorAll('.btn').forEach(button => { button.addEventListener('click', (e) => { this.createRipple(e); this.handleButtonClick(button); }); }); // History clear document.querySelector('.history').addEventListener('click', () => { this.clearHistory(); }); } initializeKeyboardSupport() { document.addEventListener('keydown', (e) => { let handled = false; if (e.key >= '0' && e.key <= '9') { this.inputNumber(e.key); handled = true; } else if (e.key === '.') { this.inputDecimal(); handled = true; } else if (['+', '-', '*', '/'].includes(e.key)) { const operatorMap = { '+': '+', '-': '-', '*': '×', '/': '÷' }; this.inputOperator(operatorMap[e.key]); handled = true; } else if (e.key === 'Enter' || e.key === '=') { this.calculate(); handled = true; } else if (e.key === 'Escape') { this.clearAll(); handled = true; } else if (e.key === 'Backspace') { this.backspace(); handled = true; } if (handled) { e.preventDefault(); } }); } handleButtonClick(button) { if (button.dataset.number) { this.inputNumber(button.dataset.number); } else if (button.dataset.operator) { this.inputOperator(button.dataset.operator); } else if (button.dataset.action) { switch (button.dataset.action) { case 'clear-all': this.clearAll(); break; case 'clear-entry': this.clearEntry(); break; case 'backspace': this.backspace(); break; case 'calculate': this.calculate(); break; } } } inputNumber(num) { if (this.waitingForOperand) { this.currentInput = num; this.waitingForOperand = false; } else { if (this.justCalculated) { this.currentInput = num; this.justCalculated = false; this.previousOperation.textContent = ''; } else { this.currentInput = this.currentInput === '0' ? num : this.currentInput + num; } } this.updateDisplay(); } inputDecimal() { if (this.waitingForOperand) { this.currentInput = '0.'; this.waitingForOperand = false; } else if (this.currentInput.indexOf('.') === -1) { this.currentInput += '.'; } this.updateDisplay(); } inputOperator(nextOperator) { const inputValue = parseFloat(this.currentInput); if (this.previousInput === '') { this.previousInput = inputValue; } else if (this.operator) { const currentValue = this.previousInput || 0; const newValue = this.performCalculation(currentValue, inputValue, this.operator); if (newValue === null) return; this.currentInput = String(newValue); this.previousInput = newValue; this.updateDisplay(); } this.waitingForOperand = true; this.operator = nextOperator; this.justCalculated = false; this.previousOperation.textContent = `${this.formatNumber(this.previousInput)} ${nextOperator}`; this.updateOperatorButtons(nextOperator); } calculate() { const inputValue = parseFloat(this.currentInput); if (this.previousInput !== '' && this.operator) { const newValue = this.performCalculation(this.previousInput, inputValue, this.operator); if (newValue === null) return; this.previousOperation.textContent = `${this.formatNumber(this.previousInput)} ${this.operator} ${this.formatNumber(inputValue)} =`; this.currentInput = String(newValue); this.previousInput = ''; this.operator = null; this.waitingForOperand = false; this.justCalculated = true; this.updateDisplay(); this.animateCalculation(); this.clearOperatorButtons(); } } performCalculation(firstOperand, secondOperand, operator) { let result; switch (operator) { case '+': result = firstOperand + secondOperand; break; case '-': result = firstOperand - secondOperand; break; case '×': result = firstOperand * secondOperand; break; case '÷': if (secondOperand === 0) { this.showError('Cannot divide by zero'); return null; } result = firstOperand / secondOperand; break; default: return null; } // Round to avoid floating point precision issues return Math.round(result * 1000000000) / 1000000000; } clearAll() { this.currentInput = '0'; this.previousInput = ''; this.operator = null; this.waitingForOperand = false; this.justCalculated = false; this.previousOperation.textContent = ''; this.updateDisplay(); this.clearOperatorButtons(); } clearEntry() { this.currentInput = '0'; this.updateDisplay(); } backspace() { if (this.currentInput.length > 1) { this.currentInput = this.currentInput.slice(0, -1); } else { this.currentInput = '0'; } this.updateDisplay(); } clearHistory() { this.previousOperation.textContent = ''; document.querySelector('.history').style.animation = 'pulse 0.3s ease-in-out'; setTimeout(() => { document.querySelector('.history').style.animation = ''; }, 300); } updateDisplay() { this.display.value = this.formatNumber(this.currentInput); // Add glow effect for large numbers if (this.currentInput.length > 10) { this.display.parentElement.classList.add('display-glow'); } else { this.display.parentElement.classList.remove('display-glow'); } } formatNumber(num) { const number = parseFloat(num); if (isNaN(number)) return num; // Format large numbers with commas if (number >= 1000 || number <= -1000) { return number.toLocaleString(); } return num; } updateOperatorButtons(activeOperator) { document.querySelectorAll('.btn-operator').forEach(btn => { btn.classList.remove('active'); }); const activeButton = document.querySelector(`[data-operator="${activeOperator}"]`); if (activeButton) { activeButton.classList.add('active'); } } clearOperatorButtons() { document.querySelectorAll('.btn-operator').forEach(btn => { btn.classList.remove('active'); }); } showError(message) { this.display.value = 'Error'; this.display.parentElement.classList.add('error'); setTimeout(() => { this.display.parentElement.classList.remove('error'); this.clearAll(); }, 1500); } animateCalculation() { this.display.parentElement.classList.add('calculate'); setTimeout(() => { this.display.parentElement.classList.remove('calculate'); }, 300); } createRipple(event) { const button = event.currentTarget; const rect = button.getBoundingClientRect(); const ripple = document.createElement('span'); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; left: ${x}px; top: ${y}px; width: ${size}px; height: ${size}px; `; ripple.classList.add('ripple'); button.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); } } // Initialize calculator when DOM is loaded document.addEventListener('DOMContentLoaded', () => { new Calculator(); }); // Add some visual feedback for the calculator loading document.addEventListener('DOMContentLoaded', () => { const calculator = document.querySelector('.calculator'); calculator.style.opacity = '0'; calculator.style.transform = 'translateY(30px) scale(0.95)'; setTimeout(() => { calculator.style.transition = 'all 0.6s ease-out'; calculator.style.opacity = '1'; calculator.style.transform = 'translateY(0) scale(1)'; }, 100); });

Public Last updated: 2026-08-25 08:31:55 AM