personal
This commit is contained in:
parent
ab42d8b1bd
commit
160f2e2ddb
1 changed files with 0 additions and 370 deletions
|
|
@ -1,370 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import Image from "next/image";
|
|
||||||
import "./darecek.css";
|
|
||||||
|
|
||||||
export default function KikiPage() {
|
|
||||||
const [hasAnswered, setHasAnswered] = useState(false);
|
|
||||||
const [showMessage, setShowMessage] = useState(false);
|
|
||||||
const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
|
|
||||||
const [hearts, setHearts] = useState<{ id: number; left: number; delay: number; duration: number; size: number }[]>([]);
|
|
||||||
const [noButtonStyle, setNoButtonStyle] = useState<React.CSSProperties>({});
|
|
||||||
const [noButtonText, setNoButtonText] = useState("ne 😢");
|
|
||||||
const [noHoverCount, setNoHoverCount] = useState(0);
|
|
||||||
const [isRunning, setIsRunning] = useState(false);
|
|
||||||
|
|
||||||
const noButtonTexts = [
|
|
||||||
"ne 😢",
|
|
||||||
"fakt? 🥺",
|
|
||||||
"pjosim? 🥺",
|
|
||||||
"hej 😡",
|
|
||||||
"stop 👿",
|
|
||||||
"nech toooo 😭",
|
|
||||||
"😭😭😭",
|
|
||||||
"budu urazeny 🥺",
|
|
||||||
"grrrrr 👿👿👿",
|
|
||||||
"stejnak nemas na vyber 😝😝😝",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Add your photos here - just put images in /public/darecek/ folder
|
|
||||||
// named photo1.jpg, photo2.jpg, etc.
|
|
||||||
const photos = [
|
|
||||||
"/darecek/photo1.jpg",
|
|
||||||
"/darecek/photo2.jpg",
|
|
||||||
"/darecek/photo3.jpg",
|
|
||||||
"/darecek/photo4.jpg",
|
|
||||||
"/darecek/photo5.jpg",
|
|
||||||
];
|
|
||||||
|
|
||||||
const moveNoButton = (e: React.MouseEvent | React.TouchEvent) => {
|
|
||||||
// Get current mouse/touch position
|
|
||||||
let currentX = 0;
|
|
||||||
let currentY = 0;
|
|
||||||
|
|
||||||
if ('touches' in e) {
|
|
||||||
currentX = e.touches[0].clientX;
|
|
||||||
currentY = e.touches[0].clientY;
|
|
||||||
} else {
|
|
||||||
currentX = e.clientX;
|
|
||||||
currentY = e.clientY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const viewportWidth = window.innerWidth;
|
|
||||||
const viewportHeight = window.innerHeight;
|
|
||||||
const buttonWidth = 200;
|
|
||||||
const buttonHeight = 60;
|
|
||||||
const padding = 20;
|
|
||||||
const minDistanceFromMouse = 200; // Minimum distance from mouse
|
|
||||||
|
|
||||||
// Calculate safe bounds
|
|
||||||
const minX = padding;
|
|
||||||
const maxX = viewportWidth - buttonWidth - padding;
|
|
||||||
const minY = padding;
|
|
||||||
const maxY = viewportHeight - buttonHeight - padding;
|
|
||||||
|
|
||||||
let newX: number;
|
|
||||||
let newY: number;
|
|
||||||
let attempts = 0;
|
|
||||||
const maxAttempts = 50;
|
|
||||||
|
|
||||||
// Keep trying until we find a position far enough from mouse
|
|
||||||
do {
|
|
||||||
newX = minX + Math.random() * (maxX - minX);
|
|
||||||
newY = minY + Math.random() * (maxY - minY);
|
|
||||||
attempts++;
|
|
||||||
|
|
||||||
// Calculate distance from mouse
|
|
||||||
const distance = Math.sqrt(
|
|
||||||
Math.pow(newX + buttonWidth / 2 - currentX, 2) +
|
|
||||||
Math.pow(newY + buttonHeight / 2 - currentY, 2)
|
|
||||||
);
|
|
||||||
|
|
||||||
// If far enough from mouse, use this position
|
|
||||||
if (distance > minDistanceFromMouse) break;
|
|
||||||
|
|
||||||
} while (attempts < maxAttempts);
|
|
||||||
|
|
||||||
// If still too close after max attempts, move to opposite side of screen
|
|
||||||
const buttonCenterX = newX + buttonWidth / 2;
|
|
||||||
const buttonCenterY = newY + buttonHeight / 2;
|
|
||||||
const distanceFromMouse = Math.sqrt(
|
|
||||||
Math.pow(buttonCenterX - currentX, 2) +
|
|
||||||
Math.pow(buttonCenterY - currentY, 2)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (distanceFromMouse < minDistanceFromMouse) {
|
|
||||||
// Move to opposite quadrant of the screen
|
|
||||||
if (currentX < viewportWidth / 2) {
|
|
||||||
newX = maxX - Math.random() * (maxX / 3);
|
|
||||||
} else {
|
|
||||||
newX = minX + Math.random() * (maxX / 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentY < viewportHeight / 2) {
|
|
||||||
newY = maxY - Math.random() * (maxY / 3);
|
|
||||||
} else {
|
|
||||||
newY = minY + Math.random() * (maxY / 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure bounds
|
|
||||||
newX = Math.max(minX, Math.min(maxX, newX));
|
|
||||||
newY = Math.max(minY, Math.min(maxY, newY));
|
|
||||||
|
|
||||||
setNoButtonStyle({
|
|
||||||
position: 'fixed',
|
|
||||||
left: `${newX}px`,
|
|
||||||
top: `${newY}px`,
|
|
||||||
});
|
|
||||||
|
|
||||||
setIsRunning(true);
|
|
||||||
setNoHoverCount(prev => prev + 1);
|
|
||||||
setNoButtonText(noButtonTexts[Math.min(noHoverCount + 1, noButtonTexts.length - 1)]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleYesClick = () => {
|
|
||||||
setHasAnswered(true);
|
|
||||||
// Show message after transition
|
|
||||||
setTimeout(() => setShowMessage(true), 500);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Generate floating hearts
|
|
||||||
const newHearts = Array.from({ length: 30 }, (_, i) => ({
|
|
||||||
id: i,
|
|
||||||
left: Math.random() * 100,
|
|
||||||
delay: Math.random() * 5,
|
|
||||||
duration: 5 + Math.random() * 10,
|
|
||||||
size: 15 + Math.random() * 25,
|
|
||||||
}));
|
|
||||||
setHearts(newHearts);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!hasAnswered) return;
|
|
||||||
|
|
||||||
// Auto-rotate photos
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
setCurrentPhotoIndex((prev) => (prev + 1) % photos.length);
|
|
||||||
}, 4000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, [hasAnswered, photos.length]);
|
|
||||||
|
|
||||||
// Question screen
|
|
||||||
if (!hasAnswered) {
|
|
||||||
return (
|
|
||||||
<div className="kiki-container">
|
|
||||||
{/* Floating Hearts Background */}
|
|
||||||
<div className="hearts-container">
|
|
||||||
{hearts.map((heart) => (
|
|
||||||
<div
|
|
||||||
key={heart.id}
|
|
||||||
className="floating-heart"
|
|
||||||
style={{
|
|
||||||
left: `${heart.left}%`,
|
|
||||||
animationDelay: `${heart.delay}s`,
|
|
||||||
animationDuration: `${heart.duration}s`,
|
|
||||||
fontSize: `${heart.size}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
💖
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Sparkles */}
|
|
||||||
<div className="sparkles">
|
|
||||||
{Array.from({ length: 50 }).map((_, i) => (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="sparkle"
|
|
||||||
style={{
|
|
||||||
left: `${Math.random() * 100}%`,
|
|
||||||
top: `${Math.random() * 100}%`,
|
|
||||||
animationDelay: `${Math.random() * 3}s`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Question Content */}
|
|
||||||
<div className="question-screen">
|
|
||||||
<div className="question-heart">😝</div>
|
|
||||||
<h1 className="question-title">kikiiiii</h1>
|
|
||||||
<h2 className="question-text">budes muj valentyn? ❤️</h2>
|
|
||||||
|
|
||||||
<div className="question-buttons">
|
|
||||||
<button className="yes-button" onClick={handleYesClick}>
|
|
||||||
jo 😘
|
|
||||||
</button>
|
|
||||||
{!isRunning && (
|
|
||||||
<button
|
|
||||||
className="no-button"
|
|
||||||
onMouseEnter={moveNoButton}
|
|
||||||
onTouchStart={moveNoButton}
|
|
||||||
onClick={moveNoButton}
|
|
||||||
>
|
|
||||||
{noButtonText}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{noHoverCount > 3 && (
|
|
||||||
<p className="hint-text">
|
|
||||||
{noHoverCount > 6 ? "dej ano tele 😛" : "to tlacitko ti zdrha 😝😝😝"}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Runaway No Button - rendered outside the question-buttons container */}
|
|
||||||
{isRunning && (
|
|
||||||
<button
|
|
||||||
className="no-button runaway"
|
|
||||||
style={noButtonStyle}
|
|
||||||
onMouseEnter={moveNoButton}
|
|
||||||
onTouchStart={moveNoButton}
|
|
||||||
onClick={moveNoButton}
|
|
||||||
>
|
|
||||||
{noButtonText}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="kiki-container">
|
|
||||||
{/* Floating Hearts Background */}
|
|
||||||
<div className="hearts-container">
|
|
||||||
{hearts.map((heart) => (
|
|
||||||
<div
|
|
||||||
key={heart.id}
|
|
||||||
className="floating-heart"
|
|
||||||
style={{
|
|
||||||
left: `${heart.left}%`,
|
|
||||||
animationDelay: `${heart.delay}s`,
|
|
||||||
animationDuration: `${heart.duration}s`,
|
|
||||||
fontSize: `${heart.size}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
💘
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Sparkles */}
|
|
||||||
<div className="sparkles">
|
|
||||||
{Array.from({ length: 50 }).map((_, i) => (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="sparkle"
|
|
||||||
style={{
|
|
||||||
left: `${Math.random() * 100}%`,
|
|
||||||
top: `${Math.random() * 100}%`,
|
|
||||||
animationDelay: `${Math.random() * 3}s`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Main Content */}
|
|
||||||
<main className="kiki-main">
|
|
||||||
{/* Title */}
|
|
||||||
<h1 className={`kiki-title ${showMessage ? "show" : ""}`}>
|
|
||||||
stastnej valentynnnn
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<h2 className={`kiki-subtitle ${showMessage ? "show" : ""}`}>
|
|
||||||
laskoooo 😘😘😝
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{/* Photo Gallery */}
|
|
||||||
<div className={`photo-frame ${showMessage ? "show" : ""}`}>
|
|
||||||
<div className="photo-inner">
|
|
||||||
<div
|
|
||||||
className="photo-slider"
|
|
||||||
style={{ transform: `translateX(-${currentPhotoIndex * 100}%)` }}
|
|
||||||
>
|
|
||||||
{photos.map((photo, index) => (
|
|
||||||
<div key={index} className="photo-slide">
|
|
||||||
<Image
|
|
||||||
src={photo}
|
|
||||||
alt={`Memory ${index + 1}`}
|
|
||||||
className="photo"
|
|
||||||
width={500}
|
|
||||||
height={500}
|
|
||||||
onError={(e) => {
|
|
||||||
// Fallback if image doesn't exist
|
|
||||||
(e.target as HTMLImageElement).src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300' viewBox='0 0 300 300'%3E%3Crect fill='%23ff6b9d' width='300' height='300'/%3E%3Ctext x='150' y='150' text-anchor='middle' dy='.3em' fill='white' font-size='60'%3E💕%3C/text%3E%3C/svg%3E";
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="photo-dots">
|
|
||||||
{photos.map((_, index) => (
|
|
||||||
<button
|
|
||||||
key={index}
|
|
||||||
className={`photo-dot ${index === currentPhotoIndex ? "active" : ""}`}
|
|
||||||
onClick={() => setCurrentPhotoIndex(index)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Love Letter */}
|
|
||||||
<div className={`love-letter ${showMessage ? "show" : ""}`}>
|
|
||||||
<div className="letter-content">
|
|
||||||
<p className="letter-greeting">pro moji princeznu,</p>
|
|
||||||
<p className="letter-text">
|
|
||||||
tohle je nas druhej valentyn a jsem moc moc stastnej, ze ho muzu stravit s tebou 😘
|
|
||||||
</p>
|
|
||||||
<p className="letter-text">
|
|
||||||
si ta nejlepsi, nejkrasnejsi a nejroztomilejsi holka na svete, kterou bych si kdy mohl prat, a jsem vdecnej, ze si to semnou vydrzela, i pres ty moje nalady 🥺😝❤️
|
|
||||||
</p>
|
|
||||||
<p className="letter-text">
|
|
||||||
tak strasne moc te milujuuuu a chci byt s tebou pro zbytek svyho zivota, lasko moje ❤️🥹
|
|
||||||
</p>
|
|
||||||
<p className="letter-signature">
|
|
||||||
tvoje laska,<br />
|
|
||||||
<span className="signature-name">Martin ❤️</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Animated Heart */}
|
|
||||||
<div className={`big-heart ${showMessage ? "show" : ""}`}>
|
|
||||||
<div className="heart-pulse">❤️</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Cute Messages */}
|
|
||||||
<div className={`cute-messages ${showMessage ? "show" : ""}`}>
|
|
||||||
<span className="cute-msg">jsi moje 👸🏽</span>
|
|
||||||
<span className="cute-msg">miluju te nejvic ve vesmiru 😝</span>
|
|
||||||
<span className="cute-msg">chci jenom tebee 😍</span>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
{/* Rose petals falling */}
|
|
||||||
<div className="petals-container">
|
|
||||||
{Array.from({ length: 20 }).map((_, i) => (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className="petal"
|
|
||||||
style={{
|
|
||||||
left: `${Math.random() * 100}%`,
|
|
||||||
animationDelay: `${Math.random() * 8}s`,
|
|
||||||
animationDuration: `${8 + Math.random() * 7}s`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
💝
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue