HTML5 Hesap Makinesi yapalım.
Özellikler :
9:16 Format & Telefon Çerçevesi: Masaüstünde şık bir akıllı telefon çerçevesinde, mobilde ise tam ekran duyarlı (responsive) olarak çalışır.
4 Canlı Tema Seçeneği: Neon Cyberpunk, Sunset Orange, Electric Purple ve Emerald Neon olmak üzere göze hitap eden canlı tema paletleri mevcuttur.
Standart & Bilimsel Mod: Tek tuşla trigonometrik fonksiyonlar (
sin,cos,tan), karekök, kare alma gibi gelişmiş bilimsel hesaplama moduna geçiş yapabilirsiniz.İşlem Geçmişi: Yapılan tüm işlemler hafızada tutulur, geçmiş panelinden eski sonuçlara tıklayarak tekrar işleme devam edebilirsiniz.
Tamamen Çevrimdışı: Harici kütüphane gerektirmez, tüm veriler tarayıcınızın
localStoragealanında güvenle saklanır.
⚡
Neon Calc
0
İşlem Geçmişi
Henüz geçmiş işlem yok.
<!DOCTYPE html>
<html lang="tr" class="h-full">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canlı Temalı Hesap Makinesi</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
cyber: { bg: '#0b0c10', card: '#1f2833', accent: '#66fcf1', text: '#c5c6c7', btn: '#1f2833', hover: '#45a29e' },
sunset: { bg: '#1a0933', card: '#2d124f', accent: '#ff758c', text: '#ffeb3b', btn: '#3d1b66', hover: '#ff758c' },
electric: { bg: '#0c071e', card: '#1d123d', accent: '#a855f7', text: '#f3e8ff', btn: '#2c1a59', hover: '#c084fc' },
emerald: { bg: '#021c1e', card: '#00332c', accent: '#10b981', text: '#e6fffa', btn: '#004d40', hover: '#34d399' }
}
}
}
}
</script>
<style>
@media (min-width: 640px) {
.phone-frame {
width: 100%;
max-width: 400px;
height: 85vh;
max-height: 820px;
box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.6);
border-radius: 2.5rem;
border: 8px solid rgba(255, 255, 255, 0.1);
overflow: hidden;
}
}
@media (max-width: 639px) {
.phone-frame {
width: 100vw;
height: 100vh;
border-radius: 0;
}
}
.btn-press:active {
transform: scale(0.93);
}
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 10px; }
</style>
</head>
<body class="h-full flex items-center justify-center transition-colors duration-500" id="bodyBg" style="background-color: #0b0c10;">
<!-- 9:16 Telefon Çerçevesi -->
<div id="appContainer" class="phone-frame flex flex-col relative transition-all duration-500 shadow-2xl bg-[#0b0c10] text-[#c5c6c7]">
<!-- Üst Bilgi Çubuğu -->
<header class="px-6 py-4 flex items-center justify-between border-b border-white/10 z-10">
<div class="flex items-center space-x-2">
<span id="appLogo" class="text-xl">⚡</span>
<h1 id="appTitle" class="font-bold text-sm tracking-wider uppercase">Neon Calc</h1>
</div>
<div class="flex items-center space-x-2">
<!-- Mod Değiştir (Standart / Bilimsel) -->
<button onclick="toggleMode()" id="modeBtn" class="px-2.5 py-1 rounded-lg text-xs font-semibold border border-white/20 transition hover:scale-105 active:scale-95">
Bilimsel
</button>
<!-- Geçmiş Butonu -->
<button onclick="toggleHistory()" class="p-2 rounded-xl border border-white/20 transition hover:scale-105 active:scale-95" title="Geçmiş">
📜
</button>
<!-- Tema Menüsü Butonu -->
<button onclick="toggleThemeModal()" class="p-2 rounded-xl border border-white/20 transition hover:scale-105 active:scale-95" title="Temalar">
🎨
</button>
</div>
</header>
<!-- Ekran (Display) Alanı -->
<div class="px-6 py-5 flex flex-col justify-end items-end border-b border-white/10 bg-black/20" style="min-height: 140px;">
<div id="historyDisplay" class="text-xs opacity-60 tracking-wider mb-1 truncate w-full text-right font-mono"></div>
<div id="mainDisplay" class="text-4xl font-bold tracking-tight truncate w-full text-right font-mono transition-all">0</div>
</div>
<!-- Ana Tuş Takımı / Hesap Makinesi Gövdesi -->
<div class="flex-1 p-5 flex flex-col justify-between overflow-y-auto">
<!-- Standart & Bilimsel Buton Grid -->
<div id="keypadGrid" class="grid grid-cols-4 gap-3 my-auto">
<!-- Dinamik olarak doldurulacak -->
</div>
</div>
<!-- Geçmiş Paneli (Slide-over) -->
<div id="historyPanel" class="absolute inset-x-0 bottom-0 top-[70px] bg-inherit z-20 transform translate-y-full transition-transform duration-300 ease-in-out flex flex-col p-5 border-t border-white/10 shadow-2xl">
<div class="flex justify-between items-center mb-4">
<h2 class="font-bold text-sm uppercase tracking-wider">İşlem Geçmişi</h2>
<div class="space-x-2">
<button onclick="clearHistory()" class="text-xs opacity-70 hover:opacity-100 px-2 py-1 border border-white/20 rounded-lg">Temizle</button>
<button onclick="toggleHistory()" class="text-xs opacity-70 hover:opacity-100 font-bold px-2 py-1">✕ Kapat</button>
</div>
</div>
<div id="historyList" class="flex-1 overflow-y-auto space-y-2 pr-1">
<div class="text-center opacity-40 text-xs py-10">Henüz geçmiş işlem yok.</div>
</div>
</div>
<!-- Tema Seçim Paneli (Modal) -->
<div id="themeModal" class="absolute inset-0 z-30 bg-black/70 backdrop-blur-sm hidden flex items-center justify-center p-6">
<div class="w-full max-w-xs rounded-2xl p-5 shadow-2xl border border-white/20 bg-slate-900 text-white" id="themeModalContent">
<div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-sm tracking-wide">Tema Seçin</h3>
<button onclick="toggleThemeModal()" class="text-xs opacity-70 hover:opacity-100 font-bold px-2 py-1">✕ Kapat</button>
</div>
<div class="space-y-2.5">
<button onclick="setTheme('cyber')" class="w-full flex items-center justify-between p-3 rounded-xl border border-white/10 bg-[#1f2833] text-[#66fcf1] font-semibold text-sm transition hover:scale-[1.02]">
<span class="flex items-center space-x-2"><span>⚡</span><span>Neon Cyberpunk</span></span>
<span class="w-4 h-4 rounded-full bg-[#66fcf1]"></span>
</button>
<button onclick="setTheme('sunset')" class="w-full flex items-center justify-between p-3 rounded-xl border border-white/10 bg-[#2d124f] text-[#ff758c] font-semibold text-sm transition hover:scale-[1.02]">
<span class="flex items-center space-x-2"><span>🌅</span><span>Sunset Orange</span></span>
<span class="w-4 h-4 rounded-full bg-[#ff758c]"></span>
</button>
<button onclick="setTheme('electric')" class="w-full flex items-center justify-between p-3 rounded-xl border border-white/10 bg-[#1d123d] text-[#c084fc] font-semibold text-sm transition hover:scale-[1.02]">
<span class="flex items-center space-x-2"><span>🔮</span><span>Electric Purple</span></span>
<span class="w-4 h-4 rounded-full bg-[#a855f7]"></span>
</button>
<button onclick="setTheme('emerald')" class="w-full flex items-center justify-between p-3 rounded-xl border border-white/10 bg-[#00332c] text-[#34d399] font-semibold text-sm transition hover:scale-[1.02]">
<span class="flex items-center space-x-2"><span>💎</span><span>Emerald Neon</span></span>
<span class="w-4 h-4 rounded-full bg-[#10b981]"></span>
</button>
</div>
</div>
</div>
</div>
<!-- JavaScript Hesap Makinesi Mantığı -->
<script>
// Uygulama Durumu
let currentInput = '0';
let historyExpression = '';
let isScientific = false;
let currentTheme = localStorage.getItem('calc_theme') || 'cyber';
let historyList = JSON.parse(localStorage.getItem('calc_history') || '[]');
// Temalar Tanımı
const themes = {
cyber: { bg: '#0b0c10', card: '#1f2833', accent: '#66fcf1', text: '#c5c6c7', btnBg: '#1f2833', btnHover: '#2c3847', opBg: '#2c3847' },
sunset: { bg: '#1a0933', card: '#2d124f', accent: '#ff758c', text: '#ffeb3b', btnBg: '#3d1b66', btnHover: '#4d237d', opBg: '#57227d' },
electric: { bg: '#0c071e', card: '#1d123d', accent: '#c084fc', text: '#f3e8ff', btnBg: '#2c1a59', btnHover: '#3b2473', opBg: '#4c2e8a' },
emerald: { bg: '#021c1e', card: '#00332c', accent: '#34d399', text: '#e6fffa', btnBg: '#004d40', btnHover: '#006655', opBg: '#005f53' }
};
window.onload = function() {
setTheme(currentTheme);
renderKeypad();
updateDisplay();
};
// Tema Uygulama
function setTheme(themeName) {
currentTheme = themeName;
localStorage.setItem('calc_theme', themeName);
const t = themes[themeName];
const container = document.getElementById('appContainer');
container.style.backgroundColor = t.bg;
container.style.color = t.text;
document.getElementById('bodyBg').style.backgroundColor = t.bg;
document.getElementById('themeModal').classList.add('hidden');
renderKeypad();
}
function toggleThemeModal() {
const modal = document.getElementById('themeModal');
modal.classList.toggle('hidden');
}
// Mod Değiştirme (Standart / Bilimsel)
function toggleMode() {
isScientific = !isScientific;
document.getElementById('modeBtn').innerText = isScientific ? 'Standart' : 'Bilimsel';
renderKeypad();
}
// Tuş Takımı Oluşturucu
function renderKeypad() {
const grid = document.getElementById('keypadGrid');
grid.innerHTML = '';
const t = themes[currentTheme];
let buttons = [];
if (isScientific) {
grid.className = "grid grid-cols-4 gap-2.5 my-auto";
buttons = [
{ label: 'sin', action: 'sci', val: 'Math.sin(' },
{ label: 'cos', action: 'sci', val: 'Math.cos(' },
{ label: 'tan', action: 'sci', val: 'Math.tan(' },
{ label: 'π', action: 'num', val: 'Math.PI' },
{ label: 'x²', action: 'sci', val: '**2' },
{ label: '√', action: 'sci', val: 'Math.sqrt(' },
{ label: '(', action: 'num', val: '(' },
{ label: ')', action: 'num', val: ')' },
{ label: 'C', action: 'clear', class: 'text-red-400 font-bold' },
{ label: '⌫', action: 'backspace' },
{ label: '%', action: 'num', val: '/100' },
{ label: '÷', action: 'op', val: '/' },
{ label: '7', action: 'num', val: '7' },
{ label: '8', action: 'num', val: '8' },
{ label: '9', action: 'num', val: '9' },
{ label: '×', action: 'op', val: '*' },
{ label: '4', action: 'num', val: '4' },
{ label: '5', action: 'num', val: '5' },
{ label: '6', action: 'num', val: '6' },
{ label: '-', action: 'op', val: '-' },
{ label: '1', action: 'num', val: '1' },
{ label: '2', action: 'num', val: '2' },
{ label: '3', action: 'num', val: '3' },
{ label: '+', action: 'op', val: '+' },
{ label: '0', action: 'num', val: '0', span: 'col-span-2' },
{ label: '.', action: 'num', val: '.' },
{ label: '=', action: 'calculate', class: 'text-white font-bold shadow-lg' }
];
} else {
grid.className = "grid grid-cols-4 gap-3 my-auto";
buttons = [
{ label: 'C', action: 'clear', class: 'text-red-400 font-bold' },
{ label: '(', action: 'num', val: '(' },
{ label: ')', action: 'num', val: ')' },
{ label: '÷', action: 'op', val: '/' },
{ label: '7', action: 'num', val: '7' },
{ label: '8', action: 'num', val: '8' },
{ label: '9', action: 'num', val: '9' },
{ label: '×', action: 'op', val: '*' },
{ label: '4', action: 'num', val: '4' },
{ label: '5', action: 'num', val: '5' },
{ label: '6', action: 'num', val: '6' },
{ label: '-', action: 'op', val: '-' },
{ label: '1', action: 'num', val: '1' },
{ label: '2', action: 'num', val: '2' },
{ label: '3', action: 'num', val: '3' },
{ label: '+', action: 'op', val: '+' },
{ label: '0', action: 'num', val: '0', span: 'col-span-2' },
{ label: '.', action: 'num', val: '.' },
{ label: '=', action: 'calculate', class: 'text-white font-bold shadow-lg' }
];
}
buttons.forEach(btn => {
const buttonEl = document.createElement('button');
buttonEl.innerText = btn.label;
buttonEl.className = `btn-press py-3.5 rounded-2xl text-sm font-semibold transition-all duration-150 flex items-center justify-center shadow-sm select-none ${btn.span || ''} ${btn.class || ''}`;
if (btn.action === 'calculate') {
buttonEl.style.backgroundColor = t.accent;
buttonEl.style.color = '#000000';
} else {
buttonEl.style.backgroundColor = t.btnBg;
buttonEl.style.color = t.text;
}
buttonEl.onclick = () => handleButton(btn);
grid.appendChild(buttonEl);
});
}
// Tuş Tıklama Mantığı
function handleButton(btn) {
// Hafif titreşim desteği (mobil cihazlar için)
if (navigator.vibrate) navigator.vibrate(15);
if (btn.action === 'num' || btn.action === 'sci') {
if (currentInput === '0' && !isNaN(btn.val)) {
currentInput = btn.val;
} else {
currentInput += btn.val;
}
} else if (btn.action === 'op') {
currentInput += ' ' + btn.label + ' ';
} else if (btn.action === 'clear') {
currentInput = '0';
historyExpression = '';
} else if (btn.action === 'backspace') {
if (currentInput.length > 1) {
currentInput = currentInput.trim().slice(0, -1);
} else {
currentInput = '0';
}
} else if (btn.action === 'calculate') {
calculateResult();
}
updateDisplay();
}
// Hesaplama Fonksiyonu
function calculateResult() {
try {
historyExpression = currentInput;
// Matematiksel sembolleri JS formatına çevir
let evalString = currentInput
.replace(/×/g, '*')
.replace(/÷/g, '/');
let result = eval(evalString);
if (isNaN(result) || !isFinite(result)) {
throw new Error("Geçersiz işlem");
}
// Sonucu yuvarla (hassasiyet hatası önlemek için)
result = parseFloat(result.toFixed(8));
// Geçmişe ekle
addToHistory(historyExpression, result);
currentInput = result.toString();
historyExpression = '';
} catch (error) {
currentInput = 'Hata';
setTimeout(() => { currentInput = '0'; updateDisplay(); }, 1200);
}
}
function updateDisplay() {
document.getElementById('mainDisplay').innerText = currentInput;
document.getElementById('historyDisplay').innerText = historyExpression;
}
// Geçmiş Yönetimi
function addToHistory(expr, res) {
historyList.unshift({ expr: expr, res: res });
if (historyList.length > 20) historyList.pop();
localStorage.setItem('calc_history', JSON.stringify(historyList));
renderHistoryList();
}
function toggleHistory() {
const panel = document.getElementById('historyPanel');
const isClosed = panel.style.transform === 'translateY(0px)' || panel.style.transform === '';
panel.style.transform = isClosed ? 'translateY(0)' : 'translateY(100%)';
if (isClosed) renderHistoryList();
}
function renderHistoryList() {
const listEl = document.getElementById('historyList');
listEl.innerHTML = '';
if (historyList.length === 0) {
listEl.innerHTML = '<div class="text-center opacity-40 text-xs py-10">Henüz geçmiş işlem yok.</div>';
return;
}
historyList.forEach(item => {
const div = document.createElement('div');
div.className = "p-3 rounded-xl border border-white/10 bg-black/20 flex flex-col items-end cursor-pointer hover:bg-white/5 transition";
div.onclick = () => {
currentInput = item.res.toString();
toggleHistory();
updateDisplay();
};
div.innerHTML = `
<span class="text-xs opacity-60 font-mono">${item.expr}</span>
<span class="text-sm font-bold font-mono">${item.res}</span>
`;
listEl.appendChild(div);
});
}
function clearHistory() {
historyList = [];
localStorage.removeItem('calc_history');
renderHistoryList();
}
</script>
</body>
</html>
ÖNEMLİ NOT:
Kodun en üst tarafında yer alan:
<script src="https://cdn.tailwindcss.com"></script>
satırı internete bağımlı çalışır.
tailwindcss.js
dosyasını internetten indirip html dosyasının yanına koyup satırı şu şekilde değiştirirseniz:
<script src="tailwindcss.js"></script>
tamamen localde çalışırsınız.

Yorumlar
Yorum Gönder