pull/1052/head
parent
9e8dd00f10
commit
a29c54c690
@ -0,0 +1,20 @@
|
|||||||
|
# Calculator (mini project)
|
||||||
|
|
||||||
|
Simple calculator implemented with HTML, CSS and JavaScript.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Basic operations: +, -, *, /
|
||||||
|
- Decimal support
|
||||||
|
- Percent handling (e.g., 50% → 0.5)
|
||||||
|
- Handles division by zero gracefully (shows "Error")
|
||||||
|
- Input and result displayed separately
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
1. Open `index.html` in a browser.
|
||||||
|
2. Use the buttons or keyboard to enter the expression.
|
||||||
|
3. Press `=` or Enter to evaluate.
|
||||||
|
4. Input remains visible; result appears below input.
|
||||||
|
|
||||||
|
## Notes for maintainers
|
||||||
|
- Files added under `projects/calculator-js/`
|
||||||
|
- No external dependencies
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
const display = document.getElementById('display');
|
||||||
|
const resultDisplay = document.getElementById('result');
|
||||||
|
const buttons = document.querySelectorAll('.buttons button');
|
||||||
|
|
||||||
|
let currentExpression = '';
|
||||||
|
|
||||||
|
function updateDisplay() {
|
||||||
|
display.value = currentExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeExpression(expr) {
|
||||||
|
return expr.replace(/[^0-9+\-*/().%]/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateExpression(expr) {
|
||||||
|
const withPercent = expr.replace(/(\d+(\.\d+)?)%/g, '($1/100)');
|
||||||
|
try {
|
||||||
|
const result = eval(withPercent);
|
||||||
|
if (typeof result === 'number') {
|
||||||
|
if (!isFinite(result)) return 'Error';
|
||||||
|
return String(Math.round(result * 1e10) / 1e10);
|
||||||
|
}
|
||||||
|
return 'Error';
|
||||||
|
} catch (e) {
|
||||||
|
return 'Error';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const val = btn.dataset.value;
|
||||||
|
const action = btn.dataset.action;
|
||||||
|
|
||||||
|
if (action === 'clear') {
|
||||||
|
currentExpression = '';
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action === 'back') {
|
||||||
|
currentExpression = currentExpression.slice(0, -1);
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action === 'equals') {
|
||||||
|
const sanitized = sanitizeExpression(currentExpression);
|
||||||
|
const result = calculateExpression(sanitized);
|
||||||
|
resultDisplay.value = result;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentExpression += val;
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Keyboard support
|
||||||
|
window.addEventListener('keydown', (e) => {
|
||||||
|
if ((e.key >= '0' && e.key <= '9') || '+-*/().%'.includes(e.key)) {
|
||||||
|
currentExpression += e.key;
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
} else if (e.key === 'Enter') {
|
||||||
|
const sanitized = sanitizeExpression(currentExpression);
|
||||||
|
resultDisplay.value = calculateExpression(sanitized);
|
||||||
|
} else if (e.key === 'Backspace') {
|
||||||
|
currentExpression = currentExpression.slice(0, -1);
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
} else if (e.key.toLowerCase() === 'c') {
|
||||||
|
currentExpression = '';
|
||||||
|
updateDisplay();
|
||||||
|
resultDisplay.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
:root{
|
||||||
|
--bg:#f4f7fb;
|
||||||
|
--panel:#ffffff;
|
||||||
|
--accent:#3b82f6;
|
||||||
|
--text:#111827;
|
||||||
|
--muted:#6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
*{box-sizing:border-box}
|
||||||
|
html,body{height:100%}
|
||||||
|
body{
|
||||||
|
margin:0;
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
background:linear-gradient(180deg,#e6eefc,#f8fafc);
|
||||||
|
font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;
|
||||||
|
color:var(--text);
|
||||||
|
padding:24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calculator{
|
||||||
|
width:320px;
|
||||||
|
background:var(--panel);
|
||||||
|
border-radius:12px;
|
||||||
|
box-shadow:0 6px 24px rgba(16,24,40,0.08);
|
||||||
|
padding:18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display{
|
||||||
|
width:100%;
|
||||||
|
height:56px;
|
||||||
|
border-radius:8px;
|
||||||
|
border:1px solid #e6eefc;
|
||||||
|
padding:8px 12px;
|
||||||
|
font-size:20px;
|
||||||
|
text-align:right;
|
||||||
|
margin-bottom:6px;
|
||||||
|
background:linear-gradient(180deg,#fff,#fbfdff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.display + .display {
|
||||||
|
background: #e5e7eb;
|
||||||
|
color: #111827;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns:repeat(4,1fr);
|
||||||
|
gap:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button{
|
||||||
|
height:48px;
|
||||||
|
border-radius:8px;
|
||||||
|
border:none;
|
||||||
|
background:#f3f4f6;
|
||||||
|
font-size:16px;
|
||||||
|
cursor:pointer;
|
||||||
|
transition:transform .08s ease, box-shadow .08s;
|
||||||
|
}
|
||||||
|
button:active{transform:translateY(1px)}
|
||||||
|
button[data-action="equals"]{
|
||||||
|
background:var(--accent);
|
||||||
|
color:#fff;
|
||||||
|
grid-column:4;
|
||||||
|
grid-row:5;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
|
button.zero{grid-column:1 / span 2}
|
||||||
|
button[data-action="clear"]{background:#fef3f2;color:#991b1b}
|
||||||
Loading…
Reference in new issue