raj / index.html
Rajkumar122f's picture
Create a Flutter-based, cross-platform calculator app (Android & iOS) with the following ultra-detailed specs: 1. UI / UX β€’ Full glassmorphism card design with backdrop blur. β€’ Neon-glow accents (cyan by day, magenta by night). β€’ Micro-interactions: 120 ms haptic feedback + 180 ms ripple-splash on every key. β€’ Numbers slide-in with 300 ms cubic-bezier ease-out animation. 2. Day / Night Toggle β€’ Floating Sun 🌞 / Moon πŸŒ™ toggle top-right. β€’ 500 ms animated gradient transition: – Day: soft pastel gradient (#F6F9FC - Initial Deployment
5859752 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Glassmorphic Calculator</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes slideIn {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.number-animation {
animation: slideIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
.glassmorphism {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
}
.ripple {
position: relative;
overflow: hidden;
}
.ripple-effect {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: scale(0);
animation: ripple 0.6s linear;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
.day-mode {
background: linear-gradient(135deg, #F6F9FC 0%, #E6F0F8 100%);
}
.night-mode {
background: linear-gradient(135deg, #0F0C29 0%, #302B63 50%, #24243E 100%);
}
.day-text {
color: #2D3748;
}
.night-text {
color: #E2E8F0;
}
.day-accent {
box-shadow: 0 0 15px rgba(0, 255, 255, 0.7);
}
.night-accent {
box-shadow: 0 0 15px rgba(255, 0, 255, 0.7);
}
.day-button {
background: rgba(255, 255, 255, 0.8);
color: #2D3748;
}
.night-button {
background: rgba(30, 30, 60, 0.8);
color: #E2E8F0;
}
.day-display {
background: rgba(255, 255, 255, 0.9);
color: #2D3748;
}
.night-display {
background: rgba(30, 30, 60, 0.9);
color: #E2E8F0;
}
.theme-toggle {
transition: all 0.5s ease;
}
.theme-toggle:hover {
transform: rotate(180deg);
}
.gradient-transition {
transition: background 0.5s ease;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4 day-mode gradient-transition">
<div class="glassmorphism w-full max-w-md p-6 relative overflow-hidden">
<!-- Theme Toggle -->
<div class="absolute top-4 right-4 z-10">
<button id="themeToggle" class="w-12 h-12 rounded-full flex items-center justify-center bg-white bg-opacity-20 shadow-lg theme-toggle">
<i id="themeIcon" class="fas fa-sun text-yellow-500 text-xl"></i>
</button>
</div>
<!-- Display -->
<div id="display" class="day-display rounded-xl p-4 mb-6 h-24 flex flex-col justify-between transition-all duration-300">
<div id="history" class="text-right text-sm opacity-70 h-6 overflow-hidden"></div>
<div id="result" class="text-right text-3xl font-semibold overflow-x-auto">0</div>
</div>
<!-- Keypad -->
<div class="grid grid-cols-4 gap-3">
<!-- Row 1 -->
<button class="ripple day-button rounded-xl p-4 text-xl font-medium transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('AC')">AC</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('Β±')">Β±</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('%')">%</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium bg-cyan-500 text-white day-accent transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('Γ·')">Γ·</button>
<!-- Row 2 -->
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('7')">7</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('8')">8</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('9')">9</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium bg-cyan-500 text-white day-accent transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('Γ—')">Γ—</button>
<!-- Row 3 -->
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('4')">4</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('5')">5</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('6')">6</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium bg-cyan-500 text-white day-accent transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('-')">-</button>
<!-- Row 4 -->
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('1')">1</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('2')">2</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('3')">3</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium bg-cyan-500 text-white day-accent transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('+')">+</button>
<!-- Row 5 -->
<button class="ripple day-button rounded-xl p-4 text-xl font-medium number-animation col-span-2 transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('0')">0</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium transition-all duration-200 hover:opacity-80 active:scale-95" onclick="appendToDisplay('.')">.</button>
<button class="ripple day-button rounded-xl p-4 text-xl font-medium bg-cyan-500 text-white day-accent transition-all duration-200 hover:opacity-80 active:scale-95" onclick="calculate()">=</button>
</div>
</div>
<script>
// Calculator logic
let currentInput = '0';
let previousInput = '';
let operation = null;
let resetScreen = false;
// DOM elements
const resultDisplay = document.getElementById('result');
const historyDisplay = document.getElementById('history');
const themeToggle = document.getElementById('themeToggle');
const themeIcon = document.getElementById('themeIcon');
const display = document.getElementById('display');
const body = document.body;
// Initialize calculator
updateDisplay();
// Theme toggle
let isDayMode = true;
themeToggle.addEventListener('click', () => {
isDayMode = !isDayMode;
if (isDayMode) {
body.classList.remove('night-mode');
body.classList.add('day-mode');
themeIcon.classList.remove('fa-moon');
themeIcon.classList.add('fa-sun');
themeIcon.classList.remove('text-purple-300');
themeIcon.classList.add('text-yellow-500');
// Update all buttons
document.querySelectorAll('.day-button').forEach(button => {
button.classList.remove('night-button');
button.classList.add('day-button');
});
// Update display
display.classList.remove('night-display');
display.classList.add('day-display');
// Update accents
document.querySelectorAll('.day-accent').forEach(button => {
button.classList.remove('night-accent');
button.classList.add('day-accent');
button.classList.remove('bg-purple-500');
button.classList.add('bg-cyan-500');
});
} else {
body.classList.remove('day-mode');
body.classList.add('night-mode');
themeIcon.classList.remove('fa-sun');
themeIcon.classList.add('fa-moon');
themeIcon.classList.remove('text-yellow-500');
themeIcon.classList.add('text-purple-300');
// Update all buttons
document.querySelectorAll('.day-button').forEach(button => {
button.classList.remove('day-button');
button.classList.add('night-button');
});
// Update display
display.classList.remove('day-display');
display.classList.add('night-display');
// Update accents
document.querySelectorAll('.day-accent').forEach(button => {
button.classList.remove('day-accent');
button.classList.add('night-accent');
button.classList.remove('bg-cyan-500');
button.classList.add('bg-purple-500');
});
}
});
// Ripple effect
document.querySelectorAll('.ripple').forEach(button => {
button.addEventListener('click', function(e) {
// Haptic feedback simulation
if (navigator.vibrate) {
navigator.vibrate(120);
}
// Create ripple
const ripple = document.createElement('span');
ripple.classList.add('ripple-effect');
// Position ripple
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
ripple.style.left = `${x}px`;
ripple.style.top = `${y}px`;
this.appendChild(ripple);
// Remove ripple after animation
setTimeout(() => {
ripple.remove();
}, 600);
});
});
// Number animation
function animateNumberButtons() {
const numberButtons = document.querySelectorAll('.number-animation');
numberButtons.forEach(button => {
button.style.animation = 'none';
void button.offsetWidth; // Trigger reflow
button.style.animation = 'slideIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards';
});
}
// Calculator functions
function appendToDisplay(value) {
if (value === 'AC') {
currentInput = '0';
previousInput = '';
operation = null;
updateDisplay();
return;
}
if (value === 'Β±') {
currentInput = (parseFloat(currentInput) * -1).toString();
updateDisplay();
return;
}
if (value === '%') {
currentInput = (parseFloat(currentInput) / 100).toString();
updateDisplay();
return;
}
if (['+', '-', 'Γ—', 'Γ·'].includes(value)) {
if (operation !== null) calculate();
previousInput = currentInput;
currentInput = '0';
operation = value;
updateDisplay();
return;
}
if (value === '.') {
if (!currentInput.includes('.')) {
currentInput += '.';
}
updateDisplay();
return;
}
if (currentInput === '0' || resetScreen) {
currentInput = value;
resetScreen = false;
} else {
currentInput += value;
}
updateDisplay();
animateNumberButtons();
}
function calculate() {
let result;
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (operation) {
case '+':
result = prev + current;
break;
case '-':
result = prev - current;
break;
case 'Γ—':
result = prev * current;
break;
case 'Γ·':
result = prev / current;
break;
default:
return;
}
currentInput = result.toString();
operation = null;
resetScreen = true;
updateDisplay();
}
function updateDisplay() {
resultDisplay.textContent = currentInput;
historyDisplay.textContent = previousInput + (operation ? ` ${operation} ` : '');
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Rajkumar122f/raj" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>