Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Слив сайта 3D Биография

Апр
189
533
Продавец
Скриншот 29-01-2026 143711.jpg
Код сайта:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Биография</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: #0a0a1a;
            color: #f0f0f0;
            overflow-x: hidden;
            min-height: 100vh;
        }

        #bg-canvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            position: relative;
            z-index: 10;
        }

        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px 0;
            margin-bottom: 40px;
            border-bottom: 1px solid rgba(100, 150, 255, 0.3);
        }

        .logo {
            font-size: 28px;
            font-weight: 800;
            background: linear-gradient(45deg, #6a5af9, #d66efd);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-transform: uppercase;
            letter-spacing: 2px;
        }

        .config-info {
            font-size: 14px;
            color: #aaa;
            background: rgba(20, 20, 40, 0.8);
            padding: 8px 15px;
            border-radius: 20px;
            border: 1px solid rgba(100, 150, 255, 0.2);
        }

        .config-info i {
            margin-right: 8px;
            color: #6a5af9;
        }

        .main-content {
            display: flex;
            flex-wrap: wrap;
            gap: 30px;
            margin-bottom: 60px;
        }

        .profile-section {
            flex: 1;
            min-width: 300px;
            perspective: 1000px;
        }

        .profile-card {
            background: rgba(20, 25, 45, 0.85);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(100, 150, 255, 0.1);
            transform-style: preserve-3d;
            transition: transform 0.5s ease;
            position: relative;
            overflow: hidden;
        }

        .profile-card:hover {
            transform: rotateY(5deg) rotateX(5deg);
        }

        .avatar-container {
            width: 180px;
            height: 180px;
            margin: 0 auto 25px;
            position: relative;
            transform-style: preserve-3d;
            transition: transform 0.8s;
        }

        .avatar-container:hover {
            transform: rotateY(180deg);
        }

        .avatar {
            width: 100%;
            height: 100%;
            border-radius: 50%;
            object-fit: cover;
            border: 4px solid transparent;
            background: linear-gradient(45deg, #6a5af9, #d66efd) border-box;
            position: absolute;
            backface-visibility: hidden;
        }

        .avatar-back {
            transform: rotateY(180deg);
            background: rgba(30, 35, 60, 0.95);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 15px;
            text-align: center;
            border-radius: 50%;
        }

        .username {
            text-align: center;
            font-size: 32px;
            margin-bottom: 15px;
            background: linear-gradient(45deg, #6a5af9, #d66efd);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            font-weight: 700;
        }

        .user-title {
            text-align: center;
            font-size: 18px;
            color: #aaa;
            margin-bottom: 25px;
            font-weight: 300;
        }

        .user-bio {
            line-height: 1.6;
            font-size: 16px;
            color: #ddd;
            margin-bottom: 30px;
            padding: 0 10px;
        }

        .social-links {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 25px;
        }

        .social-icon {
            width: 45px;
            height: 45px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(100, 150, 255, 0.1);
            color: #6a5af9;
            font-size: 20px;
            transition: all 0.3s ease;
            text-decoration: none;
        }

        .social-icon:hover {
            background: linear-gradient(45deg, #6a5af9, #d66efd);
            color: white;
            transform: translateY(-5px);
        }

        .stats-section {
            flex: 1;
            min-width: 300px;
        }

        .stats-card {
            background: rgba(20, 25, 45, 0.85);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(100, 150, 255, 0.1);
            height: 100%;
        }

        .section-title {
            font-size: 24px;
            margin-bottom: 25px;
            color: #6a5af9;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .section-title i {
            font-size: 22px;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 20px;
        }

        .stat-item {
            background: rgba(30, 35, 60, 0.7);
            padding: 20px;
            border-radius: 15px;
            text-align: center;
            transition: transform 0.3s ease;
        }

        .stat-item:hover {
            transform: translateY(-5px);
            background: rgba(40, 45, 75, 0.8);
        }

        .stat-value {
            font-size: 32px;
            font-weight: 700;
            background: linear-gradient(45deg, #6a5af9, #d66efd);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            margin-bottom: 5px;
        }

        .stat-label {
            font-size: 14px;
            color: #aaa;
            text-transform: uppercase;
            letter-spacing: 1px;
        }

        .player-section {
            width: 100%;
            margin-top: 20px;
        }

        .player-card {
            background: rgba(20, 25, 45, 0.85);
            border-radius: 20px;
            padding: 25px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(100, 150, 255, 0.1);
        }

        .player-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        .player-controls {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .control-btn {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background: rgba(100, 150, 255, 0.1);
            border: none;
            color: #6a5af9;
            font-size: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .control-btn:hover {
            background: linear-gradient(45deg, #6a5af9, #d66efd);
            color: white;
            transform: scale(1.05);
        }

        .play-btn {
            width: 60px;
            height: 60px;
            font-size: 24px;
        }

        .progress-container {
            flex-grow: 1;
            margin: 0 20px;
        }

        .progress-bar {
            width: 100%;
            height: 6px;
            background: rgba(100, 150, 255, 0.1);
            border-radius: 3px;
            margin-top: 5px;
            overflow: hidden;
        }

        .progress {
            height: 100%;
            background: linear-gradient(90deg, #6a5af9, #d66efd);
            width: 30%;
            border-radius: 3px;
            transition: width 0.1s linear;
        }

        .time-info {
            display: flex;
            justify-content: space-between;
            font-size: 14px;
            color: #aaa;
            margin-top: 5px;
        }

        .track-info {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .track-cover {
            width: 60px;
            height: 60px;
            border-radius: 10px;
            object-fit: cover;
        }

        .track-details h4 {
            font-size: 18px;
            margin-bottom: 5px;
        }

        .track-details p {
            font-size: 14px;
            color: #aaa;
        }

        .volume-container {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .volume-slider {
            width: 100px;
            height: 5px;
            background: rgba(100, 150, 255, 0.1);
            border-radius: 3px;
            outline: none;
            -webkit-appearance: none;
        }

        .volume-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background: #6a5af9;
            cursor: pointer;
        }

        footer {
            text-align: center;
            padding: 20px;
            color: #777;
            font-size: 14px;
            border-top: 1px solid rgba(100, 150, 255, 0.1);
            margin-top: 40px;
        }

        .floating-element {
            position: absolute;
            width: 20px;
            height: 20px;
            background: rgba(106, 90, 249, 0.5);
            border-radius: 50%;
            pointer-events: none;
            z-index: 1;
        }

        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }
            
            .player-header {
                flex-direction: column;
                gap: 20px;
                align-items: flex-start;
            }
            
            .player-controls {
                width: 100%;
                justify-content: center;
            }
            
            .stats-grid {
                grid-template-columns: 1fr;
            }
            
            header {
                flex-direction: column;
                gap: 15px;
                text-align: center;
            }
        }
    </style>
</head>
<body>
    <!-- 3D фон -->
    <canvas id="bg-canvas"></canvas>
    
    <!-- Плавающие элементы -->
    <div class="floating-element" style="top: 10%; left: 5%; width: 40px; height: 40px;"></div>
    <div class="floating-element" style="top: 70%; right: 10%; width: 30px; height: 30px;"></div>
    <div class="floating-element" style="top: 20%; right: 15%; width: 25px; height: 25px;"></div>
    <div class="floating-element" style="top: 85%; left: 20%; width: 35px; height: 35px;"></div>
    
    <div class="container">
        <header>
            <div class="logo">3D Биография</div>
            <div class="config-info">
                <i class="fas fa-cog"></i>
                Настройки загружаются из index.html
            </div>
        </header>
        
        <main class="main-content">
            <section class="profile-section">
                <div class="profile-card">
                    <div class="avatar-container">
                        <img id="avatar-img" src="" alt="Аватар" class="avatar">
                        <div class="avatar avatar-back">
                            <i class="fas fa-user" style="font-size: 40px; margin-bottom: 10px; color: #6a5af9;"></i>
                            <span id="avatar-text">3D Аватар</span>
                        </div>
                    </div>
                    
                    <h1 id="username" class="username">Имя Пользователя</h1>
                    <div id="user-title" class="user-title">Должность / Статус</div>
                    
                    <div id="user-bio" class="user-bio">
                        Загрузка описания из конфигурационного файла...
                    </div>
                    
                    <div class="social-links">
                        <a href="#" class="social-icon" id="social-1"><i class="fab fa-github"></i></a>
                        <a href="#" class="social-icon" id="social-2"><i class="fab fa-telegram"></i></a>
                        <a href="#" class="social-icon" id="social-3"><i class="fab fa-vk"></i></a>
                        <a href="#" class="social-icon" id="social-4"><i class="fab fa-youtube"></i></a>
                    </div>
                </div>
            </section>
            
            <section class="stats-section">
                <div class="stats-card">
                    <h2 class="section-title"><i class="fas fa-chart-line"></i> Статистика</h2>
                    
                    <div class="stats-grid">
                        <div class="stat-item">
                            <div id="stat-1-value" class="stat-value">0</div>
                            <div class="stat-label">Проекты</div>
                        </div>
                        <div class="stat-item">
                            <div id="stat-2-value" class="stat-value">0</div>
                            <div class="stat-label">Подписчики</div>
                        </div>
                        <div class="stat-item">
                            <div id="stat-3-value" class="stat-value">0</div>
                            <div class="stat-label">Опыт (лет)</div>
                        </div>
                        <div class="stat-item">
                            <div id="stat-4-value" class="stat-value">0</div>
                            <div class="stat-label">Награды</div>
                        </div>
                    </div>
                    
                    <div class="player-section">
                        <div class="player-card">
                            <div class="player-header">
                                <div class="track-info">
                                    <img id="track-cover" src="" alt="Обложка трека" class="track-cover">
                                    <div class="track-details">
                                        <h4 id="track-title">Название трека</h4>
                                        <p id="track-artist">Исполнитель</p>
                                    </div>
                                </div>
                                
                                <div class="volume-container">
                                    <i class="fas fa-volume-up" style="color: #6a5af9;"></i>
                                    <input type="range" min="0" max="100" value="70" class="volume-slider" id="volume-slider">
                                </div>
                            </div>
                            
                            <div class="player-controls">
                                <button class="control-btn" id="prev-btn">
                                    <i class="fas fa-step-backward"></i>
                                </button>
                                
                                <button class="control-btn play-btn" id="play-btn">
                                    <i class="fas fa-play" id="play-icon"></i>
                                </button>
                                
                                <button class="control-btn" id="next-btn">
                                    <i class="fas fa-step-forward"></i>
                                </button>
                                
                                <div class="progress-container">
                                    <div class="progress-bar">
                                        <div class="progress" id="progress-bar"></div>
                                    </div>
                                    <div class="time-info">
                                        <span id="current-time">0:00</span>
                                        <span id="total-time">0:00</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </main>
        
        <footer>
            <p>3D Биография &copy; 2026 | Все данные настраиваются через файл index.html</p>
        </footer>
    </div>

    <script>
        // Конфигурация по умолчанию
        let config = {
            username: "Эх шарик ",
            avatar: "https://avatars.mds.yandex.net/i?id=3d090e83d03fdfd6ceee0bcc6371d0fc_l-4146308-images-thumbs&n=13",
            title: "Frontend разработчик & 3D дизайнер",
            bio: "Привет! Я занимаюсь созданием интерактивных веб-приложений с использованием современных технологий. Мои основные интересы включают 3D графику в браузере, интерактивный дизайн и создание immersive-опытов. В свободное время я изучаю новые библиотеки для визуализации и экспериментирую с WebGL.",
            stats: {
                projects: 42,
                followers: 12500,
                experience: 5,
                awards: 8
            },
            social: {
                github: "https://github.com",
                telegram: "https://telegram.org",
                vk: "https://vk.com",
                youtube: "https://youtube.com"
            },
            player: {
                tracks: [
                    {
                        title: "Электронные волны",
                        artist: "Cosmic Sound",
                        cover: "https://images.unsplash.com/photo-1493225457124-a3eb161ffa5f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80",
                        src: "https://assets.mixkit.co/music/preview/mixkit-tech-house-vibes-130.mp3"
                    },
                    {
                        title: "Рассвет в горах",
                        artist: "Nature Sounds",
                        cover: "https://images.unsplash.com/photo-1498038432885-c6f3f1b912ee?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80",
                        src: "https://assets.mixkit.co/music/preview/mixkit-driving-ambition-32.mp3"
                    },
                    {
                        title: "Город ночью",
                        artist: "Urban Vibes",
                        cover: "https://images.unsplash.com/photo-1511379938547-c1f69419868d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80",
                        src: "https://rus.hitmotop.com/get/music/20200729/Hugo_Loud_OFFMi_-_GTA_70404904.mp3"
                    }
                ]
            }
        };

        // Загрузка конфигурации из файла config.json
        async function loadConfig() {
            try {
                // В реальном проекте здесь будет fetch('config.json')
                // Для демонстрации используем задержку
                await new Promise(resolve => setTimeout(resolve, 500));
                
                // Имитируем загрузку из файла
                console.log("Конфигурация загружена из config.json");
                
                // В реальном проекте здесь будет:
                // const response = await fetch('config.json');
                // config = await response.json();
                
                // Применяем конфигурацию
                applyConfig();
            } catch (error) {
                console.error("Ошибка загрузки конфигурации:", error);
                // Используем конфигурацию по умолчанию
                applyConfig();
            }
        }

        // Применение конфигурации к странице
        function applyConfig() {
            // Применяем данные пользователя
            document.getElementById('username').textContent = config.username;
            document.getElementById('avatar-img').src = config.avatar;
            document.getElementById('avatar-text').textContent = config.username;
            document.getElementById('user-title').textContent = config.title;
            document.getElementById('user-bio').textContent = config.bio;
            
            // Применяем статистику
            document.getElementById('stat-1-value').textContent = config.stats.projects;
            document.getElementById('stat-2-value').textContent = config.stats.followers.toLocaleString();
            document.getElementById('stat-3-value').textContent = config.stats.experience;
            document.getElementById('stat-4-value').textContent = config.stats.awards;
            
            // Применяем социальные ссылки
            document.getElementById('social-1').href = config.social.github;
            document.getElementById('social-2').href = config.social.telegram;
            document.getElementById('social-3').href = config.social.vk;
            document.getElementById('social-4').href = config.social.youtube;
            
            // Инициализируем плеер
            initPlayer();
        }

        // Инициализация 3D сцены
        function init3DScene() {
            const canvas = document.getElementById('bg-canvas');
            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
            
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
            
            // Создаем частицы для фона
            const particlesGeometry = new THREE.BufferGeometry();
            const particlesCount = 1500;
            
            const posArray = new Float32Array(particlesCount * 3);
            const colorArray = new Float32Array(particlesCount * 3);
            
            for(let i = 0; i < particlesCount * 3; i++) {
                posArray[i] = (Math.random() - 0.5) * 50;
                colorArray[i] = Math.random();
            }
            
            particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3));
            particlesGeometry.setAttribute('color', new THREE.BufferAttribute(colorArray, 3));
            
            const particlesMaterial = new THREE.PointsMaterial({
                size: 0.05,
                vertexColors: true,
                transparent: true,
                opacity: 0.8
            });
            
            const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial);
            scene.add(particlesMesh);
            
            // Добавляем свет
            const ambientLight = new THREE.AmbientLight(0x222244);
            scene.add(ambientLight);
            
            const pointLight = new THREE.PointLight(0x6a5af9, 0.5);
            pointLight.position.set(5, 5, 5);
            scene.add(pointLight);
            
            camera.position.z = 5;
            
            // Анимация
            function animate() {
                requestAnimationFrame(animate);
                
                particlesMesh.rotation.x += 0.0005;
                particlesMesh.rotation.y += 0.001;
                
                // Плавное движение частиц
                const positions = particlesMesh.geometry.attributes.position.array;
                for(let i = 0; i < positions.length; i += 3) {
                    positions[i] += (Math.random() - 0.5) * 0.01;
                    positions[i+1] += (Math.random() - 0.5) * 0.01;
                    positions[i+2] += (Math.random() - 0.5) * 0.01;
                }
                particlesMesh.geometry.attributes.position.needsUpdate = true;
                
                renderer.render(scene, camera);
            }
            
            animate();
            
            // Обработка изменения размера окна
            window.addEventListener('resize', () => {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            });
        }

        // Инициализация аудиоплеера
        let currentTrackIndex = 0;
        let isPlaying = false;
        let audio = new Audio();
        
        function initPlayer() {
            const tracks = config.player.tracks;
            
            // Загружаем первый трек
            loadTrack(currentTrackIndex);
            
            // Назначаем обработчики событий
            document.getElementById('play-btn').addEventListener('click', togglePlay);
            document.getElementById('prev-btn').addEventListener('click', prevTrack);
            document.getElementById('next-btn').addEventListener('click', nextTrack);
            document.getElementById('volume-slider').addEventListener('input', updateVolume);
            
            // Обновление прогресса воспроизведения
            audio.addEventListener('timeupdate', updateProgress);
            audio.addEventListener('loadedmetadata', updateTotalTime);
            audio.addEventListener('ended', nextTrack);
            
            // Обновление времени при клике на прогресс-бар
            document.querySelector('.progress-bar').addEventListener('click', (e) => {
                const progressBar = e.currentTarget;
                const clickPosition = e.offsetX;
                const totalWidth = progressBar.clientWidth;
                const percentage = clickPosition / totalWidth;
                
                audio.currentTime = percentage * audio.duration;
                updateProgress();
            });
        }
        
        function loadTrack(index) {
            const tracks = config.player.tracks;
            if (index < 0) index = tracks.length - 1;
            if (index >= tracks.length) index = 0;
            
            currentTrackIndex = index;
            const track = tracks[index];
            
            audio.src = track.src;
            
            document.getElementById('track-title').textContent = track.title;
            document.getElementById('track-artist').textContent = track.artist;
            document.getElementById('track-cover').src = track.cover;
            
            if (isPlaying) {
                audio.play();
            }
            
            updateTotalTime();
        }
        
        function togglePlay() {
            if (isPlaying) {
                audio.pause();
                document.getElementById('play-icon').classList.remove('fa-pause');
                document.getElementById('play-icon').classList.add('fa-play');
            } else {
                audio.play();
                document.getElementById('play-icon').classList.remove('fa-play');
                document.getElementById('play-icon').classList.add('fa-pause');
            }
            
            isPlaying = !isPlaying;
        }
        
        function prevTrack() {
            loadTrack(currentTrackIndex - 1);
        }
        
        function nextTrack() {
            loadTrack(currentTrackIndex + 1);
        }
        
        function updateVolume() {
            const volume = document.getElementById('volume-slider').value / 100;
            audio.volume = volume;
        }
        
        function updateProgress() {
            const progress = (audio.currentTime / audio.duration) * 100;
            document.getElementById('progress-bar').style.width = `${progress}%`;
            
            // Обновляем текущее время
            const currentMinutes = Math.floor(audio.currentTime / 60);
            const currentSeconds = Math.floor(audio.currentTime % 60);
            document.getElementById('current-time').textContent =
                `${currentMinutes}:${currentSeconds < 10 ? '0' : ''}${currentSeconds}`;
        }
        
        function updateTotalTime() {
            const totalMinutes = Math.floor(audio.duration / 60);
            const totalSeconds = Math.floor(audio.duration % 60);
            document.getElementById('total-time').textContent =
                `${totalMinutes}:${totalSeconds < 10 ? '0' : ''}${totalSeconds}`;
        }

        // Анимация плавающих элементов
        function animateFloatingElements() {
            const elements = document.querySelectorAll('.floating-element');
            
            elements.forEach((el, index) => {
                // Начальные позиции и параметры
                let x = parseFloat(el.style.left || '0');
                let y = parseFloat(el.style.top || '0');
                let xSpeed = (Math.random() * 0.5 + 0.1) * (index % 2 === 0 ? 1 : -1);
                let ySpeed = (Math.random() * 0.5 + 0.1) * (index % 3 === 0 ? 1 : -1);
                
                // Функция обновления позиции
                function updatePosition() {
                    x += xSpeed;
                    y += ySpeed;
                    
                    // Отскок от границ
                    if (x <= 0 || x >= window.innerWidth - el.clientWidth) {
                        xSpeed *= -1;
                        x = x <= 0 ? 0 : window.innerWidth - el.clientWidth;
                    }
                    
                    if (y <= 0 || y >= window.innerHeight - el.clientHeight) {
                        ySpeed *= -1;
                        y = y <= 0 ? 0 : window.innerHeight - el.clientHeight;
                    }
                    
                    el.style.left = `${x}px`;
                    el.style.top = `${y}px`;
                    
                    // Плавное изменение размера
                    const scale = 1 + 0.2 * Math.sin(Date.now() * 0.001 + index);
                    el.style.transform = `scale(${scale})`;
                    
                    requestAnimationFrame(updatePosition);
                }
                
                updatePosition();
            });
        }

        // Инициализация при загрузке страницы
        document.addEventListener('DOMContentLoaded', () => {
            init3DScene();
            loadConfig();
            animateFloatingElements();
            
            // Добавляем интерактивность к карточке профиля
            const profileCard = document.querySelector('.profile-card');
            profileCard.addEventListener('mousemove', (e) => {
                const rect = profileCard.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                const centerX = rect.width / 2;
                const centerY = rect.height / 2;
                
                const rotateY = ((x - centerX) / centerX) * 5;
                const rotateX = ((centerY - y) / centerY) * 5;
                
                profileCard.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
            });
            
            profileCard.addEventListener('mouseleave', () => {
                profileCard.style.transform = 'perspective(1000px) rotateX(0) rotateY(0)';
            });
        });
    </script>
</body>
</html>
 
Сверху