Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Professional Scientific Calculator</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;500;700&display=swap'); | |
body { | |
font-family: 'Roboto Mono', monospace; | |
} | |
.calculator { | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); | |
transition: all 0.3s ease; | |
} | |
.display { | |
min-height: 120px; | |
word-break: break-all; | |
} | |
.btn { | |
transition: all 0.1s ease; | |
transform-origin: center; | |
} | |
.btn:active { | |
transform: scale(0.95); | |
} | |
.btn-operator { | |
background-color: #3b82f6; | |
color: white; | |
} | |
.btn-operator:hover { | |
background-color: #2563eb; | |
} | |
.btn-function { | |
background-color: #10b981; | |
color: white; | |
} | |
.btn-function:hover { | |
background-color: #059669; | |
} | |
.btn-equals { | |
background-color: #f59e0b; | |
color: white; | |
} | |
.btn-equals:hover { | |
background-color: #d97706; | |
} | |
.btn-clear { | |
background-color: #ef4444; | |
color: white; | |
} | |
.btn-clear:hover { | |
background-color: #dc2626; | |
} | |
.btn-secondary { | |
background-color: #4b5563; | |
color: white; | |
} | |
.btn-secondary:hover { | |
background-color: #374151; | |
} | |
.btn-number { | |
background-color: #1f2937; | |
color: white; | |
} | |
.btn-number:hover { | |
background-color: #111827; | |
} | |
.history-item:hover { | |
background-color: #f3f4f6; | |
cursor: pointer; | |
} | |
.tab-active { | |
border-bottom: 3px solid #3b82f6; | |
font-weight: 500; | |
} | |
.scientific-panel { | |
transition: all 0.3s ease; | |
} | |
.angle-unit { | |
background-color: #e5e7eb; | |
color: #1f2937; | |
} | |
.angle-unit.active { | |
background-color: #3b82f6; | |
color: white; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 min-h-screen flex items-center justify-center p-4"> | |
<div class="calculator w-full max-w-md bg-white rounded-2xl overflow-hidden shadow-xl"> | |
<!-- Calculator header with tabs --> | |
<div class="flex border-b"> | |
<div class="tab tab-active py-3 px-6 text-center flex-1 cursor-pointer" data-tab="basic"> | |
<i class="fas fa-calculator mr-2"></i> Basic | |
</div> | |
<div class="tab py-3 px-6 text-center flex-1 cursor-pointer" data-tab="scientific"> | |
<i class="fas fa-square-root-alt mr-2"></i> Scientific | |
</div> | |
<div class="tab py-3 px-6 text-center flex-1 cursor-pointer" data-tab="history"> | |
<i class="fas fa-history mr-2"></i> History | |
</div> | |
</div> | |
<!-- Display area --> | |
<div class="display p-4 bg-gray-50 text-right"> | |
<div id="expression" class="text-gray-500 text-lg min-h-6 overflow-x-auto whitespace-nowrap"></div> | |
<div id="result" class="text-3xl font-semibold mt-2 overflow-x-auto whitespace-nowrap">0</div> | |
</div> | |
<!-- Angle unit selector --> | |
<div class="scientific-panel hidden px-4 py-2 bg-gray-100 flex justify-center space-x-2"> | |
<button class="angle-unit active px-3 py-1 rounded-full text-sm" data-unit="deg">DEG</button> | |
<button class="angle-unit px-3 py-1 rounded-full text-sm" data-unit="rad">RAD</button> | |
<button class="angle-unit px-3 py-1 rounded-full text-sm" data-unit="grad">GRAD</button> | |
</div> | |
<!-- Calculator buttons --> | |
<div class="grid grid-cols-5 gap-1 p-2"> | |
<!-- Row 1 --> | |
<button class="btn btn-clear col-span-2 py-4 rounded" data-action="clear">AC</button> | |
<button class="btn btn-clear py-4 rounded" data-action="backspace"> | |
<i class="fas fa-backspace"></i> | |
</button> | |
<button class="btn btn-secondary py-4 rounded" data-action="percentage">%</button> | |
<button class="btn btn-operator py-4 rounded" data-action="divide">÷</button> | |
<!-- Row 2 --> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="sin">sin</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="cos">cos</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="tan">tan</button> | |
<button class="btn btn-secondary py-4 rounded" data-action="power">x^y</button> | |
<button class="btn btn-operator py-4 rounded" data-action="multiply">×</button> | |
<!-- Row 3 --> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="asin">sin⁻¹</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="acos">cos⁻¹</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="atan">tan⁻¹</button> | |
<button class="btn btn-secondary py-4 rounded" data-action="square">x²</button> | |
<button class="btn btn-operator py-4 rounded" data-action="subtract">−</button> | |
<!-- Row 4 --> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="log">log</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="ln">ln</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="factorial">x!</button> | |
<button class="btn btn-secondary py-4 rounded" data-action="sqrt">√</button> | |
<button class="btn btn-operator py-4 rounded" data-action="add">+</button> | |
<!-- Row 5 --> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="pi">π</button> | |
<button class="btn btn-function py-4 rounded scientific-btn hidden" data-action="e">e</button> | |
<button class="btn btn-secondary py-4 rounded" data-action="decimal">.</button> | |
<button class="btn btn-number py-4 rounded col-span-2" data-action="equals">=</button> | |
<!-- Row 6 (Numbers) --> | |
<button class="btn btn-number py-4 rounded" data-number="7">7</button> | |
<button class="btn btn-number py-4 rounded" data-number="8">8</button> | |
<button class="btn btn-number py-4 rounded" data-number="9">9</button> | |
<button class="btn btn-number py-4 rounded" data-number="4">4</button> | |
<button class="btn btn-number py-4 rounded" data-number="5">5</button> | |
<button class="btn btn-number py-4 rounded" data-number="6">6</button> | |
<button class="btn btn-number py-4 rounded" data-number="1">1</button> | |
<button class="btn btn-number py-4 rounded" data-number="2">2</button> | |
<button class="btn btn-number py-4 rounded" data-number="3">3</button> | |
<button class="btn btn-number py-4 rounded" data-number="0">0</button> | |
<button class="btn btn-number py-4 rounded" data-action="sign">±</button> | |
</div> | |
<!-- History panel (hidden by default) --> | |
<div id="history-panel" class="hidden max-h-64 overflow-y-auto p-4 border-t"> | |
<div class="text-center text-gray-500 mb-2">Calculation History</div> | |
<div id="history-list"></div> | |
</div> | |
</div> | |
<script> | |
// DOM elements | |
const resultElement = document.getElementById('result'); | |
const expressionElement = document.getElementById('expression'); | |
const historyList = document.getElementById('history-list'); | |
const tabs = document.querySelectorAll('.tab'); | |
const scientificPanel = document.querySelector('.scientific-panel'); | |
const scientificButtons = document.querySelectorAll('.scientific-btn'); | |
const historyPanel = document.getElementById('history-panel'); | |
const angleUnitButtons = document.querySelectorAll('.angle-unit'); | |
// Calculator state | |
let currentInput = '0'; | |
let previousInput = ''; | |
let operation = null; | |
let resetInput = false; | |
let angleMode = 'deg'; // deg, rad, grad | |
let calculationHistory = []; | |
// Initialize calculator | |
updateDisplay(); | |
// Event listeners for number buttons | |
document.querySelectorAll('[data-number]').forEach(button => { | |
button.addEventListener('click', () => { | |
appendNumber(button.getAttribute('data-number')); | |
}); | |
}); | |
// Event listeners for operation buttons | |
document.querySelectorAll('[data-action]').forEach(button => { | |
button.addEventListener('click', () => { | |
const action = button.getAttribute('data-action'); | |
switch(action) { | |
case 'add': | |
case 'subtract': | |
case 'multiply': | |
case 'divide': | |
chooseOperation(action); | |
break; | |
case 'equals': | |
compute(); | |
break; | |
case 'clear': | |
clear(); | |
break; | |
case 'backspace': | |
backspace(); | |
break; | |
case 'decimal': | |
appendDecimal(); | |
break; | |
case 'sign': | |
toggleSign(); | |
break; | |
case 'percentage': | |
percentage(); | |
break; | |
case 'square': | |
square(); | |
break; | |
case 'sqrt': | |
squareRoot(); | |
break; | |
case 'power': | |
power(); | |
break; | |
case 'sin': | |
sin(); | |
break; | |
case 'cos': | |
cos(); | |
break; | |
case 'tan': | |
tan(); | |
break; | |
case 'asin': | |
asin(); | |
break; | |
case 'acos': | |
acos(); | |
break; | |
case 'atan': | |
atan(); | |
break; | |
case 'log': | |
log(); | |
break; | |
case 'ln': | |
ln(); | |
break; | |
case 'factorial': | |
factorial(); | |
break; | |
case 'pi': | |
appendPi(); | |
break; | |
case 'e': | |
appendE(); | |
break; | |
} | |
}); | |
}); | |
// Tab switching | |
tabs.forEach(tab => { | |
tab.addEventListener('click', () => { | |
const tabName = tab.getAttribute('data-tab'); | |
// Update active tab | |
tabs.forEach(t => t.classList.remove('tab-active')); | |
tab.classList.add('tab-active'); | |
// Show/hide panels | |
if (tabName === 'scientific') { | |
scientificPanel.classList.remove('hidden'); | |
scientificButtons.forEach(btn => btn.classList.remove('hidden')); | |
historyPanel.classList.add('hidden'); | |
} else if (tabName === 'history') { | |
scientificPanel.classList.add('hidden'); | |
scientificButtons.forEach(btn => btn.classList.add('hidden')); | |
historyPanel.classList.remove('hidden'); | |
renderHistory(); | |
} else { | |
scientificPanel.classList.add('hidden'); | |
scientificButtons.forEach(btn => btn.classList.add('hidden')); | |
historyPanel.classList.add('hidden'); | |
} | |
}); | |
}); | |
// Angle unit selection | |
angleUnitButtons.forEach(button => { | |
button.addEventListener('click', () => { | |
angleUnitButtons.forEach(btn => btn.classList.remove('active')); | |
button.classList.add('active'); | |
angleMode = button.getAttribute('data-unit'); | |
}); | |
}); | |
// 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 === '+') { | |
chooseOperation('add'); | |
} else if (e.key === '-') { | |
chooseOperation('subtract'); | |
} else if (e.key === '*') { | |
chooseOperation('multiply'); | |
} else if (e.key === '/') { | |
chooseOperation('divide'); | |
} else if (e.key === 'Enter' || e.key === '=') { | |
compute(); | |
} else if (e.key === 'Escape') { | |
clear(); | |
} else if (e.key === 'Backspace') { | |
backspace(); | |
} else if (e.key === '%') { | |
percentage(); | |
} else if (e.key === '^') { | |
power(); | |
} | |
}); | |
// Calculator functions | |
function appendNumber(number) { | |
if (currentInput === '0' || resetInput) { | |
currentInput = number; | |
resetInput = false; | |
} else { | |
currentInput += number; | |
} | |
updateDisplay(); | |
} | |
function appendDecimal() { | |
if (resetInput) { | |
currentInput = '0.'; | |
resetInput = false; | |
return; | |
} | |
if (currentInput.indexOf('.') === -1) { | |
currentInput += '.'; | |
} | |
updateDisplay(); | |
} | |
function toggleSign() { | |
currentInput = (parseFloat(currentInput) * -1).toString(); | |
updateDisplay(); | |
} | |
function clear() { | |
currentInput = '0'; | |
previousInput = ''; | |
operation = null; | |
updateDisplay(); | |
} | |
function backspace() { | |
if (currentInput.length === 1 || (currentInput.length === 2 && currentInput.startsWith('-'))) { | |
currentInput = '0'; | |
} else { | |
currentInput = currentInput.slice(0, -1); | |
} | |
updateDisplay(); | |
} | |
function chooseOperation(op) { | |
if (currentInput === '0' && previousInput !== '') { | |
operation = op; | |
return; | |
} | |
if (previousInput === '') { | |
previousInput = currentInput; | |
} else if (operation) { | |
const result = computeOperation(previousInput, currentInput, operation); | |
previousInput = result.toString(); | |
} | |
operation = op; | |
currentInput = '0'; | |
updateDisplay(); | |
} | |
function compute() { | |
if (operation === null || previousInput === '') return; | |
const result = computeOperation(previousInput, currentInput, operation); | |
// Add to history | |
const historyEntry = { | |
expression: `${previousInput} ${getOperationSymbol(operation)} ${currentInput}`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
operation = null; | |
previousInput = ''; | |
resetInput = true; | |
updateDisplay(); | |
} | |
function computeOperation(num1, num2, op) { | |
const n1 = parseFloat(num1); | |
const n2 = parseFloat(num2); | |
switch(op) { | |
case 'add': return n1 + n2; | |
case 'subtract': return n1 - n2; | |
case 'multiply': return n1 * n2; | |
case 'divide': return n1 / n2; | |
default: return n2; | |
} | |
} | |
function percentage() { | |
currentInput = (parseFloat(currentInput) / 100).toString(); | |
updateDisplay(); | |
} | |
function square() { | |
const num = parseFloat(currentInput); | |
const result = num * num; | |
// Add to history | |
const historyEntry = { | |
expression: `${num}²`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function squareRoot() { | |
const num = parseFloat(currentInput); | |
const result = Math.sqrt(num); | |
// Add to history | |
const historyEntry = { | |
expression: `√${num}`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function power() { | |
previousInput = currentInput; | |
currentInput = '0'; | |
operation = 'power'; | |
expressionElement.textContent = `${previousInput}^`; | |
resultElement.textContent = currentInput; | |
} | |
function sin() { | |
let num = parseFloat(currentInput); | |
// Convert to radians if needed | |
if (angleMode === 'deg') { | |
num = degToRad(num); | |
} else if (angleMode === 'grad') { | |
num = gradToRad(num); | |
} | |
const result = Math.sin(num); | |
// Add to history | |
const historyEntry = { | |
expression: `sin(${currentInput}${angleMode})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function cos() { | |
let num = parseFloat(currentInput); | |
// Convert to radians if needed | |
if (angleMode === 'deg') { | |
num = degToRad(num); | |
} else if (angleMode === 'grad') { | |
num = gradToRad(num); | |
} | |
const result = Math.cos(num); | |
// Add to history | |
const historyEntry = { | |
expression: `cos(${currentInput}${angleMode})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function tan() { | |
let num = parseFloat(currentInput); | |
// Convert to radians if needed | |
if (angleMode === 'deg') { | |
num = degToRad(num); | |
} else if (angleMode === 'grad') { | |
num = gradToRad(num); | |
} | |
const result = Math.tan(num); | |
// Add to history | |
const historyEntry = { | |
expression: `tan(${currentInput}${angleMode})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function asin() { | |
let num = parseFloat(currentInput); | |
let result = Math.asin(num); | |
// Convert from radians if needed | |
if (angleMode === 'deg') { | |
result = radToDeg(result); | |
} else if (angleMode === 'grad') { | |
result = radToGrad(result); | |
} | |
// Add to history | |
const historyEntry = { | |
expression: `sin⁻¹(${currentInput})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function acos() { | |
let num = parseFloat(currentInput); | |
let result = Math.acos(num); | |
// Convert from radians if needed | |
if (angleMode === 'deg') { | |
result = radToDeg(result); | |
} else if (angleMode === 'grad') { | |
result = radToGrad(result); | |
} | |
// Add to history | |
const historyEntry = { | |
expression: `cos⁻¹(${currentInput})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function atan() { | |
let num = parseFloat(currentInput); | |
let result = Math.atan(num); | |
// Convert from radians if needed | |
if (angleMode === 'deg') { | |
result = radToDeg(result); | |
} else if (angleMode === 'grad') { | |
result = radToGrad(result); | |
} | |
// Add to history | |
const historyEntry = { | |
expression: `tan⁻¹(${currentInput})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function log() { | |
const num = parseFloat(currentInput); | |
const result = Math.log10(num); | |
// Add to history | |
const historyEntry = { | |
expression: `log(${currentInput})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function ln() { | |
const num = parseFloat(currentInput); | |
const result = Math.log(num); | |
// Add to history | |
const historyEntry = { | |
expression: `ln(${currentInput})`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function factorial() { | |
const num = parseInt(currentInput); | |
let result = 1; | |
for (let i = 2; i <= num; i++) { | |
result *= i; | |
} | |
// Add to history | |
const historyEntry = { | |
expression: `${currentInput}!`, | |
result: result | |
}; | |
calculationHistory.unshift(historyEntry); | |
currentInput = result.toString(); | |
updateDisplay(); | |
} | |
function appendPi() { | |
if (currentInput === '0' || resetInput) { | |
currentInput = Math.PI.toString(); | |
resetInput = false; | |
} else { | |
currentInput += Math.PI.toString(); | |
} | |
updateDisplay(); | |
} | |
function appendE() { | |
if (currentInput === '0' || resetInput) { | |
currentInput = Math.E.toString(); | |
resetInput = false; | |
} else { | |
currentInput += Math.E.toString(); | |
} | |
updateDisplay(); | |
} | |
// Helper functions | |
function updateDisplay() { | |
resultElement.textContent = currentInput; | |
if (operation !== null) { | |
expressionElement.textContent = `${previousInput} ${getOperationSymbol(operation)}`; | |
} else { | |
expressionElement.textContent = ''; | |
} | |
} | |
function getOperationSymbol(op) { | |
switch(op) { | |
case 'add': return '+'; | |
case 'subtract': return '−'; | |
case 'multiply': return '×'; | |
case 'divide': return '÷'; | |
case 'power': return '^'; | |
default: return ''; | |
} | |
} | |
function degToRad(degrees) { | |
return degrees * Math.PI / 180; | |
} | |
function radToDeg(radians) { | |
return radians * 180 / Math.PI; | |
} | |
function gradToRad(grads) { | |
return grads * Math.PI / 200; | |
} | |
function radToGrad(radians) { | |
return radians * 200 / Math.PI; | |
} | |
function renderHistory() { | |
historyList.innerHTML = ''; | |
if (calculationHistory.length === 0) { | |
historyList.innerHTML = '<div class="text-center text-gray-400 py-4">No history yet</div>'; | |
return; | |
} | |
calculationHistory.forEach((item, index) => { | |
const historyItem = document.createElement('div'); | |
historyItem.className = 'history-item p-2 border-b hover:bg-gray-50'; | |
historyItem.innerHTML = ` | |
<div class="text-sm text-gray-500">${item.expression}</div> | |
<div class="text-right font-semibold">${item.result}</div> | |
`; | |
historyItem.addEventListener('click', () => { | |
currentInput = item.result.toString(); | |
updateDisplay(); | |
}); | |
historyList.appendChild(historyItem); | |
}); | |
} | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=lior007/my-clock" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |