import React, { useState, useEffect, useRef } from 'react'; import { Lock } from 'lucide-react'; // --- Компонент загрузочного экрана с кнопкой --- const TerminalScreen = ({ onDecrypt }) => { const [text, setText] = useState(''); const fullText = '> One encrypted package found for you.'; useEffect(() => { let i = 0; const interval = setInterval(() => { setText(fullText.slice(0, i)); i++; if (i > fullText.length) clearInterval(interval); }, 40); return () => clearInterval(interval); }, []); return (

[system] Initializing heart.protocol_v2.0...

Love you.

{text} _

(or just click anywhere)

); }; // --- Компонент сердца из текста --- const HeartCanvas = () => { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); let animationFrameId; let particles = []; let time = 0; const resize = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }; window.addEventListener('resize', resize); resize(); // Класс частицы (буквы) class Particle { constructor(x, y) { this.x = x; this.y = y; this.originX = x; this.originY = y; // Размер шрифта this.size = Math.random() * 6 + 8; this.text = 'i love you'; // Красивые красные оттенки const r = 255; const g = Math.floor(Math.random() * 80); // 0-80 const b = Math.floor(Math.random() * 80); // 0-80 this.color = `rgba(${r}, ${g}, ${b}, ${Math.random() * 0.5 + 0.5})`; // Смещение для эффекта плавания this.offsetX = (Math.random() - 0.5) * 15; this.offsetY = (Math.random() - 0.5) * 15; this.angle = Math.random() * Math.PI * 2; this.speed = Math.random() * 0.02 + 0.01; } update(time) { // Эффект сердцебиения (пульсация) const pulse = 1 + Math.sin(time * 2.5) * 0.04; // Вычисляем позицию относительно центра const dx = this.originX - canvas.width / 2; const dy = this.originY - canvas.height / 2; // Применяем пульсацию и плавное покачивание this.x = canvas.width / 2 + dx * pulse + Math.sin(time + this.angle) * 2; this.y = canvas.height / 2 + dy * pulse + Math.cos(time + this.angle) * 2; this.angle += this.speed; } draw(ctx) { ctx.font = `bold ${this.size}px "Courier New", monospace`; ctx.fillStyle = this.color; // Свечение текста ctx.shadowBlur = 8; ctx.shadowColor = 'rgba(255, 0, 50, 0.8)'; ctx.fillText(this.text, this.x, this.y); } } // Генерация точек внутри сердца const createHeart = () => { particles = []; const scale = 14; // Масштаб сердца const offsetX = canvas.width / 2; const offsetY = canvas.height / 2 + 40; // Смещение вниз // Используем неявное уравнение сердца: (x^2 + y^2 - 1)^3 - x^2 * y^3 <= 0 // Генерируем много случайных точек и оставляем только те, что внутри let attempts = 0; while (particles.length < 1200 && attempts < 20000) { attempts++; // Случайная точка в квадрате [-2, 2] const x = (Math.random() - 0.5) * 4; const y = (Math.random() - 0.5) * 4; // Проверка, находится ли точка внутри сердца const eq = Math.pow(x*x + y*y - 1, 3) - x*x * Math.pow(y, 3); if (eq <= 0) { // Умножаем на масштаб и центрируем // Инвертируем Y, так как в Canvas ось Y идет вниз const px = offsetX + x * scale; const py = offsetY - y * scale; particles.push(new Particle(px, py)); } } }; createHeart(); const animate = () => { time += 0.02; ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(p => { p.update(time); p.draw(ctx); }); animationFrameId = requestAnimationFrame(animate); }; animate(); return () => { cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resize); }; }, []); return (
{/* Текст поверх сердца */}

Love you.

); }; // --- Главный компонент --- export default function App() { const [stage, setStage] = useState('terminal'); return (
{stage === 'terminal' ? (
setStage('heart')} />
) : (
)} {/* Встроенные стили для анимации перехода */}
); }