Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions Hanzala Bhoraniya/Glass_Calculator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
![Calculator Preview](./preview.png)
# 🧮 Glass Calculator

A beautifully designed, fully functional web-based calculator featuring a modern **Glassmorphism** user interface. This project was built to practice DOM manipulation, JavaScript logic, and advanced CSS styling techniques.

## ✨ Features

* **Glassmorphism UI:** Built with translucent backgrounds, frosted glass effects (`backdrop-filter`), and subtle borders to create a sleek, modern look.
* **Animated Background:** Features a custom CSS `@keyframes` animation with moving ambient radial gradients.
* **Dynamic Display:** The calculator features a dual-display system. It shows your current equation on top and automatically calculates the live answer on the bottom as you type.
* **Full Functionality:** * Standard arithmetic operations (`+`, `-`, `×`, `÷`)
* Percentage calculations (`%`)
* Decimal support with logic to prevent multiple/invalid decimal placements
* Backspace and All Clear (`AC`) functionality

## 🛠️ Tech Stack

* **HTML5:** Semantic structure and layout.
* **CSS3:** Advanced styling, CSS Grid for the button layout, Flexbox, keyframe animations, and custom hover states.
* **JavaScript (Vanilla):** Event listeners, error handling (`try/catch`), string parsing, and calculation logic.

## 🚀 What I Learned

While building this project, I strengthened my skills in:
* **CSS Grid & Flexbox:** Precisely aligning the calculator buttons and display areas.
* **Event Delegation:** Handling clicks for all calculator buttons efficiently.
* **Edge-case Logic:** Writing JavaScript to handle weird user inputs (like pressing multiple decimals or operators in a row).

## 👤 Author

**Hanzala Bhoraniya**
* Part of the Web Development journey (Delta Projects)
49 changes: 49 additions & 0 deletions Hanzala Bhoraniya/Glass_Calculator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Glass Calculator</title>
<link rel="stylesheet" href="style.css" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Poppins:wght@500;700&family=Space+Mono&display=swap"
rel="stylesheet"
/>
</head>
<body>
<div id="header-text">
<h1>Glass Calculator</h1>
</div>
<div id="calculator">
<div id="calculator-display">
<p id="upper-text" class="display-text"></p>
<p id="lower-text" class="display-text small-text"></p>
</div>
<div id="all-btns">
<button id="clear-all" class="btns action">AC</button>
<button id="backspace" class="btns action"><img src="Assets/Icons/gemini-svg.svg" alt="backspace"></button>
<button id="percentage" class="btns action">%</button>
<button id="equal" class="btns action">=</button>

<button class="btns operator">÷</button>
<button class="btns operator">×</button>
<button class="btns operator">-</button>
<button class="btns operator">+</button>


