Pokażę jak to dzięki pomocy jednej funkcji JavaScript – eval() i podstawowej znajomości HTML, CSS i JavaScript można zbudować kalkulator w przeglądarce internetowej.
Od prostej wersji z obliczeniami w konsoli:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Calculator</title>
</head>
<body>
<p>
<button onclick="
calculation +='1';
console.log(calculation);
">
1
</button>
<button onclick="
calculation +='2';
console.log(calculation);
">
2
</button>
<button onclick="
calculation +='3';
console.log(calculation);
">
3
</button>
<button onclick="
calculation += ' + ';
">
+
</button>
</p>
<p>
<button onclick="
calculation +='4';
console.log(calculation);
">
4
</button>
<button onclick="
calculation +='5';
console.log(calculation);
">
5
</button>
<button onclick="
calculation +='6';
console.log(calculation);
">
6
</button>
<button onclick="
calculation += ' - ';
">
-
</button>
</p>
<p>
<button onclick="
calculation +='7';
console.log(calculation);
">
7
</button>
<button onclick="
calculation +='8';
console.log(calculation);
">
8
</button>
<button onclick="
calculation +='9';
console.log(calculation);
">
9
</button>
<button onclick="
calculation += ' * ';
">
*
</button>
</p>
<p>
<button onclick="
calculation +='0';
console.log(calculation);
">
0
</button>
<button onclick="
calculation += '.';
">
.
</button>
<button onclick="
calculation = eval(calculation);
console.log(calculation);
">
=
</button>
<button onclick="
calculation += ' / ';
">
/
</button>
</p>
<p>
<button onclick="
calculation = '';
console.log(0);
">
Clear
</button>
</p>
<script>
let calculation = "";
</script>
</body>
</html>
Z dodaniem domyślnych stylów i animacji z Bootstrap-a:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<!-- Add Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.calc-button {
width: 60px;
height: 60px;
margin: 5px;
}
.display {
font-size: 2rem;
margin-bottom: 20px;
text-align: right;
padding: 10px;
}
</style>
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-4">
<div class="card p-3 shadow">
<div class="display bg-white border rounded" id="display">0</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
<button class="btn btn-success calc-button" onclick="calculate()">=</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
</div>
<div class="d-flex justify-content-center">
<button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
</div>
</div>
</div>
</div>
</div>
<!-- Add Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script>
let calculation = '';
function updateCalculation(value) {
calculation += value;
document.getElementById('display').innerText = calculation;
}
function calculate() {
try {
calculation = eval(calculation);
document.getElementById('display').innerText = calculation;
} catch (e) {
document.getElementById('display').innerText = 'Error';
}
}
function clearCalculation() {
calculation = '';
document.getElementById('display').innerText = '0';
}
</script>
</body>
</html>
Później dodaniem więcej animacji korzystając z biblioteki jQuery:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<!-- Add Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Add jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Add jQuery UI for animations -->
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<style>
.calc-button {
width: 70px;
height: 70px;
margin: 8px;
font-size: 1.5rem;
}
.display {
font-size: 2.5rem;
margin-bottom: 20px;
text-align: right;
padding: 15px;
background-color: #f8f9fa;
}
.container {
margin-top: 50px;
}
.btn-primary,
.btn-warning,
.btn-danger,
.btn-success {
transition: transform 0.1s ease;
}
</style>
</head>
<body class="bg-light">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-4">
<div class="card p-4 shadow-lg rounded">
<div class="display border rounded" id="display">0</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('1')">1</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('2')">2</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('3')">3</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' + ')">+</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('4')">4</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('5')">5</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('6')">6</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' - ')">-</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('7')">7</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('8')">8</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('9')">9</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' * ')">*</button>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-primary calc-button" onclick="updateCalculation('0')">0</button>
<button class="btn btn-primary calc-button" onclick="updateCalculation('.')">.</button>
<button class="btn btn-success calc-button" onclick="calculate()">=</button>
<button class="btn btn-warning calc-button" onclick="updateCalculation(' / ')">/</button>
</div>
<div class="d-flex justify-content-center">
<button class="btn btn-danger calc-button" onclick="clearCalculation()">Clear</button>
</div>
</div>
</div>
</div>
</div>
<!-- Add Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script>
let calculation = '';
function updateCalculation(value) {
// Add animations for button press
animateButton(value);
calculation += value;
$("#display").text(calculation);
}
function calculate() {
try {
calculation = eval(calculation);
$("#display").text(calculation).effect("bounce", { times: 3 }, 500);
} catch (e) {
$("#display").text('Error').effect("shake", { times: 3 }, 500);
}
}
function clearCalculation() {
calculation = '';
$("#display").text('0').fadeOut(100).fadeIn(100);
}
// Add animation for button clicks
function animateButton(value) {
$(".btn").each(function () {
if ($(this).text() === value) {
$(this).addClass("pressed");
$(this).css("transform", "scale(0.95)");
setTimeout(() => {
$(this).css("transform", "scale(1)");
}, 100);
}
});
}
// Animation for button press style
$(".btn").on("mousedown", function () {
$(this).css("transform", "scale(0.95)");
});
$(".btn").on("mouseup", function () {
$(this).css("transform", "scale(1)");
});
</script>
</body>
</html>
Kończąc na kalkulatorze z motywem prosto z Matrix-a:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Matrix Calculator</title>
<style>
body,
html {
margin: 0;
padding: 0;
height: 100%;
background-color: #000;
color: #00ff00;
font-family: 'Courier New', monospace;
overflow: hidden;
}
#matrix-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
pointer-events: none;
}
.matrix-column {
position: absolute;
top: -50px;
font-size: 14px;
line-height: 1.5;
}
.container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
z-index: 2;
}
.calculator {
background-color: rgba(0, 20, 0, 0.8);
border: 2px solid #00ff00;
border-radius: 10px;
padding: 20px;
box-shadow: 0 0 20px #00ff00;
transition: all 0.5s ease;
}
.calculator:hover {
transform: scale(1.05);
box-shadow: 0 0 30px #00ff00;
}
.display {
width: 240px;
height: 60px;
margin-bottom: 20px;
text-align: right;
padding: 15px;
background-color: #001400;
color: #00ff00;
border-radius: 5px;
border: 1px solid #00ff00;
text-shadow: 0 0 5px #00ff00;
transition: all 0.5s ease;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
font-size: 2.5rem;
display: flexbox;
align-items: center;
justify-content: flex-end;
cursor: text;
user-select: text;
}
.display-content {
transition: all 0.3s ease;
}
.display.animate .display-content {
animation: pulse 0.5s;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.btn {
width: 60px;
height: 60px;
margin: 5px;
font-size: 1.2rem;
background-color: #001400;
color: #00ff00;
border: 1px solid #00ff00;
border-radius: 5px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background-color: rgba(0, 255, 0, 0.5);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.6s ease, height 0.6s ease;
}
.btn:hover {
color: #000;
box-shadow: 0 0 15px #00ff00;
}
.btn:hover::before {
width: 200%;
height: 200%;
}
.btn:active {
transform: scale(0.95);
box-shadow: 0 0 5px #00ff00;
}
.btn span {
position: relative;
z-index: 1;
}
@keyframes glowPulse {
0% {
box-shadow: 0 0 5px #00ff00;
}
50% {
box-shadow: 0 0 20px #00ff00;
}
100% {
box-shadow: 0 0 5px #00ff00;
}
}
.btn:focus {
outline: none;
animation: glowPulse 1s infinite;
}
.display:focus {
outline: none;
box-shadow: 0 0 15px #00ff00;
}
</style>
</head>
<body>
<div id="matrix-bg"></div>
<div class="container">
<div class="calculator">
<div class="display" id="display">
<div class="display-content">0</div>
</div>
<div>
<button class="btn" data-value="7"><span>7</span></button>
<button class="btn" data-value="8"><span>8</span></button>
<button class="btn" data-value="9"><span>9</span></button>
<button class="btn" data-value="+"><span>+</span></button>
</div>
<div>
<button class="btn" data-value="4"><span>4</span></button>
<button class="btn" data-value="5"><span>5</span></button>
<button class="btn" data-value="6"><span>6</span></button>
<button class="btn" data-value="-"><span>-</span></button>
</div>
<div>
<button class="btn" data-value="1"><span>1</span></button>
<button class="btn" data-value="2"><span>2</span></button>
<button class="btn" data-value="3"><span>3</span></button>
<button class="btn" data-value="*"><span>*</span></button>
</div>
<div>
<button class="btn" data-value="0"><span>0</span></button>
<button class="btn" data-value="."><span>.</span></button>
<button class="btn" data-value="="><span>=</span></button>
<button class="btn" data-value="/"><span>/</span></button>
</div>
<div>
<button class="btn" data-value="clear"><span>Clear</span></button>
</div>
</div>
</div>
<script>
const matrixBg = document.getElementById('matrix-bg');
const display = document.getElementById('display');
const displayContent = display.querySelector('.display-content');
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-=[]{}|;:,.<>?';
const rows = Math.floor((window.innerHeight + 50) / 20);
let calculation = '';
let isDisplayFocused = false;
function createColumn() {
const column = document.createElement('div');
column.className = 'matrix-column';
column.style.left = `${Math.random() * window.innerWidth}px`;
let y = -50;
let output = '';
for (let j = 0; j < rows; j++) {
output += characters[Math.floor(Math.random() * characters.length)] + '<br><br>';
}
column.innerHTML = output;
matrixBg.appendChild(column);
function updateColumn() {
y += 5;
if (y > window.innerHeight) {
matrixBg.removeChild(column);
} else {
column.style.transform = `translateY(${y}px)`;
requestAnimationFrame(updateColumn);
}
}
requestAnimationFrame(updateColumn);
}
function startMatrixEffect() {
createColumn();
setTimeout(startMatrixEffect, Math.random() * 500);
}
for (let i = 0; i < 5; i++) {
setTimeout(startMatrixEffect, i * 200);
}
function updateDisplay() {
const scrollPosition = display.scrollLeft;
displayContent.textContent = calculation || '0';
display.classList.add('animate');
setTimeout(() => display.classList.remove('animate'), 500);
if (!isDisplayFocused) {
display.scrollLeft = display.scrollWidth;
} else {
display.scrollLeft = scrollPosition;
}
}
function handleButtonClick(e) {
const btn = e.target.closest('.btn');
if (!btn) return;
btn.classList.add('active');
setTimeout(() => btn.classList.remove('active'), 200);
const value = btn.dataset.value;
if (value === '=') {
try {
calculation = eval(calculation).toString();
} catch (error) {
calculation = 'Error';
}
} else if (value === 'clear') {
calculation = '';
} else {
calculation += value;
}
updateDisplay();
}
document.querySelector('.calculator').addEventListener('click', handleButtonClick);
// Make the display focusable
display.tabIndex = 0;
// Track focus state
display.addEventListener('focus', () => {
isDisplayFocused = true;
});
display.addEventListener('blur', () => {
isDisplayFocused = false;
});
// Prevent default calculator behavior when interacting with the display
display.addEventListener('mousedown', (e) => {
e.stopPropagation();
});
display.addEventListener('touchstart', (e) => {
e.stopPropagation();
});
// Prevent keyboard input on the display
display.addEventListener('keydown', (e) => {
e.preventDefault();
});
let lastTime = 0;
function animate(currentTime) {
if (currentTime - lastTime > 500) {
createColumn();
lastTime = currentTime;
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>
</body>
</html>
Tutaj link do repozytorium z wszystkimi wersjami aplikacji: kalkulator-github
Oraz proste demo z działania:
