- Апр
- 189
- 533
Продавец

Код сайта:
<!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 Биография © 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>