what i did today was make a calculator but it is an advance one
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Advanced Calculator</title>
<style>
* { box-sizing: border-box; font-family: system-ui, sans-serif; }
body {
background: #111827;
color: #e5e7eb;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.calc {
background: #020617;
padding: 1rem;
border-radius: 1rem;
box-shadow: 0 20px 40px rgba(0,0,0,0.5);
width: 360px;
max-width: 100%;
}
.display {
background: #020617;
border-radius: 0.75rem;
padding: 0.75rem 0.9rem;
border: 1px solid #1f2937;
margin-bottom: 0.75rem;
}
.expression {
font-size: 0.85rem;
color: #9ca3af;
min-height: 1.2em;
word-wrap: break-word;
}
.result {
font-size: 1.6rem;
text-align: right;
margin-top: 0.25rem;
word-wrap: break-word;
}
.row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.4rem;
margin-bottom: 0.4rem;
}
button {
border: none;
border-radius: 0.6rem;
padding: 0.7rem 0.4rem;
font-size: 0.95rem;
cursor: pointer;
background: #111827;
color: #e5e7eb;
transition: background 0.1s, transform 0.05s;
}
button:active {
transform: translateY(1px);
background: #0f172a;
}
.btn-op { color: #38bdf8; }
.btn-fn { color: #a855f7; font-size: 0.8rem; }
.btn-eq {
background: #22c55e;
color: #022c22;
font-weight: 600;
}
.btn-eq:active { background: #16a34a; }
.btn-ac { color: #f97373; }
.row-wide {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 0.4rem;
margin-bottom: 0.4rem;
}
.history {
margin-top: 0.5rem;
max-height: 120px;
overflow-y: auto;
font-size: 0.8rem;
border-top: 1px solid #1f2937;
padding-top: 0.4rem;
}
.history-item {
display: flex;
justify-content: space-between;
gap: 0.5rem;
padding: 0.15rem 0;
cursor: pointer;
}
.history-exp { color: #9ca3af; }
.history-res { color: #e5e7eb; }
</style>
</head>
<body>
<div class="calc">
<div class="display">
<div class="expression" id="expression"></div>
<div class="result" id="result">0</div>
</div>
<div class="row">
<button class="btn-ac" data-action="clear">AC</button>
<button data-action="backspace">⌫</button>
<button class="btn-op" data-value="(">(</button>
<button class="btn-op" data-value=")">)</button>
</div>
<div class="row">
<button class="btn-fn" data-fn="sin">sin</button>
<button class="btn-fn" data-fn="cos">cos</button>
<button class="btn-fn" data-fn="tan">tan</button>
<button class="btn-op" data-value="/">÷</button>
</div>
<div class="row">
<button class="btn-fn" data-fn="log">log</button>
<button class="btn-fn" data-fn="ln">ln</button>
<button class="btn-fn" data-fn="sqrt">√</button>
<button class="btn-op" data-value="*">×</button>
</div>
<div class="row">
<button data-value="7">7</button>
<button data-value="8">8</button>
<button data-value="9">9</button>
<button class="btn-op" data-value="-">−</button>
</div>
<div class="row">
<button data-value="4">4</button>
<button data-value="5">5</button>
<button data-value="6">6</button>
<button class="btn-op" data-value="+">+</button>
</div>
<div class="row">
<button data-value="1">1</button>
<button data-value="2">2</button>
<button data-value="3">3</button>
<button class="btn-op" data-value="^">xʸ</button>
</div>
<div class="row-wide">
<button data-value="0">0</button>
<button data-value=".">.</button>
<button class="btn-eq" data-action="equals">=</button>
</div>
<div class="history" id="history"></div>
</div>
<script>
const exprEl = document.getElementById('expression');
const resultEl = document.getElementById('result');
const historyEl = document.getElementById('history');
let expression = '';
let lastResult = null;
const history = [];
function updateDisplay() {
exprEl.textContent = expression;
if (!expression) resultEl.textContent = lastResult !== null ? lastResult : '0';
}
function addToHistory(exp, res) {
history.unshift({ exp, res });
if (history.length > 20) history.pop();
renderHistory();
}
function renderHistory() {
historyEl.innerHTML = '';
history.forEach((item, index) => {
const div = document.createElement('div');
div.className = 'history-item';
div.innerHTML = `
<span class="history-exp">${item.exp}</span>
<span class="history-res">${item.res}</span>
`;
div.addEventListener('click', () => {
expression = item.exp;
lastResult = item.res;
updateDisplay();
});
historyEl.appendChild(div);
});
}
function insertValue(val) {
expression += val;
updateDisplay();
}
function insertFunction(fn) {
// functions are in radians
expression += fn + '(';
updateDisplay();
}
function clearAll() {
expression = '';
lastResult = null;
updateDisplay();
}
function backspace() {
expression = expression.slice(0, -1);
updateDisplay();
}
function toSafeExpression(exp) {
// Replace ^ with ** and map functions to Math.*
return exp
.replace(/π/g, 'Math.PI')
.replace(/e/g, 'Math.E')
.replace(/\^/g, '**')
.replace(/\bsin\(/g, 'Math.sin(')
.replace(/\bcos\(/g, 'Math.cos(')
.replace(/\btan\(/g, 'Math.tan(')
.replace(/\blog\(/g, 'Math.log10(')
.replace(/\bln\(/g, 'Math.log(')
.replace(/\bsqrt\(/g, 'Math.sqrt(');
}
function evaluateExpression() {
if (!expression) return;
try {
const safe = toSafeExpression(expression);
// eslint-disable-next-line no-new-func
const fn = new Function('return ' + safe);
let res = fn();
if (typeof res === 'number' && !Number.isNaN(res) && Number.isFinite(res)) {
// round to avoid floating noise
res = Math.round((res + Number.EPSILON) * 1e12) / 1e12;
lastResult = res;
resultEl.textContent = res;
addToHistory(expression, res);
} else {
resultEl.textContent = 'Error';
}
} catch (e) {
resultEl.textContent = 'Error';
}
}
document.addEventListener('click', (e) => {
const btn = e.target.closest('button');
if (!btn) return;
const val = btn.getAttribute('data-value');
const action = btn.getAttribute('data-action');
const fn = btn.getAttribute('data-fn');
if (val !== null) {
insertValue(val);
} else if (fn) {
insertFunction(fn);
} else if (action === 'clear') {
clearAll();
} else if (action === 'backspace') {
backspace();
} else if (action === 'equals') {
evaluateExpression();
}
});
// Basic keyboard support
document.addEventListener('keydown', (e) => {
const key = e.key;
if ((key >= '0' && key <= '9') || key === '.' || key === '(' || key === ')') {
insertValue(key);
} else if (['+', '-', '*', '/'].includes(key)) {
insertValue(key);
} else if (key === '^') {
insertValue('^');
} else if (key === 'Backspace') {
backspace();
} else if (key === 'Enter' || key === '=') {
e.preventDefault();
evaluateExpression();
} else if (key === 'Escape') {
clearAll();
}
});
updateDisplay();
</script>
</body>
</html>
Leave a Reply