/
Devilcry_Y
/
testvakant
Обзор
Документация
Войти
/
Devilcry_Y
/
testvakant
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
webgl.html
297 строк
12 KB
Devilcry_Y
Начало работы
05 июн 2026, 14:48
Верифицирован
05 июн 2026, 14:48
266fdd1
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Фотогалерея | Никита Шепелин</title> <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@300;400;500;600;700;800&display=swap" rel="stylesheet"> <link rel="stylesheet" href="common.css"> <style> .service-hero { padding: 60px 0 40px; text-align: center; } .service-hero h1 { font-size: 64px; font-weight: 800; letter-spacing: -0.02em; } .service-hero p { font-size: 20px; color: #4a4a4a; max-width: 700px; margin: 20px auto 0; } .projects-grid { display: flex; flex-direction: column; gap: 80px; margin: 60px 0 100px; } .project { display: flex; gap: 60px; flex-wrap: wrap; align-items: center; border-bottom: 1px solid #efefef; padding-bottom: 60px; } .project:last-child { border-bottom: none; } .project:nth-child(even) { flex-direction: row-reverse; } .project-text { flex: 1; } .project-text h2 { font-size: 36px; font-weight: 700; margin-bottom: 20px; } .project-text p { font-size: 18px; color: #4a4a4a; margin-bottom: 24px; } .project-image { flex: 1; position: relative; cursor: pointer; } .project-image img { width: 100%; border-radius: 28px; transition: transform 0.2s; } .project-image:hover img { transform: scale(1.02); } /* Стили карусели (всплывающий блок) */ .carousel-popup { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.9); backdrop-filter: blur(10px); border-radius: 32px; padding: 20px; z-index: 1000; display: flex; align-items: center; gap: 20px; box-shadow: 0 25px 50px rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.2); } .carousel-popup .carousel-img { max-width: 70vw; max-height: 70vh; border-radius: 24px; } .carousel-popup button { background: rgba(255,255,255,0.2); border: none; font-size: 32px; cursor: pointer; color: white; width: 50px; height: 50px; border-radius: 40px; transition: background 0.2s; } .carousel-popup button:hover { background: #ff6b35; } .close-carousel { position: absolute; top: 10px; right: 20px; background: none; font-size: 28px; border: none; color: white; cursor: pointer; } @media (max-width: 900px) { .project, .project:nth-child(even) { flex-direction: column; } .service-hero h1 { font-size: 44px; } } </style> </head> <body> <header> <div class="container"> <a href="index.html" class="back-link">← На главную</a> </div> </header> <main> <div class="service-hero"> <h1>Фотогалерея</h1> <p>Мои путешествия и вдохновение. Наведи на любое фото — откроется карусель.</p> </div> <div class="container"> <div class="projects-grid"> <!-- Блок 1 --> <div class="project" data-gallery='[ "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1447752875215-b2761acb3c5d?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1433086966358-54859d0ed716?w=800&h=600&fit=crop" ]'> <div class="project-text"> <h2>Командировки</h2> <p>Чуть позже придумаю описание и добавлю фото</p> </div> <div class="project-image"> <img src="https://images.unsplash.com/photo-1558591710-4b4a1ae0f04d?w=600&h=450&fit=crop" alt="желе-сфера"> </div> </div> <!-- Блок 2 --> <div class="project" data-gallery='[ "https://images.unsplash.com/photo-1601585272913-f0ff8c2c4a8a?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1581291518633-83b4ebd1d83e?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1558655146-9fda38edc179?w=800&h=600&fit=crop" ]'> <div class="project-text"> <h2>Киргизия</h2> <p>Чуть позже придумаю описание и добавлю фото.</p> </div> <div class="project-image"> <img src="https://images.unsplash.com/photo-1581091226033-d5c48150dbaa?w=600&h=450&fit=crop" alt="конфигуратор"> </div> </div> <!-- Блок 3 --> <div class="project" data-gallery='[ "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1470071459604-3b5ec3c7fe05?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1426604966848-d7adac402bff?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=800&h=600&fit=crop" ]'> <div class="project-text"> <h2>Путешествие в горы</h2> <p>Альпы, снег и свобода. Каждый кадр напоминает о том, как важно иногда отключаться от работы.</p> </div> <div class="project-image"> <img src="https://images.unsplash.com/photo-1519681393784-d120267933ba?w=600&h=450&fit=crop" alt="горы"> </div> </div> <!-- Блок 4 --> <div class="project" data-gallery='[ "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1505118380757-91f5f5632de0?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1433838552652-f9a46b332c40?w=800&h=600&fit=crop", "https://images.unsplash.com/photo-1533105079780-92b9be482077?w=800&h=600&fit=crop" ]'> <div class="project-text"> <h2>Морское приключение</h2> <p>Побережье, закаты и бесконечный океан. Источник вдохновения для новых проектов.</p> </div> <div class="project-image"> <img src="https://images.unsplash.com/photo-1505118380757-91f5f5632de0?w=600&h=450&fit=crop" alt="море"> </div> </div> </div> </div> </main> <footer> <div class="container"> <p>© 2025 Никита Шепелин — фотогалерея</p> </div> </footer> <script> // Карусель при наведении на главное изображение const projects = document.querySelectorAll('.project'); let currentCarousel = null; projects.forEach(project => { const imgContainer = project.querySelector('.project-image'); const mainImg = imgContainer.querySelector('img'); const gallery = JSON.parse(project.getAttribute('data-gallery')); let currentIndex = 0; function showCarousel(event) { if (currentCarousel) return; const rect = mainImg.getBoundingClientRect(); const popup = document.createElement('div'); popup.className = 'carousel-popup'; popup.innerHTML = ` <button class="prev">‹</button> <img class="carousel-img" src="${gallery[currentIndex]}" alt="carousel"> <button class="next">›</button> <button class="close-carousel">✕</button> `; document.body.appendChild(popup); currentCarousel = popup; const prevBtn = popup.querySelector('.prev'); const nextBtn = popup.querySelector('.next'); const closeBtn = popup.querySelector('.close-carousel'); const imgEl = popup.querySelector('.carousel-img'); function updateImage() { imgEl.src = gallery[currentIndex]; } function nextImage() { currentIndex = (currentIndex + 1) % gallery.length; updateImage(); } function prevImage() { currentIndex = (currentIndex - 1 + gallery.length) % gallery.length; updateImage(); } nextBtn.addEventListener('click', nextImage); prevBtn.addEventListener('click', prevImage); closeBtn.addEventListener('click', () => { popup.remove(); currentCarousel = null; }); // Закрытие по клику вне попапа (на фон) popup.addEventListener('click', (e) => { if (e.target === popup) { popup.remove(); currentCarousel = null; } }); } function hideCarousel() { if (currentCarousel) { currentCarousel.remove(); currentCarousel = null; } } // При наведении на контейнер с картинкой – показываем карусель imgContainer.addEventListener('mouseenter', showCarousel); // При уходе мыши с контейнера – убираем карусель (но если мышь внутри попапа, не убираем) imgContainer.addEventListener('mouseleave', () => { // Даём небольшую задержку, чтобы можно было зайти на попап setTimeout(() => { if (currentCarousel && !currentCarousel.matches(':hover') && !imgContainer.matches(':hover')) { currentCarousel.remove(); currentCarousel = null; } }, 200); }); // Если мышь заходит на попап – не закрываем document.body.addEventListener('mouseover', (e) => { if (currentCarousel && currentCarousel.contains(e.target)) { return; } }); }); </script> </body> </html>