Calculator
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ultimate Calculator</title> <style> :root { --bg-color: #f3f4f6; --text-color: #111827; --display-bg: #f9fafb; --button-bg: #ffffff; --button-hover: #f9fafb; --operation-bg: #3b82f6; --operation-hover: #60a5fa; --equals-bg: #10b981; --equals-hover: #34d399; --clear-bg: #ef4444; --clear-hover: #f87171; --memory-bg: #8b5cf6; --memory-hover: #a78bfa; --function-bg: #6366f1; --function-hover: #818cf8; --history-bg: #f9fafb; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } .dark-mode { --bg-color: #111827; --text-color: #f3f4f6; --display-bg: #1f2937; --button-bg: #374151; --button-hover: #4b5563; --operation-bg: #2563eb; --operation-hover: #3b82f6; --equals-bg: #059669; --equals-hover: #10b981; --clear-bg: #dc2626; --clear-hover: #ef4444; --memory-bg: #7c3aed; --memory-hover: #8b5cf6; --function-bg: #4f46e5; --function-hover: #6366f1; --history-bg: #1f2937; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: var(--bg-color); color: var(--text-color); transition: background-color 0.3s, color 0.3s; } .calculator { width: 100%; max-width: 360px; padding: 20px; border-radius: 24px; box-shadow: var(--shadow); background-color: var(--bg-color); } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .title { display: flex; align-items: center; font-size: 20px; font-weight: bold; } .title svg { margin-right: 8px; } .icon-button { background-color: var(--button-bg); border: none; border-radius: 9999px; padding: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .icon-button:hover { background-color: var(--button-hover); transform: scale(1.05); } .icon-button svg { width: 20px; height: 20px; } .display { width: 100%; padding: 12px; margin-bottom: 12px; border-radius: 12px; background-color: var(--display-bg); text-align: right; font-family: monospace; font-size: 32px; overflow-x: auto; white-space: nowrap; box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05); } .memory-indicator { font-size: 12px; color: #6b7280; margin-top: 4px; } .operation-indicator { font-size: 12px; color: #6b7280; } .history-panel { width: 100%; height: 80px; padding: 8px; margin-bottom: 12px; border-radius: 12px; background-color: var(--history-bg); overflow-y: auto; box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05); } .history-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; font-size: 14px; font-weight: 500; } .clear-history { display: flex; align-items: center; font-size: 12px; padding: 4px; border: none; background: none; cursor: pointer; color: var(--text-color); opacity: 0.7; } .clear-history:hover { opacity: 1; } .clear-history svg { width: 14px; height: 14px; margin-right: 4px; } .history-content { font-size: 14px; white-space: nowrap; overflow-x: auto; } .history-item { margin-right: 12px; display: inline-block; } .no-history { text-align: center; font-size: 14px; color: #6b7280; margin-top: 8px; } .buttons-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; } .button { border: none; border-radius: 12px; padding: 12px 0; font-size: 18px; font-weight: 500; cursor: pointer; transition: all 0.2s; box-shadow: var(--shadow); } .button:hover { transform: scale(1.05); } .button:active { transform: scale(0.95); } .number { background-color: var(--button-bg); color: var(--text-color); } .number:hover { background-color: var(--button-hover); } .operation { background-color: var(--operation-bg); color: white; } .operation:hover { background-color: var(--operation-hover); } .equals { background-color: var(--equals-bg); color: white; } .equals:hover { background-color: var(--equals-hover); } .clear { background-color: var(--clear-bg); color: white; } .clear:hover { background-color: var(--clear-hover); } .memory { background-color: var(--memory-bg); color: white; padding: 8px 0; font-size: 16px; } .memory:hover { background-color: var(--memory-hover); } .function { background-color: var(--function-bg); color: white; } .function:hover { background-color: var(--function-hover); } .col-span-2 { grid-column: span 2; } .col-span-3 { grid-column: span 3; } .footer { display: flex; justify-content: center; align-items: center; margin-top: 12px; font-size: 12px; opacity: 0.7; } .footer svg { width: 16px; height: 16px; margin-right: 4px; } </style> </head> <body> <div class="calculator"> <div class="header"> <div class="title"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="4" y="2" width="16" height="20" rx="2" ry="2"></rect> <line x1="8" y1="6" x2="16" y2="6"></line> <line x1="8" y1="12" x2="16" y2="12"></line> <line x1="8" y1="18" x2="16" y2="18"></line> </svg> Ultimate Calculator </div> <div> <button class="icon-button" id="history-button"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="22 12 16 12 14 15 10 9 8 12 2 12"></polyline> <path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path> </svg> </button> <button class="icon-button" id="theme-button"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" id="moon-icon"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" id="sun-icon" style="display: none;"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </button> </div> </div> <div class="display" id="display">0</div> <div class="memory-indicator" id="memory-indicator" style="display: none;"></div> <div class="operation-indicator" id="operation-indicator"></div> <div class="history-panel" id="history-panel" style="display: none;"> <div class="history-header"> <div>History</div> <button class="clear-history" id="clear-history"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="3 6 5 6 21 6"></polyline> <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path> <line x1="10" y1="11" x2="10" y2="17"></line> <line x1="14" y1="11" x2="14" y2="17"></line> </svg> Clear </button> </div> <div class="history-content" id="history-content"></div> </div> <div class="buttons-grid"> <button class="button memory" id="mc">MC</button> <button class="button memory" id="mr">MR</button> <button class="button memory" id="m-plus">M+</button> <button class="button memory" id="m-minus">M-</button> <button class="button function" id="square">x²</button> <button class="button function" id="sqrt">√x</button> <button class="button clear" id="clear">C</button> <button class="button function" id="backspace">⌫</button> <button class="button function" id="percentage">%</button> <button class="button operation" id="divide">÷</button> <button class="button number" id="seven">7</button> <button class="button number" id="eight">8</button> <button class="button number" id="nine">9</button> <button class="button operation" id="multiply">×</button> <button class="button number" id="four">4</button> <button class="button number" id="five">5</button> <button class="button number" id="six">6</button> <button class="button operation" id="subtract">-</button> <button class="button number" id="one">1</button> <button class="button number" id="two">2</button> <button class="button number" id="three">3</button> <button class="button operation" id="add">+</button> <button class="button function" id="toggle-sign">±</button> <button class="button number" id="zero">0</button> <button class="button number" id="decimal">.</button> <button class="button equals" id="equals">=</button> </div> <div class="footer"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="13 3 13 10 19 10"></polyline> <polyline points="22 3 16 10 22 10 22 3"></polyline> <path d="M11 21a9 9 0 0 1-9-9 9 9 0 0 1 9-9 1 1 0 0 1 1 1v7h7a1 1 0 0 1 1 1 9 9 0 0 1-9 9z"></path> </svg> Keyboard support enabled </div> </div> <script> // Calculator state let display = '0'; let memory = null; let currentOperation = null; let prevValue = null; let waitingForOperand = false; let history = []; let showHistory = false; let darkMode = false; // DOM elements const displayElement = document.getElementById('display'); const memoryIndicator = document.getElementById('memory-indicator'); const operationIndicator = document.getElementById('operation-indicator'); const historyPanel = document.getElementById('history-panel'); const historyContent = document.getElementById('history-content'); const historyButton = document.getElementById('history-button'); const clearHistoryButton = document.getElementById('clear-history'); const themeButton = document.getElementById('theme-button'); const moonIcon = document.getElementById('moon-icon'); const sunIcon = document.getElementById('sun-icon'); // Number buttons document.querySelectorAll('.number:not(#decimal)').forEach(button => { button.addEventListener('click', () => handleNumber(button.textContent)); }); // Operation buttons document.getElementById('add').addEventListener('click', () => handleOperation('+')); document.getElementById('subtract').addEventListener('click', () => handleOperation('-')); document.getElementById('multiply').addEventListener('click', () => handleOperation('×')); document.getElementById('divide').addEventListener('click', () => handleOperation('÷')); // Function buttons document.getElementById('decimal').addEventListener('click', handleDecimal); document.getElementById('equals').addEventListener('click', calculate); document.getElementById('clear').addEventListener('click', clearDisplay); document.getElementById('backspace').addEventListener('click', backspace); document.getElementById('toggle-sign').addEventListener('click', toggleSign); document.getElementById('percentage').addEventListener('click', percentage); document.getElementById('square').addEventListener('click', square); document.getElementById('sqrt').addEventListener('click', squareRoot); // Memory buttons document.getElementById('mc').addEventListener('click', memoryClear); document.getElementById('mr').addEventListener('click', memoryRecall); document.getElementById('m-plus').addEventListener('click', memoryAdd); document.getElementById('m-minus').addEventListener('click', memorySubtract); // UI buttons historyButton.addEventListener('click', toggleHistory); clearHistoryButton.addEventListener('click', clearHistory); themeButton.addEventListener('click', toggleTheme); // Keyboard support document.addEventListener('keydown', handleKeyDown); // Update display function updateDisplay() { displayElement.textContent = display; if (memory !== null) { memoryIndicator.textContent = `M: ${memory}`; memoryIndicator.style.display = 'block'; } else { memoryIndicator.style.display = 'none'; } if (currentOperation && prevValue !== null) { operationIndicator.textContent = `${prevValue} ${currentOperation}`; } else { operationIndicator.textContent = ''; } } // Handle number input function handleNumber(num) { animateButton(num); if (waitingForOperand) { display = num; waitingForOperand = false; } else { display = display === '0' ? num : display + num; } updateDisplay(); } // Handle decimal point function handleDecimal() { animateButton('.'); if (waitingForOperand) { display = '0.'; waitingForOperand = false; } else if (display.indexOf('.') === -1) { display += '.'; } updateDisplay(); } // Handle operations function handleOperation(operation) { animateButton(operation); const value = parseFloat(display); if (prevValue === null) { prevValue = value; } else if (currentOperation) { const result = performCalculation(); prevValue = result; display = String(result); // Add to history addToHistory(`${prevValue} ${currentOperation} ${value} = ${result}`); } waitingForOperand = true; currentOperation = operation; updateDisplay(); } // Perform calculation function performCalculation() { const current = parseFloat(display); const previous = prevValue; let result; switch (currentOperation) { case '+': result = previous + current; break; case '-': result = previous - current; break; case '×': result = previous * current; break; case '÷': result = previous / current; break; default: return current; } return Math.round(result * 1000000) / 1000000; // Handle floating point precision } // Calculate result function calculate() { animateButton('='); if (!currentOperation || prevValue === null) return; const current = parseFloat(display); const result = performCalculation(); // Add to history addToHistory(`${prevValue} ${currentOperation} ${current} = ${result}`); display = String(result); prevValue = null; currentOperation = null; waitingForOperand = true; updateDisplay(); } // Clear display function clearDisplay() { animateButton('C'); display = '0'; prevValue = null; currentOperation = null; waitingForOperand = false; updateDisplay(); } // Backspace function backspace() { animateButton('⌫'); if (waitingForOperand) return; if (display.length === 1 || (display.length === 2 && display.startsWith('-'))) { display = '0'; } else { display = display.slice(0, -1); } updateDisplay(); } // Toggle sign function toggleSign() { animateButton('±'); display = display.startsWith('-') ? display.slice(1) : '-' + display; updateDisplay(); } // Percentage function percentage() { animateButton('%'); const value = parseFloat(display); display = String(value / 100); updateDisplay(); } // Square function square() { animateButton('x²'); const value = parseFloat(display); const result = value * value; display = String(result); // Add to history addToHistory(`${value}² = ${result}`); updateDisplay(); } // Square root function squareRoot() { animateButton('√'); const value = parseFloat(display); const result = Math.sqrt(value); display = String(result); // Add to history addToHistory(`√${value} = ${result}`); updateDisplay(); } // Memory functions function memoryClear() { animateButton('MC'); memory = null; updateDisplay(); } function memoryRecall() { animateButton('MR'); if (memory !== null) { display = String(memory); updateDisplay(); } } function memoryAdd() { animateButton('M+'); const value = parseFloat(display); memory = memory === null ? value : memory + value; updateDisplay(); } function memorySubtract() { animateButton('M-'); const value = parseFloat(display); memory = memory === null ? -value : memory - value; updateDisplay(); } // History functions function toggleHistory() { showHistory = !showHistory; historyPanel.style.display = showHistory ? 'block' : 'none'; updateHistoryDisplay(); } function clearHistory() { history = []; updateHistoryDisplay(); } function addToHistory(item) { history.push(item); if (showHistory) { updateHistoryDisplay(); } } function updateHistoryDisplay() { historyContent.innerHTML = ''; if (history.length === 0) { const noHistory = document.createElement('div'); noHistory.className = 'no-history'; noHistory.textContent = 'No history yet'; historyContent.appendChild(noHistory); } else { history.forEach(item => { const historyItem = document.createElement('span'); historyItem.className = 'history-item'; historyItem.textContent = item; historyContent.appendChild(historyItem); }); } } // Theme toggle function toggleTheme() { darkMode = !darkMode; document.body.classList.toggle('dark-mode'); if (darkMode) { moonIcon.style.display = 'none'; sunIcon.style.display = 'block'; } else { moonIcon.style.display = 'block'; sunIcon.style.display = 'none'; } } // Button animation function animateButton(value) { const button = document.querySelector(`[id="${value.toLowerCase()}"]`) || document.querySelector(`[id="${value}"]`); if (button) { button.classList.add('active'); setTimeout(() => button.classList.remove('active'), 150); } } // Keyboard support function handleKeyDown(e) { if (e.key.match(/[0-9]/)) handleNumber(e.key); if (e.key === '.') handleDecimal(); if (e.key === '+') handleOperation('+'); if (e.key === '-') handleOperation('-'); if (e.key === '*') handleOperation('×'); if (e.key === '/') handleOperation('÷'); if (e.key === 'Enter' || e.key === '=') calculate(); if (e.key === 'Escape' || e.key === 'c' || e.key === 'C') clearDisplay(); if (e.key === 'Backspace') backspace(); } // Initialize updateDisplay(); </script> </body> </html>
Comments
Post a Comment