Категории
Эффект растущей картинки javascript при скролле страницы
15.10.2025 | коды из категории: Создание сайтов
Как использовать у себя?
- Скопируйте HTML-структуру ниже.
- Замените URL картинки на свою.
- Настройте
minHeight и maxHeight в JavaScript под свои нужды.
- Добавьте свой контент внутрь или под блок.
Базовая HTML-структура
<div class="hero" id="hero">
<!-- Можно добавить контент сюда -->
<h2 style="color: white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">
Привет!
</h2>
</div>
<div class="content">
<h1>Основной контент</h1>
<p>Этот текст начнёт скроллиться только после того, как картинка вырастет до 700px.</p>
</div>
JavaScript (основной логика)
const hero = document.getElementById('hero');
const minHeight = 200;
const maxHeight = 700;
const expandRange = maxHeight - minHeight;
let currentExpand = 0;
let isExpanded = false;
document.addEventListener('wheel', (e) => {
if (isExpanded) return;
e.preventDefault();
const delta = e.deltaY > 0 ? 1 : -1;
currentExpand = Math.max(0, Math.min(expandRange, currentExpand + delta * 30));
hero.style.height = (minHeight + currentExpand) + 'px';
if (currentExpand >= expandRange) {
isExpanded = true;
}
}, { passive: false });
Ограничения
- Работает на десктопе (мышь/трекпад). На мобильных устройствах потребуется дополнительная обработка
touchmove.
- Не работает, если пользователь использует клавиши (Page Down, стрелки) — можно доработать при необходимости.
- Некоторые браузеры могут игнорировать
preventDefault() без { passive: false }.
Советы
- Используйте
background-position: top, чтобы при росте открывалась нижняя часть изображения.
- Для плавности можно заменить шаг
30 на значение, пропорциональное e.deltaY.
- Добавьте
will-change: height в CSS для лучшей производительности.
Полный код страницы все в одном
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Сначала растёт картинка — потом скролл</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
overflow-x: hidden;
/* Запретим стандартный скролл, пока не нужно */
}
.hero {
width: 100%;
height: 200px; /* начальная высота */
background: url('https://picsum.photos/1200/1000') top / cover no-repeat;
transition: height 0s; /* мгновенно, без задержки */
}
.content {
padding: 30px 20px;
background: #f5f5f5;
/* Контент будет НЕ скроллиться, пока картинка растёт */
}
h1 { margin-bottom: 16px; }
p { line-height: 1.6; margin-bottom: 12px; }
</style>
</head>
<body>
<div class="hero" id="hero"></div>
<div class="content">
<h1>Привет! Это контент под картинкой</h1>
<p>Сейчас картинка — 200px. Прокрути вниз.</p>
<p><strong>Важно:</strong> сначала будет расти только картинка (до 700px), а этот текст останется на месте!</p>
<p>Только когда картинка достигнет 700px — начнётся настоящий скролл.</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
<p>Много текста для скролла после...</p>
<p>...</p><p>...</p><p>...</p><p>...</p><p>...</p>
</div>
<script>
const hero = document.getElementById('hero');
const minHeight = 200;
const maxHeight = 700;
const expandRange = maxHeight - minHeight; // 500
let currentExpand = 0; // сколько уже "растянули" (0..500)
let isExpanded = false;
// Перехватываем колёсико мыши
document.addEventListener('wheel', (e) => {
if (isExpanded) return; // если уже раскрыто — не мешаем скроллу
e.preventDefault(); // БЛОКИРУЕМ стандартный скролл
// Определяем направление
const delta = e.deltaY > 0 ? 1 : -1;
// Увеличиваем или уменьшаем "раскрытие"
currentExpand = Math.max(0, Math.min(expandRange, currentExpand + delta * 30));
// Обновляем высоту
const newHeight = minHeight + currentExpand;
hero.style.height = newHeight + 'px';
// Если достигли максимума — включаем обычный скролл
if (currentExpand >= expandRange) {
isExpanded = true;
// Разрешаем скролл: убираем обработчик или просто перестаём блокировать
// (в данном случае — флаг isExpanded)
}
// Для плавности можно добавить requestAnimationFrame, но и так работает
}, { passive: false }); // passive: false — обязательно, чтобы preventDefault работал
// Инициализация
hero.style.height = minHeight + 'px';
</script>
</body>
</html>
← Назад к списку
Комментарии
Пока нет комментариев. Будьте первым!