Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Advanced Calculator</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| :root { | |
| --primary-color: #667eea; | |
| --secondary-color: #764ba2; | |
| --bg-primary: #0f0f23; | |
| --bg-secondary: #1a1a2e; | |
| --bg-tertiary: #16213e; | |
| --text-primary: #ffffff; | |
| --text-secondary: #a0a0a0; | |
| --accent: #f7b801; | |
| --danger: #ff4757; | |
| --success: #00d2d3; | |
| --border-radius: 20px; | |
| --button-radius: 15px; | |
| --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| body.light-theme { | |
| --bg-primary: #f8f9fa; | |
| --bg-secondary: #ffffff; | |
| --bg-tertiary: #e9ecef; | |
| --text-primary: #212529; | |
| --text-secondary: #6c757d; | |
| --primary-color: #667eea; | |
| --secondary-color: #764ba2; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; | |
| background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%); | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| color: var(--text-primary); | |
| transition: var(--transition); | |
| overflow-x: hidden; | |
| } | |
| header { | |
| padding: 1.5rem; | |
| text-align: center; | |
| background: rgba(255, 255, 255, 0.05); | |
| backdrop-filter: blur(10px); | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .logo { | |
| font-size: 1.8rem; | |
| font-weight: 700; | |
| background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| margin-bottom: 0.5rem; | |
| } | |
| .built-with { | |
| font-size: 0.9rem; | |
| color: var(--text-secondary); | |
| } | |
| .built-with a { | |
| color: var(--primary-color); | |
| text-decoration: none; | |
| transition: var(--transition); | |
| } | |
| .built-with a:hover { | |
| text-decoration: underline; | |
| } | |
| main { | |
| flex: 1; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 2rem; | |
| } | |
| .calculator-container { | |
| display: grid; | |
| grid-template-columns: 1fr auto; | |
| gap: 2rem; | |
| max-width: 1200px; | |
| width: 100%; | |
| } | |
| .calculator { | |
| background: var(--bg-secondary); | |
| border-radius: var(--border-radius); | |
| padding: 2rem; | |
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | |
| width: 100%; | |
| max-width: 450px; | |
| margin: 0 auto; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .calculator::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 2px; | |
| background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); | |
| animation: shimmer 2s infinite; | |
| } | |
| @keyframes shimmer { | |
| 0% { transform: translateX(-100%); } | |
| 100% { transform: translateX(100%); } | |
| } | |
| .theme-toggle { | |
| position: absolute; | |
| top: 1.5rem; | |
| right: 1.5rem; | |
| background: var(--bg-tertiary); | |
| border: none; | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.2rem; | |
| transition: var(--transition); | |
| z-index: 10; | |
| } | |
| .theme-toggle:hover { | |
| transform: rotate(180deg); | |
| background: var(--primary-color); | |
| } | |
| .display { | |
| background: var(--bg-tertiary); | |
| border-radius: var(--button-radius); | |
| padding: 1.5rem; | |
| margin-bottom: 1.5rem; | |
| min-height: 100px; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: flex-end; | |
| align-items: flex-end; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .display::after { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, var(--primary-color), transparent); | |
| animation: scan 3s linear infinite; | |
| } | |
| @keyframes scan { | |
| 0% { transform: translateY(-100%); opacity: 0; } | |
| 50% { opacity: 1; } | |
| 100% { transform: translateY(100%); opacity: 0; } | |
| } | |
| .previous-operand { | |
| font-size: 0.9rem; | |
| color: var(--text-secondary); | |
| margin-bottom: 0.5rem; | |
| min-height: 20px; | |
| } | |
| .current-operand { | |
| font-size: 2.5rem; | |
| font-weight: 300; | |
| color: var(--text-primary); | |
| word-wrap: break-word; | |
| word-break: break-all; | |
| transition: var(--transition); | |
| } | |
| .current-operand.error { | |
| color: var(--danger); | |
| animation: shake 0.5s; | |
| } | |
| @keyframes shake { | |
| 0%, 100% { transform: translateX(0); } | |
| 25% { transform: translateX(-10px); } | |
| 75% { transform: translateX(10px); } | |
| } | |
| .buttons { | |
| display: grid; | |
| grid-template-columns: repeat(4, 1fr); | |
| gap: 0.75rem; | |
| } | |
| button { | |
| background: var(--bg-tertiary); | |
| border: none; | |
| border-radius: var(--button-radius); | |
| padding: 1.25rem; | |
| font-size: 1.2rem; | |
| color: var(--text-primary); | |
| cursor: pointer; | |
| transition: var(--transition); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| button::before { | |
| content: ''; | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| width: 0; | |
| height: 0; | |
| border-radius: 50%; | |
| background: rgba(255, 255, 255, 0.1); | |
| transform: translate(-50%, -50%); | |
| transition: width 0.6s, height 0.6s; | |
| } | |
| button:active::before { | |
| width: 300px; | |
| height: 300px; | |
| } | |
| button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3); | |
| } | |
| button:active { | |
| transform: translateY(0); | |
| } | |
| button.operator { | |
| background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); | |
| font-weight: 600; | |
| } | |
| button.operator:hover { | |
| box-shadow: 0 5px 20px rgba(102, 126, 234, 0.5); | |
| } | |
| button.equals { | |
| background: linear-gradient(135deg, var(--accent), #f39c12); | |
| grid-column: span 2; | |
| font-weight: 600; | |
| } | |
| button.clear { | |
| background: linear-gradient(135deg, var(--danger), #c44569); | |
| } | |
| button.function { | |
| background: var(--bg-tertiary); | |
| color: var(--primary-color); | |
| font-weight: 600; | |
| } | |
| button.zero { | |
| grid-column: span 2; | |
| } | |
| .history-panel { | |
| background: var(--bg-secondary); | |
| border-radius: var(--border-radius); | |
| padding: 1.5rem; | |
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); | |
| width: 100%; | |
| max-width: 350px; | |
| max-height: 500px; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .history-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .history-title { | |
| font-size: 1.2rem; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| } | |
| .clear-history { | |
| background: transparent; | |
| border: 1px solid var(--danger); | |
| color: var(--danger); | |
| padding: 0.5rem 1rem; | |
| border-radius: 8px; | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .clear-history:hover { | |
| background: var(--danger); | |
| color: white; | |
| } | |
| .history-list { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding-right: 0.5rem; | |
| } | |
| .history-list::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .history-list::-webkit-scrollbar-track { | |
| background: var(--bg-tertiary); | |
| border-radius: 3px; | |
| } | |
| .history-list::-webkit-scrollbar-thumb { | |
| background: var(--primary-color); | |
| border-radius: 3px; | |
| } | |
| .history-item { | |
| background: var(--bg-tertiary); | |
| border-radius: 10px; | |
| padding: 1rem; | |
| margin-bottom: 0.75rem; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| animation: slideIn 0.3s ease; | |
| } | |
| @keyframes slideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateX(20px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateX(0); | |
| } | |
| } | |
| .history-item:hover { | |
| background: var(--primary-color); | |
| transform: translateX(-5px); | |
| } | |
| .history-expression { | |
| font-size: 0.9rem; | |
| color: var(--text-secondary); | |
| margin-bottom: 0.25rem; | |
| } | |
| .history-result { | |
| font-size: 1.1rem; | |
| color: var(--text-primary); | |
| font-weight: 600; | |
| } | |
| .empty-history { | |
| text-align: center; | |
| color: var(--text-secondary); | |
| padding: 2rem; | |
| font-style: italic; | |
| } | |
| @media (max-width: 968px) { | |
| .calculator-container { | |
| grid-template-columns: 1fr; | |
| max-width: 500px; | |
| } | |
| .history-panel { | |
| max-height: 300px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .calculator { | |
| padding: 1.5rem; | |
| } | |
| .display { | |
| padding: 1rem; | |
| min-height: 80px; | |
| } | |
| .current-operand { | |
| font-size: 2rem; | |
| } | |
| button { | |
| padding: 1rem; | |
| font-size: 1rem; | |
| } | |
| .buttons { | |
| gap: 0.5rem; | |
| } | |
| } | |
| .tooltip { | |
| position: absolute; | |
| background: var(--bg-tertiary); | |
| color: var(--text-primary); | |
| padding: 0.5rem 1rem; | |
| border-radius: 8px; | |
| font-size: 0.8rem; | |
| white-space: nowrap; | |
| pointer-events: none; | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| z-index: 1000; | |
| bottom: calc(100% + 10px); | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| button:hover .tooltip { | |
| opacity: 1; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="logo">Advanced Calculator</div> | |
| <div class="built-with">Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Anycoder</a></div> | |
| </header> | |
| <main> | |
| <div class="calculator-container"> | |
| <div class="calculator"> | |
| <button class="theme-toggle" onclick="toggleTheme()"> | |
| <span id="themeIcon">🌙</span> | |
| </button> | |
| <div class="display"> | |
| <div class="previous-operand" id="previousOperand"></div> | |
| <div class="current-operand" id="currentOperand">0</div> | |
| </div> | |
| <div class="buttons"> | |
| <button class="clear" onclick="clearAll()">AC</button> | |
| <button class="function" onclick="deleteDigit()">DEL</button> | |
| <button class="function" onclick="appendFunction('sqrt')">√</button> | |
| <button class="operator" onclick="chooseOperation('/')">÷</button> | |
| <button onclick="appendNumber('7')">7</button> | |
| <button onclick="appendNumber('8')">8</button> | |
| <button onclick="appendNumber('9')">9</button> | |
| <button class="operator" onclick="chooseOperation('*')">×</button> | |
| <button onclick="appendNumber('4')">4</button> | |
| <button onclick="appendNumber('5')">5</button> | |
| <button onclick="appendNumber('6')">6</button> | |
| <button class="operator" onclick="chooseOperation('-')">−</button> | |
| <button onclick="appendNumber('1')">1</button> | |
| <button onclick="appendNumber('2')">2</button> | |
| <button onclick="appendNumber('3')">3</button> | |
| <button class="operator" onclick="chooseOperation('+')">+</button> | |
| <button onclick="appendNumber('0')" class="zero">0</button> | |
| <button onclick="appendDecimal()">.</button> | |
| <button onclick="appendFunction('percent')">%</button> | |
| <button class="equals" onclick="calculate()">=</button> | |
| <button class="function" onclick="appendFunction('sin')">sin</button> | |
| <button class="function" onclick="appendFunction('cos')">cos</button> | |
| <button class="function" onclick="appendFunction('tan')">tan</button> | |
| <button class="function" onclick="appendFunction('log')">log</button> | |
| <button class="function" onclick="appendFunction('pow2')">x²</button> | |
| <button class="function" onclick="appendFunction('pow3')">x³</button> | |
| <button class="function" onclick="appendFunction('pi')">π</button> | |
| <button class="function" onclick="appendFunction('e')">e</button> | |
| </div> | |
| </div> | |
| <div class="history-panel"> | |
| <div class="history-header"> | |
| <div class="history-title">History</div> | |
| <button class="clear-history" onclick="clearHistory()">Clear</button> | |
| </div> | |
| <div class="history-list" id="historyList"> | |
| <div class="empty-history">No calculations yet</div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <script> | |
| let currentOperand = '0'; | |
| let previousOperand = ''; | |
| let operation = null; | |
| let shouldResetScreen = false; | |
| let history = []; | |
| const currentOperandElement = document.getElementById('currentOperand'); | |
| const previousOperandElement = document.getElementById('previousOperand'); | |
| const historyListElement = document.getElementById('historyList'); | |
| function updateDisplay() { | |
| currentOperandElement.textContent = formatNumber(currentOperand); | |
| if (operation != null) { | |
| previousOperandElement.textContent = `${formatNumber(previousOperand)} ${getOperationSymbol(operation)}`; | |
| } else { | |
| previousOperandElement.textContent = ''; | |
| } | |
| } | |
| function formatNumber(number) { | |
| if (number.length > 12) { | |
| return parseFloat(number).toExponential(6); | |
| } | |
| const stringNumber = number.toString(); | |
| if (stringNumber.includes('.')) { | |
| return parseFloat(stringNumber).toLocaleString('en-US', { | |
| maximumFractionDigits: 10 | |
| }); | |
| } | |
| return parseFloat(stringNumber).toLocaleString('en-US'); | |
| } | |
| function getOperationSymbol(op) { | |
| switch(op) { | |
| case '+': return '+'; | |
| case '-': return '−'; | |
| case '*': return '×'; | |
| case '/': return '÷'; | |
| default: return op; | |
| } | |
| } | |
| function appendNumber(number) { | |
| if (shouldResetScreen) { | |
| currentOperand = ''; | |
| shouldResetScreen = false; | |
| } | |
| if (currentOperand === '0' && number !== '.') { | |
| currentOperand = number; | |
| } else { | |
| currentOperand += number; | |
| } | |
| updateDisplay(); | |
| } | |
| function appendDecimal() { | |
| if (shouldResetScreen) { | |
| currentOperand = '0'; | |
| shouldResetScreen = false; | |
| } | |
| if (!currentOperand.includes('.')) { | |
| currentOperand += '.'; | |
| } | |
| updateDisplay(); | |
| } | |
| function chooseOperation(op) { | |
| if (currentOperand === '') return; | |
| if (previousOperand !== '') { | |
| calculate(); | |
| } | |
| operation = op; | |
| previousOperand = currentOperand; | |
| currentOperand = ''; | |
| updateDisplay(); | |
| } | |
| function calculate() { | |
| let computation; | |
| const prev = parseFloat(previousOperand); | |
| const current = parseFloat(currentOperand); | |
| if (isNaN(prev) || isNaN(current)) return; | |
| switch(operation) { | |
| case '+': | |
| computation = prev + current; | |
| break; | |
| case '-': | |
| computation = prev - current; | |
| break; | |
| case '*': | |
| computation = prev * current; | |
| break; | |
| case '/': | |
| if (current === 0) { | |
| showError('Cannot divide by zero'); | |
| return; | |
| } | |
| computation = prev / current; | |
| break; | |
| default: | |
| return; | |
| } | |
| addToHistory(`${formatNumber(previousOperand)} ${getOperationSymbol(operation)} ${formatNumber(currentOperand)}`, computation.toString()); | |
| currentOperand = computation.toString(); | |
| operation = null; | |
| previousOperand = ''; | |
| shouldResetScreen = true; | |
| updateDisplay(); | |
| } | |
| function appendFunction(func) { | |
| const current = parseFloat(currentOperand); | |
| if (isNaN(current)) return; | |
| let result; | |
| switch(func) { | |
| case 'sqrt': | |
| if (current < 0) { | |
| showError('Invalid input'); | |
| return; | |
| } | |
| result = Math.sqrt(current); | |
| break; | |
| case 'percent': | |
| result = current / 100; | |
| break; | |
| case 'sin': | |
| result = Math.sin(current * Math.PI / 180); | |
| break; | |
| case 'cos': | |
| result = Math.cos(current * Math.PI / 180); | |
| break; | |
| case 'tan': | |
| result = Math.tan(current * Math.PI / 180); | |
| break; | |
| case 'log': | |
| if (current <= 0) { | |
| showError('Invalid input'); | |
| return; | |
| } | |
| result = Math.log10(current); | |
| break; | |
| case 'pow2': | |
| result = Math.pow(current, 2); | |
| break; | |
| case 'pow3': | |
| result = Math.pow(current, 3); | |
| break; | |
| case 'pi': | |
| currentOperand = Math.PI.toString(); | |
| updateDisplay(); | |
| return; | |
| case 'e': | |
| currentOperand = Math.E.toString(); | |
| updateDisplay(); | |
| return; | |
| default: | |
| return; | |
| } | |
| addToHistory(`${func}(${formatNumber(currentOperand)})`, result.toString()); | |
| currentOperand = result.toString(); | |
| shouldResetScreen = true; | |
| updateDisplay(); | |
| } | |
| function clearAll() { | |
| currentOperand = '0'; | |
| previousOperand = ''; | |
| operation = null; | |
| shouldResetScreen = false; | |
| updateDisplay(); | |
| } | |
| function deleteDigit() { | |
| if (currentOperand.length > 1) { | |
| currentOperand = currentOperand.slice(0, -1); | |
| } else { | |
| currentOperand = '0'; | |
| } | |
| updateDisplay(); | |
| } | |
| function showError(message) { | |
| currentOperandElement.textContent = message; | |
| currentOperandElement.classList.add('error'); | |
| setTimeout(() => { | |
| currentOperandElement.classList.remove('error'); | |
| clearAll(); | |
| }, 2000); | |
| } | |
| function addToHistory(expression, result) { | |
| history.unshift({ expression, result }); | |
| if (history.length > 20) { | |
| history.pop(); | |
| } | |
| updateHistoryDisplay(); | |
| } | |
| function updateHistoryDisplay() { | |
| if (history.length === 0) { | |
| historyListElement.innerHTML = '<div class="empty-history">No calculations yet</div>'; | |
| return; | |
| } | |
| historyListElement.innerHTML = history.map((item, index) => ` | |
| <div class="history-item" onclick="loadFromHistory(${index})"> | |
| <div class="history-expression">${item.expression}</div> | |
| <div class="history-result">= ${formatNumber(item.result)}</div> | |
| </div> | |
| `).join(''); | |
| } | |
| function loadFromHistory(index) { | |
| const item = history[index]; | |
| currentOperand = item.result; | |
| shouldResetScreen = true; | |
| updateDisplay(); | |
| } | |
| function clearHistory() { | |
| history = []; | |
| updateHistoryDisplay(); | |
| } | |
| function toggleTheme() { | |
| document.body.classList.toggle('light-theme'); | |
| const icon = document.getElementById('themeIcon'); | |
| icon.textContent = document.body.classList.contains('light-theme') ? '☀️' : '🌙'; | |
| } | |
| // Keyboard support | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key >= '0' && e.key <= '9') { | |
| appendNumber(e.key); | |
| } else if (e.key === '.') { | |
| appendDecimal(); | |
| } else if (e.key === '+' || e.key === '-' || e.key === '*' || e.key === '/') { | |
| chooseOperation(e.key); | |
| } else if (e.key === 'Enter' || e.key === '=') { | |
| calculate(); | |
| } else if (e.key === 'Escape' || e.key === 'c' || e.key === 'C') { | |
| clearAll(); | |
| } else if (e.key === 'Backspace') { | |
| deleteDigit(); | |
| } | |
| }); | |
| // Initialize | |
| updateDisplay(); | |
| </script> | |
| </body> | |
| </html> |