<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>A simple calculator</title>
<link rel="stylesheet" href="index.css">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Andika+New+Basic:wght@400;700&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/3d18fa0c0a.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="calculator">
<div id="screen">
<p id="result"></p>
<span id="input">0</span>
</div>
<div id="grid">
<button id="butC" class="reset">C</button>
<button id="but^" class="btnOper small">x²</button>
<button id="but√" class="btnOper">√</button>
<button id="but÷" class="btnOper">÷</button>
<button id="but7">7</button>
<button id="but8">8</button>
<button id="but9">9</button>
<button id="but×" class="btnOper">×</button>
<button id="but4">4</button>
<button id="but5">5</button>
<button id="but6">6</button>
<button id="but-" class="btnOper">-</button>
<button id="but1">1</button>
<button id="but2">2</button>
<button id="but3">3</button>
<button id="but+" class="btnOper">+</button>
<button id="but/" class="small">+/-</button>
<button id="but0">0</button>
<button id="but.">.</button>
<button id="but=" class="btnOper">=</button>
</div>
</div>
<script type="module" src="js.js"></script>
</body>
</html>
body {
text-align: center;
margin: 0;
padding: 1rem;
background-color: #f3767c;
font-family: 'Andika New Basic', sans-serif;
font-weight: 700;
user-select: none;
}
#calculator {
width: 58vh;
background: rgb(58,57,62);
background: linear-gradient(124deg, rgba(58,57,62,1) 0%, rgba(19,15,16,1) 100%);
display: block;
margin: auto;
padding: 5vh;
border-radius: 4vh;
}
#screen {
padding: 3vh;
height: 12vh;
background-color: #A2AF77;
border-radius: 4vh;
margin-bottom: 6vh;
font-size: 6.9vh;
text-align: right;
}
#result {
color: rgba(58,57,62,0.5);
height: 4.5vh;
font-size: 3vh;
position: relative;
top: -2vh;
right: 1vh;
margin: 0;
}
#input {
position: relative;
top: -4vh;
}
#grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
column-gap: 2.5vh;
row-gap: 3vh;
font-size: 6vh;
}
button {
font-family: 'Andika New Basic', sans-serif;
font-weight: 700;
font-size: 1em;
color: #FBFDFD;
background-color: #58595B;
border: none;
border-radius: 0.1em;
padding: 0;
outline: none;
cursor: pointer;
}
button:hover {
filter: brightness(0.9);
}
button:active {
transform: translateY(1px) scale(0.99);
filter: brightness(0.6);
}
button img {
width: 0.8em;
}
button:disabled {
pointer-events: none;
filter: brightness(0.5);
cursor: none;
}
.btnOper {
background-color: #130F10;
}
.small {
font-size: 0.75em;
}
.reset {
background-color: #F27B13;
}
const btns = document.querySelectorAll('button[id^=but]')
let input = document.getElementById('input');
let upper = document.getElementById('result');
let result = "0", num = "0";
let op = false, op2 = false;
btns.forEach(btn => {
btn.addEventListener('click', event => {
butType(event, btn);
if(isNaN(num) || !isFinite(num)) {
input.innerHTML = "Error!"
btns.forEach(btn => {
if(btn != btns[0]) {
btn.disabled = true;
}
})
} else {
if(op == false) {
result = num;
}
if (op2 == false) {
if(Decimal(num) >= 10 ** 11 || Decimal(num) <= -(10 ** 11)) {
input.innerHTML = Decimal(Decimal(num).toExponential()).toPrecision(6);
} else {
if(String(num).match(/e/)) {
input.innerHTML = parseFloat(Decimal(num).toPrecision(6));
} else {
input.innerHTML = parseFloat(String(num).slice(0, 12));
}
}
} else {
input.innerHTML = num;
}
}
if((op2 == true || result != num) && op != false) {
upper.innerHTML = Decimal(Decimal(result).toPrecision(11)) + "" + op
} else {
upper.innerHTML = ""
}
});
});
const butType = (event, btn) => {
const id = event.currentTarget.id;
switch(true) {
case /\d/.test(id):
butNum(id[3]);
break;
case /[√^]/.test(id):
butSpecialOp(id[3]);
break;
case id[3] == "/":
butSign();
break;
case id[3] == ".":
butDot();
break;
case id[3] == "=":
butEqual();
break;
case btn.classList.contains("btnOper"):
butOp(id[3]);
break;
default:
[op, num, op2] = [false, "0", false];
btns.forEach(btn => {
btn.disabled = false;
})
}
}
const butNum = (number) => {
String(num)
if(num == "0" || op2 == false) {
num = number;
op2 = true;
} else if (num.match(/[\d\.]/g).length < 12) {
num += number;
}
}
const butOp = (opSign) => {
if((op2 == true || result != num) && op != false) {
butEqual();
}
[op, op2] = [opSign, false]
}
const butSpecialOp = (opSign) => {
if(opSign == "√") {
num = Decimal(num).squareRoot();
} else {
num = Decimal(num).toPower(2);
}
op2 = false;
}
const butDot = () => {
num = String(num);
if(num == "0" || op2 == false) {
num = "0."
} else if(!num.match(/\./) && num.match(/[\d\.]/g).length < 11) {
num += ".";
}
op2 = true;
}
const butSign = () => {
num = String(num)
if(num != "0") {
if(num[0] == "-") {
num = num.slice(1);
} else {
num = "-" + num;
}
}
}
const butEqual = () => {
if(op != false) {
num = math[op](parseFloat(result),parseFloat(num))
}
[op, op2, result] = [false, false, num]
}
let math = {
'+': function (x, y) { return Decimal(x + y) },
'-': function (x, y) { return Decimal(x - y) },
'×': function (x, y) { return Decimal(x * y) },
'÷': function (x, y) { return Decimal(x / y) }
};
This Pen doesn't use any external CSS resources.