Valentine_prop / static /script.js
Hemann's picture
Update static/script.js
e973a2a verified
Raw
History Blame Contribute Delete
16.8 kB
// Wait for DOM to be fully loaded
document.addEventListener('DOMContentLoaded', function () {
// State
let noClickCount = 0;
let yesButtonScale = 1;
// Creative messages when clicking "No"
const noMessages = [
"Are you sure? πŸ₯Ί",
"Really? Think again! πŸ’­",
"But... but... 😒",
"You're breaking my heart! πŸ’”",
"Please reconsider? πŸ™",
"I'll give you chocolate! 🍫",
"What if I say pretty please? πŸ₯Ή",
"The Yes button is getting bigger... notice? πŸ‘€",
"I'll be sad forever... 😭",
"Just one chance? 🎯",
"I promise to be awesome! ⭐",
"You're making the teddy bear cry! πŸ§ΈπŸ’§",
"Even the flowers are wilting... πŸ’πŸ˜”",
"My heart is doing backflips of sadness! πŸ€Έβ€β™‚οΈπŸ’”",
"The universe wants you to say yes! 🌌",
"I'll write you poetry! πŸ“βœ¨",
"I'll serenade you! 🎡🎀",
"Fine, I'll do the dishes for a month! 🍽️",
"I'll let you pick all the movies! 🎬",
"Okay seriously, just click Yes already! 😀",
"The No button is getting tired... 😴",
"Even my grandma thinks you should say yes! πŸ‘΅",
"I'll give you my Netflix password! πŸ“Ί",
"The stars are aligning for a YES! ⭐✨",
"This is your sign to click YES! πŸͺ§",
"I'll buy you pizza! πŸ•",
"Come on, you know you want to! 😏",
"The Yes button misses you! πŸ’š",
"I'll teach you my secret cookie recipe! πŸͺ",
"Fine, you can have the last slice! 🍰",
"I'm running out of creative messages... πŸ˜…",
"Seriously though... please? πŸ₯ΊπŸ‘‰πŸ‘ˆ",
"The No button doesn't even work anymore! 🚫",
"You've unlocked: Persistent Mode! πŸ”“",
"I'll never give up! Never! πŸ’ͺ",
"This is like the 100th no... just say yes! πŸ’―",
"The teddy bear is packing its bags... 🧳🧸",
"Okay, you win... JK! Keep trying! 😜",
"Plot twist: There is no No button! 🎭",
"You're really testing my patience here! ⏰",
"The Yes button is HUGE now! How can you resist? 🎯",
"I'll name a star after you! ⭐",
"Fine, I'll do your laundry too! πŸ‘•",
"This is getting ridiculous... just say yes! 🀦",
"The No button is having an existential crisis! πŸ€”",
"Even the code is begging you to click Yes! πŸ’»",
"I'll give you unlimited hugs! πŸ€—",
"The universe is literally expanding the Yes button! 🌍",
"You're more stubborn than a mule! 🐴",
"Okay fine, you can have my fries! 🍟"
];
// DOM Elements
const yesBtn = document.getElementById('yesBtn');
const noBtn = document.getElementById('noBtn');
const phrase = document.getElementById('phrase');
const questionScreen = document.getElementById('questionScreen');
const successScreen = document.getElementById('successScreen');
const attemptCounter = document.getElementById('attemptCounter');
const replayBtn = document.getElementById('replayBtn');
const statsMessage = document.getElementById('statsMessage');
const copyBtn = document.getElementById('copyBtn');
const shareUrl = document.getElementById('shareUrl');
const sparkleCanvas = document.getElementById('sparkleCanvas');
// Initialize
init();
function init() {
// Set up canvas
sparkleCanvas.width = window.innerWidth;
sparkleCanvas.height = window.innerHeight;
// Create floating hearts
createFloatingHearts();
// Set share URL
shareUrl.value = window.location.href;
// Event listeners
yesBtn.addEventListener('click', handleYesClick);
noBtn.addEventListener('click', handleNoClick);
replayBtn.addEventListener('click', resetGame);
copyBtn.addEventListener('click', copyShareLink);
// Sparkle effect on mouse move
document.addEventListener('mousemove', createSparkle);
// Resize canvas on window resize
window.addEventListener('resize', () => {
sparkleCanvas.width = window.innerWidth;
sparkleCanvas.height = window.innerHeight;
});
}
function handleYesClick() {
// Play celebration sound
playCelebrationSound();
// Add explosion effect on button
createButtonExplosion(yesBtn);
// Screen shake effect
document.body.classList.add('screen-shake');
setTimeout(() => document.body.classList.remove('screen-shake'), 500);
// Hide question screen
questionScreen.classList.remove('active');
// Show success screen with animation
setTimeout(() => {
successScreen.classList.add('active');
createConfetti();
createFireworks();
createHeartExplosion();
// Show stats
if (noClickCount > 0) {
statsMessage.textContent = `It took ${noClickCount} "No" click${noClickCount > 1 ? 's' : ''} before you said yes! πŸ˜„`;
} else {
statsMessage.textContent = "You said yes right away! You're amazing! 🌟";
}
}, 300);
}
function handleNoClick() {
noClickCount++;
// Update counter
attemptCounter.textContent = `No clicks: ${noClickCount}`;
// Show message
const messageIndex = Math.min(noClickCount - 1, noMessages.length - 1);
phrase.textContent = noMessages[messageIndex];
phrase.classList.add('shake');
setTimeout(() => phrase.classList.remove('shake'), 500);
// Make Yes button bigger
yesButtonScale += 0.1;
yesBtn.style.transform = `scale(${yesButtonScale})`;
// Make No button smaller and move it
const newSize = Math.max(0.5, 1 - (noClickCount * 0.05));
noBtn.style.transform = `scale(${newSize})`;
// Move No button to random position after 5 clicks
if (noClickCount >= 5) {
moveNoButton();
}
// Make No button harder to click after 10 clicks
if (noClickCount >= 10) {
noBtn.addEventListener('mouseenter', dodgeButton);
}
}
function moveNoButton() {
const container = document.querySelector('.button-container');
const containerRect = container.getBoundingClientRect();
const btnRect = noBtn.getBoundingClientRect();
const maxX = containerRect.width - btnRect.width;
const maxY = containerRect.height - btnRect.height;
const randomX = Math.random() * maxX;
const randomY = Math.random() * maxY;
noBtn.style.position = 'absolute';
noBtn.style.left = `${randomX}px`;
noBtn.style.top = `${randomY}px`;
}
function dodgeButton() {
const container = document.querySelector('.button-container');
const containerRect = container.getBoundingClientRect();
const randomX = Math.random() * (containerRect.width - 100);
const randomY = Math.random() * (containerRect.height - 50);
noBtn.style.left = `${randomX}px`;
noBtn.style.top = `${randomY}px`;
}
function resetGame() {
noClickCount = 0;
yesButtonScale = 1;
// Reset UI
phrase.textContent = '';
attemptCounter.textContent = '';
yesBtn.style.transform = 'scale(1)';
noBtn.style.transform = 'scale(1)';
noBtn.style.position = 'relative';
noBtn.style.left = 'auto';
noBtn.style.top = 'auto';
noBtn.removeEventListener('mouseenter', dodgeButton);
// Switch screens
successScreen.classList.remove('active');
setTimeout(() => {
questionScreen.classList.add('active');
}, 300);
}
function createFloatingHearts() {
const heartsBackground = document.getElementById('heartsBackground');
const heartEmojis = ['πŸ’•', 'πŸ’–', 'πŸ’—', 'πŸ’“', 'πŸ’', '❀️', '🧑', 'πŸ’›', 'πŸ’š', 'πŸ’™', 'πŸ’œ'];
for (let i = 0; i < 15; i++) {
const heart = document.createElement('div');
heart.className = 'floating-heart';
heart.textContent = heartEmojis[Math.floor(Math.random() * heartEmojis.length)];
heart.style.left = `${Math.random() * 100}%`;
heart.style.animationDuration = `${10 + Math.random() * 10}s`;
heart.style.animationDelay = `${Math.random() * 5}s`;
heart.style.fontSize = `${20 + Math.random() * 20}px`;
heartsBackground.appendChild(heart);
}
}
function createSparkle(e) {
const ctx = sparkleCanvas.getContext('2d');
const x = e.clientX;
const y = e.clientY;
// Random sparkle properties
const size = Math.random() * 3 + 1;
const life = 30;
drawSparkle(ctx, x, y, size, life);
}
function drawSparkle(ctx, x, y, size, life) {
if (life <= 0) return;
ctx.fillStyle = `rgba(255, ${100 + life * 5}, ${150 + life * 3}, ${life / 30})`;
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fill();
setTimeout(() => {
ctx.clearRect(x - size - 1, y - size - 1, size * 2 + 2, size * 2 + 2);
drawSparkle(ctx, x, y, size, life - 1);
}, 50);
}
function createConfetti() {
const duration = 3000;
const animationEnd = Date.now() + duration;
const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];
const confettiInterval = setInterval(() => {
const timeLeft = animationEnd - Date.now();
if (timeLeft <= 0) {
clearInterval(confettiInterval);
return;
}
const particleCount = 3;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'confetti';
particle.style.left = `${Math.random() * 100}%`;
particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
particle.style.animationDuration = `${Math.random() * 2 + 1}s`;
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 3000);
}
}, 50);
}
function copyShareLink() {
shareUrl.select();
shareUrl.setSelectionRange(0, 99999); // For mobile devices
navigator.clipboard.writeText(shareUrl.value).then(() => {
const originalText = copyBtn.textContent;
copyBtn.textContent = 'Copied! βœ“';
copyBtn.style.backgroundColor = '#10b981';
setTimeout(() => {
copyBtn.textContent = originalText;
copyBtn.style.backgroundColor = '';
}, 2000);
});
}
// Play celebration sound/song
function playCelebrationSound() {
try {
const loveSong = document.getElementById('loveSong');
// Reset and play the song
if (loveSong) {
loveSong.currentTime = 0; // Start from beginning
loveSong.volume = 0.7; // Set volume to 70%
// Play the song
const playPromise = loveSong.play();
if (playPromise !== undefined) {
playPromise
.then(() => {
console.log('Love song playing!');
})
.catch(error => {
console.log('Auto-play prevented:', error);
// Fallback to simple tones if song can't play
playFallbackTones();
});
}
} else {
// Fallback if audio element not found
playFallbackTones();
}
} catch (e) {
console.log('Audio error:', e);
playFallbackTones();
}
}
// Fallback function for simple tones (if song fails to play)
function playFallbackTones() {
try {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
// Create a series of happy notes
const notes = [523.25, 659.25, 783.99, 1046.50]; // C5, E5, G5, C6
notes.forEach((frequency, index) => {
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.frequency.value = frequency;
oscillator.type = 'sine';
const startTime = audioContext.currentTime + (index * 0.1);
const duration = 0.3;
gainNode.gain.setValueAtTime(0.3, startTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, startTime + duration);
oscillator.start(startTime);
oscillator.stop(startTime + duration);
});
} catch (e) {
console.log('Fallback audio not supported');
}
}
// Create button explosion effect
function createButtonExplosion(button) {
const rect = button.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
for (let i = 0; i < 20; i++) {
const particle = document.createElement('div');
particle.className = 'explosion-particle';
particle.style.left = centerX + 'px';
particle.style.top = centerY + 'px';
const angle = (Math.PI * 2 * i) / 20;
const velocity = 100 + Math.random() * 100;
const tx = Math.cos(angle) * velocity;
const ty = Math.sin(angle) * velocity;
particle.style.setProperty('--tx', tx + 'px');
particle.style.setProperty('--ty', ty + 'px');
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 1000);
}
}
// Create fireworks effect
function createFireworks() {
const colors = ['#ff0000', '#ff4d6d', '#ff758f', '#ffd700', '#ff69b4', '#ff1493'];
for (let i = 0; i < 5; i++) {
setTimeout(() => {
const x = Math.random() * window.innerWidth;
const y = Math.random() * (window.innerHeight / 2);
for (let j = 0; j < 30; j++) {
const particle = document.createElement('div');
particle.className = 'firework-particle';
particle.style.left = x + 'px';
particle.style.top = y + 'px';
particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
const angle = (Math.PI * 2 * j) / 30;
const velocity = 50 + Math.random() * 100;
const tx = Math.cos(angle) * velocity;
const ty = Math.sin(angle) * velocity;
particle.style.setProperty('--tx', tx + 'px');
particle.style.setProperty('--ty', ty + 'px');
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 1500);
}
}, i * 300);
}
}
// Create heart explosion effect
function createHeartExplosion() {
const hearts = ['πŸ’•', 'πŸ’–', 'πŸ’—', 'πŸ’“', 'πŸ’', '❀️'];
for (let i = 0; i < 15; i++) {
setTimeout(() => {
const heart = document.createElement('div');
heart.className = 'heart-burst';
heart.textContent = hearts[Math.floor(Math.random() * hearts.length)];
heart.style.left = '50%';
heart.style.top = '50%';
heart.style.fontSize = (20 + Math.random() * 30) + 'px';
const angle = (Math.PI * 2 * i) / 15;
const distance = 200 + Math.random() * 200;
const tx = Math.cos(angle) * distance;
const ty = Math.sin(angle) * distance;
heart.style.setProperty('--tx', tx + 'px');
heart.style.setProperty('--ty', ty + 'px');
document.body.appendChild(heart);
setTimeout(() => heart.remove(), 2000);
}, i * 50);
}
}
}); // End of DOMContentLoaded