<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<title>Calculator</title>
</head>
<body>
<section class="calculator-grid">
<div class="output">
<div data-previous-operand class="previous"></div>
<div data-current-operand class="current"></div>
</div>
<button data-all-clear class="span-two yellow">AC</button>
<button data-delete class="yellow">DEL</button>
<button data-operation class="light-purple">÷</button>
<button data-number="7">7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operation class="light-purple">×</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operation class="light-purple">-</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operation class="light-purple">+</button>
<button data-number class="span-two">0</button>
<button data-number>.</button>
<button data-equals class="dark-purple">=</button>
</section>
<script src="index.js"></script>
</body>
</html>
* {
font-family: "Roboto", sans-serif;
margin: 0;
padding: 0;
}
body {
background-color: #fdfdfd;
}
button {
border-radius: 50%;
width: 70px;
height: 70px;
text-align: center;
font-size: 1.5rem;
border: 1px;
background-image: linear-gradient(#e8e8e8 0%, #ddd 100%);
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5),
0 2px 2px rgba(0, 0, 0, 0.19);
border-bottom: solid 2px #b5b5b5;
}
button:active {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5),
0 2px 2px rgba(0, 0, 0, 0.19);
border-bottom: none;
}
.span-two {
grid-column: 1 / span 2;
width: 160px;
border-radius: 50px;
}
.calculator-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 6px;
width: 350px;
margin: 5rem auto;
box-shadow: 5px 5px 15px 5px rgba(234, 232, 232, 0.25);
border-radius: 10px;
padding: 50px 20px;
}
.output {
grid-column-start: span 4;
font-size: 3rem;
display: inline;
vertical-align: bottom;
text-align: right;
padding-top: 50px;
word-wrap: break-word;
word-break: break-all;
}
.previous,
.current {
padding: 5px 20px;
height: 50px;
}
.previous {
font-size: 1.5rem;
color: #515050;
}
.light-purple {
background-image: linear-gradient(#dccdff 0%, #b07ad5 100%);
color: #8c00ff;
}
.dark-purple {
background-image: linear-gradient(#7b43ff 0%, #660ea2 100%);
color: #fff;
}
.yellow {
background-image: linear-gradient(#fff8bd 0%, #f4db79 100%);
color: #e9ab36;
}
class Calculator {
constructor(previousOperationTextEl, currentOperationTextEl) {
this.previousOperationTextEl = previousOperationTextEl;
this.currentOperationTextEl = currentOperationTextEl;
this.clear();
}
// functions
clear() {
this.currentOperand = "";
this.previousOperand = "";
this.operation = undefined;
}
delete() {
this.currentOperand = this.currentOperand.toString().slice(0, -1);
}
appendNumber(number) {
if (number === "." && this.currentOperand.includes(".")) return;
this.currentOperand = this.currentOperand.toString() + number.toString();
}
chooseOperation(operation) {
if (this.currentOperand === "") return; // if currentOperand is empty, exit the function now
if (this.previousOperand !== "") {
this.compute();
}
this.operation = operation;
this.previousOperand = this.currentOperand;
this.currentOperand = "";
}
compute() {
let computation;
const prev = parseFloat(this.previousOperand);
const current = parseFloat(this.currentOperand);
if (isNaN(prev) || isNaN(current)) return; // if the user click equals button with enpty numbers, cancel this function
switch (this.operation) {
case "+":
computation = prev + current;
break;
case "-":
computation = prev - current;
break;
case "÷":
computation = prev / current;
break;
case "×":
computation = prev * current;
break;
case "%":
computation = prev / current;
break;
default:
return;
}
this.currentOperand = computation;
this.operation = undefined;
this.previousOperand = "";
}
getDisplayNumber(number) {
const stringNumber = number.toString();
const integerDigits = parseFloat(stringNumber.split("."[0]));
const decimalDigits = stringNumber.split(".")[1];
let integerDisplay;
if (isNaN(integerDigits)) {
integerDisplay = "";
} else {
integerDisplay = integerDigits.toLocaleString("en", {
maximamFractionDigits: 0,
});
}
if (decimalDigits != null) {
return `${integerDisplay}.${decimalDigits}`;
} else {
return integerDisplay;
}
}
updateDisplay() {
this.currentOperationTextEl.innerText = this.getDisplayNumber(
this.currentOperand,
);
if (this.operation != null) {
this.previousOperationTextEl.innerText = `${this.getDisplayNumber(
this.previousOperand,
)} ${this.operation}`;
} else {
this.previousOperationTextEl.innerText = "";
}
}
}
const numberButtons = document.querySelectorAll("[data-number]");
const operationButtons = document.querySelectorAll("[data-operation]");
const equalsButton = document.querySelector("[data-equals]");
const deleteButton = document.querySelector("[data-delete]");
const allClearButton = document.querySelector("[data-all-clear]");
const previousOperationTextEl = document.querySelector(
"[data-previous-operand]",
);
const currentOperationTextEl = document.querySelector("[data-current-operand]");
const calculator = new Calculator(
previousOperationTextEl,
currentOperationTextEl,
);
numberButtons.forEach((button) => {
button.addEventListener("click", () => {
calculator.appendNumber(button.innerText);
calculator.updateDisplay();
console.log(calculator.currentOperand);
});
});
operationButtons.forEach((button) => {
button.addEventListener("click", () => {
calculator.chooseOperation(button.innerText);
calculator.updateDisplay();
});
});
allClearButton.addEventListener("click", () => {
calculator.clear();
calculator.updateDisplay();
});
equalsButton.addEventListener("click", () => {
calculator.compute();
calculator.updateDisplay();
});
deleteButton.addEventListener("click", () => {
calculator.delete();
calculator.updateDisplay();
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.