mindfullness / index.html
madansa7's picture
Update index.html
da727bb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mindful Moments - Meditation & Breathing Timer</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>
/* Full width container for WordPress */
html, body {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
max-width: 100% !important;
}
.breath-circle {
transition: all 4s cubic-bezier(0.65, 0, 0.35, 1);
transform-origin: center;
}
.inhale {
animation: pulseIn 4s infinite alternate;
}
.exhale {
animation: pulseOut 6s infinite alternate;
}
@keyframes pulseIn {
0% { transform: scale(0.9); opacity: 0.7; }
100% { transform: scale(1.2); opacity: 1; }
}
@keyframes pulseOut {
0% { transform: scale(1.2); opacity: 1; }
100% { transform: scale(0.9); opacity: 0.7; }
}
.progress-ring__circle {
transition: stroke-dashoffset 0.5s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Custom container to prevent overflow */
.wp-container {
width: 100% !important;
padding: 0 !important;
margin: 0 !important;
}
</style>
</head>
<body class="bg-gradient-to-br from-indigo-900 to-purple-900 min-h-screen text-white font-sans wp-container">
<div class="container mx-auto px-4 py-8 max-w-3xl">
<header class="text-center mb-8">
<h1 class="text-4xl font-bold mb-2">Mindful Moments</h1>
<p class="text-xl text-indigo-200">Find your calm with guided breathing exercises</p>
</header>
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 shadow-xl">
<div class="flex flex-col md:flex-row gap-8">
<!-- Timer Section -->
<div class="flex-1">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-semibold">Meditation Timer</h2>
<div class="flex items-center space-x-2">
<button id="sound-toggle" class="p-2 rounded-full hover:bg-white/10 transition">
<i class="fas fa-volume-up"></i>
</button>
<button id="fullscreen-toggle" class="p-2 rounded-full hover:bg-white/10 transition">
<i class="fas fa-expand"></i>
</button>
</div>
</div>
<div class="flex flex-col items-center mb-8">
<div class="relative w-64 h-64 mb-6 flex items-center justify-center">
<!-- Progress ring -->
<svg class="w-full h-full absolute" viewBox="0 0 100 100">
<circle class="text-white/10" stroke-width="4" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50" />
<circle id="progress-ring" class="progress-ring__circle text-indigo-400" stroke-width="4" stroke-dasharray="283" stroke-dashoffset="283" stroke-linecap="round" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50" />
</svg>
<!-- Breathing circle -->
<div id="breath-visual" class="breath-circle absolute w-40 h-40 rounded-full bg-indigo-400/30 flex items-center justify-center">
<div id="breath-text" class="text-2xl font-medium">Ready</div>
</div>
</div>
<div id="time-display" class="text-6xl font-mono mb-6">05:00</div>
<div class="flex space-x-4">
<button id="start-btn" class="px-8 py-3 bg-indigo-600 hover:bg-indigo-700 rounded-full font-medium transition">
Start
</button>
<button id="reset-btn" class="px-8 py-3 bg-white/10 hover:bg-white/20 rounded-full font-medium transition">
Reset
</button>
</div>
</div>
</div>
<!-- Controls Section -->
<div class="flex-1">
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Session Length</h3>
<div class="grid grid-cols-3 gap-3">
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="1">1 min</button>
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="3">3 min</button>
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="5">5 min</button>
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="10">10 min</button>
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="15">15 min</button>
<button class="duration-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition" data-minutes="20">20 min</button>
</div>
</div>
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Breathing Pattern</h3>
<div class="space-y-3">
<div class="flex items-center space-x-3">
<input type="radio" id="pattern-relax" name="breath-pattern" value="relax" class="hidden peer" checked>
<label for="pattern-relax" class="flex-1 py-3 px-4 bg-white/10 hover:bg-white/20 peer-checked:bg-indigo-600 peer-checked:hover:bg-indigo-700 rounded-lg transition cursor-pointer flex items-center justify-between">
<span>Relaxing (4-6-8)</span>
<span class="text-xs opacity-70">Inhale-4 Hold-6 Exhale-8</span>
</label>
</div>
<div class="flex items-center space-x-3">
<input type="radio" id="pattern-balance" name="breath-pattern" value="balance" class="hidden peer">
<label for="pattern-balance" class="flex-1 py-3 px-4 bg-white/10 hover:bg-white/20 peer-checked:bg-indigo-600 peer-checked:hover:bg-indigo-700 rounded-lg transition cursor-pointer flex items-center justify-between">
<span>Balanced (4-4-4)</span>
<span class="text-xs opacity-70">Inhale-4 Hold-4 Exhale-4</span>
</label>
</div>
<div class="flex items-center space-x-3">
<input type="radio" id="pattern-energy" name="breath-pattern" value="energy" class="hidden peer">
<label for="pattern-energy" class="flex-1 py-3 px-4 bg-white/10 hover:bg-white/20 peer-checked:bg-indigo-600 peer-checked:hover:bg-indigo-700 rounded-lg transition cursor-pointer flex items-center justify-between">
<span>Energizing (4-2-4)</span>
<span class="text-xs opacity-70">Inhale-4 Hold-2 Exhale-4</span>
</label>
</div>
</div>
</div>
<div>
<h3 class="text-xl font-semibold mb-4">Ambient Sounds</h3>
<div class="grid grid-cols-2 gap-3">
<button class="sound-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition flex items-center space-x-2" data-sound="rain">
<i class="fas fa-cloud-rain"></i>
<span>Rain</span>
</button>
<button class="sound-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition flex items-center space-x-2" data-sound="forest">
<i class="fas fa-tree"></i>
<span>Forest</span>
</button>
<button class="sound-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition flex items-center space-x-2" data-sound="waves">
<i class="fas fa-water"></i>
<span>Waves</span>
</button>
<button class="sound-btn py-3 px-4 bg-white/10 hover:bg-white/20 rounded-lg transition flex items-center space-x-2" data-sound="none">
<i class="fas fa-times"></i>
<span>None</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="mt-8 text-center text-indigo-200">
<p>Take a deep breath and find your center. Regular practice can reduce stress and improve focus.</p>
</div>
</div>
<!-- Audio elements with updated free sound sources -->
<audio id="inhale-sound" src="https://assets.mixkit.co/active/sounds/preview/mixkit-positive-interface-beep-221.mp3" preload="auto"></audio>
<audio id="exhale-sound" src="https://assets.mixkit.co/active/sounds/preview/mixkit-achievement-bell-600.mp3" preload="auto"></audio>
<audio id="rain-sound" loop src="https://media.rainymood.com/0.m4a" preload="auto"></audio>
<audio id="forest-sound" loop src="https://assets.mixkit.co/active/sounds/preview/mixkit-forest-ambience-1683.mp3" preload="auto"></audio>
<audio id="waves-sound" loop src="https://assets.mixkit.co/active/sounds/preview/mixkit-waves-on-the-beach-1183.mp3" preload="auto"></audio>
<audio id="end-sound" src="https://assets.mixkit.co/active/sounds/preview/mixkit-marimba-alert-2334.mp3" preload="auto"></audio>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM elements
const timeDisplay = document.getElementById('time-display');
const startBtn = document.getElementById('start-btn');
const resetBtn = document.getElementById('reset-btn');
const durationBtns = document.querySelectorAll('.duration-btn');
const breathVisual = document.getElementById('breath-visual');
const breathText = document.getElementById('breath-text');
const progressRing = document.getElementById('progress-ring');
const soundToggle = document.getElementById('sound-toggle');
const fullscreenToggle = document.getElementById('fullscreen-toggle');
const soundBtns = document.querySelectorAll('.sound-btn');
// Audio elements
const inhaleSound = document.getElementById('inhale-sound');
const exhaleSound = document.getElementById('exhale-sound');
const rainSound = document.getElementById('rain-sound');
const forestSound = document.getElementById('forest-sound');
const wavesSound = document.getElementById('waves-sound');
const endSound = document.getElementById('end-sound');
// Variables
let timer;
let totalSeconds = 300; // Default 5 minutes
let remainingSeconds = totalSeconds;
let isRunning = false;
let isBreathing = false;
let soundEnabled = true;
let ambientSound = null;
let currentPattern = 'relax';
let inhaleDuration = 4;
let holdDuration = 6;
let exhaleDuration = 8;
// Initialize
updateTimeDisplay();
setupEventListeners();
function setupEventListeners() {
// Duration buttons
durationBtns.forEach(btn => {
btn.addEventListener('click', function() {
const minutes = parseInt(this.dataset.minutes);
totalSeconds = minutes * 60;
remainingSeconds = totalSeconds;
updateTimeDisplay();
resetProgressRing();
});
});
// Breathing pattern radio buttons
document.querySelectorAll('input[name="breath-pattern"]').forEach(radio => {
radio.addEventListener('change', function() {
currentPattern = this.value;
switch(currentPattern) {
case 'relax':
inhaleDuration = 4;
holdDuration = 6;
exhaleDuration = 8;
break;
case 'balance':
inhaleDuration = 4;
holdDuration = 4;
exhaleDuration = 4;
break;
case 'energy':
inhaleDuration = 4;
holdDuration = 2;
exhaleDuration = 4;
break;
}
});
});
// Sound buttons
soundBtns.forEach(btn => {
btn.addEventListener('click', function() {
const soundType = this.dataset.sound;
// Stop all ambient sounds
rainSound.pause();
forestSound.pause();
wavesSound.pause();
// Remove active class from all buttons
soundBtns.forEach(b => b.classList.remove('bg-indigo-600', 'hover:bg-indigo-700'));
if (soundType !== 'none') {
// Add active class to clicked button
this.classList.add('bg-indigo-600', 'hover:bg-indigo-700');
// Play selected sound
ambientSound = soundType;
if (soundEnabled) {
switch(soundType) {
case 'rain':
rainSound.currentTime = 0;
rainSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'forest':
forestSound.currentTime = 0;
forestSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'waves':
wavesSound.currentTime = 0;
wavesSound.play().catch(e => console.log("Audio play failed:", e));
break;
}
}
} else {
ambientSound = null;
}
});
});
// Start button
startBtn.addEventListener('click', function() {
if (isRunning) {
pauseTimer();
this.textContent = 'Resume';
} else {
startTimer();
this.textContent = 'Pause';
}
});
// Reset button
resetBtn.addEventListener('click', resetTimer);
// Sound toggle
soundToggle.addEventListener('click', toggleSound);
// Fullscreen toggle
fullscreenToggle.addEventListener('click', toggleFullscreen);
}
function startTimer() {
if (!isRunning) {
isRunning = true;
// Start ambient sound if selected
if (soundEnabled && ambientSound) {
switch(ambientSound) {
case 'rain':
rainSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'forest':
forestSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'waves':
wavesSound.play().catch(e => console.log("Audio play failed:", e));
break;
}
}
// Start breathing if not already running
if (!isBreathing) {
startBreathingCycle();
}
timer = setInterval(function() {
remainingSeconds--;
updateTimeDisplay();
updateProgressRing();
if (remainingSeconds <= 0) {
clearInterval(timer);
isRunning = false;
startBtn.textContent = 'Start';
// Play end sound
if (soundEnabled) {
endSound.currentTime = 0;
endSound.play().catch(e => console.log("Audio play failed:", e));
}
// Show completion message
breathText.textContent = 'Complete!';
breathVisual.classList.remove('inhale', 'exhale');
breathVisual.style.transform = 'scale(1)';
// Stop ambient sound
rainSound.pause();
forestSound.pause();
wavesSound.pause();
}
}, 1000);
}
}
function pauseTimer() {
clearInterval(timer);
isRunning = false;
// Pause ambient sound
rainSound.pause();
forestSound.pause();
wavesSound.pause();
// Pause breathing animation
breathVisual.classList.remove('inhale', 'exhale');
breathText.textContent = 'Paused';
}
function resetTimer() {
clearInterval(timer);
isRunning = false;
remainingSeconds = totalSeconds;
updateTimeDisplay();
resetProgressRing();
startBtn.textContent = 'Start';
// Reset breathing
breathVisual.classList.remove('inhale', 'exhale');
breathText.textContent = 'Ready';
breathVisual.style.transform = 'scale(1)';
// Stop all sounds
rainSound.pause();
forestSound.pause();
wavesSound.pause();
inhaleSound.pause();
exhaleSound.pause();
endSound.pause();
}
function updateTimeDisplay() {
const minutes = Math.floor(remainingSeconds / 60);
const seconds = remainingSeconds % 60;
timeDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
function updateProgressRing() {
const circumference = 2 * Math.PI * 45;
const offset = circumference - (remainingSeconds / totalSeconds) * circumference;
progressRing.style.strokeDashoffset = offset;
}
function resetProgressRing() {
progressRing.style.strokeDashoffset = 283;
}
function startBreathingCycle() {
isBreathing = true;
breathCycle();
}
function breathCycle() {
if (!isRunning) return;
// Inhale phase
breathText.textContent = 'Inhale';
breathVisual.classList.remove('exhale');
breathVisual.classList.add('inhale');
if (soundEnabled) {
inhaleSound.currentTime = 0;
inhaleSound.play().catch(e => console.log("Audio play failed:", e));
}
setTimeout(() => {
if (!isRunning) return;
// Hold phase
breathText.textContent = 'Hold';
breathVisual.classList.remove('inhale');
setTimeout(() => {
if (!isRunning) return;
// Exhale phase
breathText.textContent = 'Exhale';
breathVisual.classList.remove('inhale');
breathVisual.classList.add('exhale');
if (soundEnabled) {
exhaleSound.currentTime = 0;
exhaleSound.play().catch(e => console.log("Audio play failed:", e));
}
setTimeout(() => {
if (isRunning) {
breathCycle();
}
}, exhaleDuration * 1000);
}, holdDuration * 1000);
}, inhaleDuration * 1000);
}
function toggleSound() {
soundEnabled = !soundEnabled;
if (soundEnabled) {
soundToggle.innerHTML = '<i class="fas fa-volume-up"></i>';
// Resume ambient sound if one was selected
if (ambientSound) {
switch(ambientSound) {
case 'rain':
rainSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'forest':
forestSound.play().catch(e => console.log("Audio play failed:", e));
break;
case 'waves':
wavesSound.play().catch(e => console.log("Audio play failed:", e));
break;
}
}
} else {
soundToggle.innerHTML = '<i class="fas fa-volume-mute"></i>';
// Pause all sounds
rainSound.pause();
forestSound.pause();
wavesSound.pause();
inhaleSound.pause();
exhaleSound.pause();
}
}
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
console.error(`Error attempting to enable fullscreen: ${err.message}`);
});
fullscreenToggle.innerHTML = '<i class="fas fa-compress"></i>';
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
fullscreenToggle.innerHTML = '<i class="fas fa-expand"></i>';
}
}
}
});
</script>
</html>