<button class="btns nums zero">0</button>
<button class="btns nums one">1</button>
<button class="btns nums two">2</button>
<button class="btns nums three">3</button>
<button class="btns nums four">4</button>
<button class="btns nums five">5</button>
<button class="btns nums six">6</button>
<button class="btns nums seven">7</button>
<button class="btns nums eight">8</button>
<button class="btns nums nine">9</button>
<button class="btns nums dot">.</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Binary file added Hanzala Bhoraniya/Glass_Calculator/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 126 additions & 0 deletions Hanzala Bhoraniya/Glass_Calculator/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
let display = document.querySelector("#calculator-display");
let upperDisplay = document.querySelector("#upper-text");
let lowerDisplay = document.querySelector("#lower-text");
let nums = document.querySelectorAll(".nums");
let operator = document.querySelectorAll(".operator");
let action = document.querySelectorAll(".action");
let allBtns = document.querySelector("#all-btns");
let btns = document.querySelectorAll(".btns");
let backspace = document.querySelector("#backspace");
let validOperators = ["+", "-", "×", "÷"];
// All functions defination.
function clearAll() {
upperDisplay.innerText = "";
lowerDisplay.innerText = "";
upperDisplay.classList.remove("small-text");
lowerDisplay.classList.add("small-text");
}
function getAns(number) {
try {
if (validOperators.includes(number[number.length - 1])) {
number = number.slice(0, -1);
}
number = number.replaceAll("÷", "/").replaceAll("×", "*");
return eval(number);
} catch (error) {
console.log(error);
return "error";
}
}
function parts(text) {
return text.split(/[\×\÷\+\-]/);
}
// All other logic
allBtns.addEventListener("click", (event) => {
if (event.target.classList.contains("btns")) {
if (event.target.classList.contains("action")) {
if (event.target.innerText === `AC`) {
clearAll();
} else if (event.target.innerText === "=") {
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
// adding and removing class.
lowerDisplay.classList.remove("small-text");
upperDisplay.classList.add("small-text");
} else if (event.target.innerText === "%") {
let equationArr = parts(upperDisplay.innerText);
let percentNum = equationArr[equationArr.length - 1] / 100;
let lastNumLength = equationArr[equationArr.length - 1].length;
let firstText = upperDisplay.innerText.slice(0, -lastNumLength);
upperDisplay.innerText = firstText + percentNum;
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
} else if (event.target === backspace) {
upperDisplay.innerText = upperDisplay.innerText.slice(0, -1);
if (upperDisplay.innerText === "") {
lowerDisplay.innerText = "";
return;
}
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
}
} else if (event.target.classList.contains("operator")) {
if (upperDisplay.innerText === "0" || upperDisplay.innerText === "") {
upperDisplay.innerText = "";
} else if (
validOperators.includes(
upperDisplay.innerText[upperDisplay.innerText.length - 1],
)
) {
upperDisplay.innerText =
upperDisplay.innerText.slice(0, -1) + event.target.innerText;
} else if (upperDisplay.classList.contains("small-text")) {
upperDisplay.classList.remove("small-text");
lowerDisplay.classList.add("small-text");
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
upperDisplay.innerText =
lowerDisplay.innerText.slice(1) + event.target.innerText;
} else {
upperDisplay.innerText += event.target.innerText;
}
} else if (event.target.classList.contains("nums")) {
if (event.target.innerText === ".") {
//1. cheking if the last charedter is alredy dot but then also user is pressing dot btn again do notiong.
if ((upperDisplay.innerText[upperDisplay.innerText.length - 1] === ".")) {
upperDisplay.innerText =
upperDisplay.innerText.slice(0, -1) + event.target.innerText;
// upperDisplay.innerText += event.target.innerText;
}
//2. cheking if the last element is the a opeator then write 0. insted of directly writing decimal after a valid operator.
else if (validOperators.includes(upperDisplay.innerText[upperDisplay.innerText.length - 1])) {
upperDisplay.innerText += "0.";
}
//3. cheking if the number which currently user is typing alredy consist dot if yes then do noting.
else if (upperDisplay.innerText.includes(".") && upperDisplay.innerText.length > 0) {
let decimalArr = parts(upperDisplay.innerText);
if (!(decimalArr[decimalArr.length - 1].includes("."))) {
upperDisplay.innerText += ".";
}
}
//4. cheking if the user is pressing the dot as his first num then we will write 0. inted of just writing dot which will create an err.
else if (upperDisplay.innerText === "" || upperDisplay.innerText === "0") {
upperDisplay.innerText = "0.";
}
else {
upperDisplay.innerText += event.target.innerText
}
}
else if (upperDisplay.innerText === "0" || upperDisplay.innerText === "") {
if (event.target.innerText === "0") {
upperDisplay.innerText = 0;
}
else {
upperDisplay.innerText = event.target.innerText;
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
}
}
else {
if (upperDisplay.classList.contains("small-text")) {
upperDisplay.classList.remove("small-text");
lowerDisplay.classList.add("small-text");
clearAll();
upperDisplay.innerText = lowerDisplay.innerText.slice(1);
}
upperDisplay.innerText += event.target.innerText;
lowerDisplay.innerText = `=${getAns(upperDisplay.innerText)}`;
}
}
}
});
Loading