Страницы

Поиск по вопросам

вторник, 30 октября 2018 г.

Как реализовать такой эффект параллакса?

На сайте Apple (блок "Самый мощный iMac в истории") есть эффект параллакса. При прокрутке до определенной точки картинка начинает прокручиваться медленнее текста, и в конце медленная прокрутка сменяется стандартной. Как можно реализовать такой же эффект?
UPD:
Есть скрипт, который при прокрутке до определенной высоты замедляет прокрутку блока. Сначала у нас блок с абсолютным позиционированием, при прокрутке определенного количества пикселей блок получает фиксированное позиционирование и начинает прокручиваться медленнее основного контента.
// Наш элемент, который будет замедляться var $element = $('.first'), /* * Последняя позиция скролла, нужна * для вычисления */ lastScrollTop = 0, /* * Отступ сверху для нашего блока * с фиксированным и абсолютным * позиционированием */ defaultElementAbsoluteTop = 150, defaultElementFixedTop = 90, // Коэффициэнт замедления n = 4;
// Отслеживаем скролл страницы $(window).scroll(function (event) {
// Вычисляем текущее положение var scrollTop = $(window).scrollTop(), /* * Вычисляем положение нашего блока * от верхней части сайта/родителя. * Т.к. этот элемент до этого был абсолютным, * то у него отступ сверху всегда одинаков, * А когда подходит момент, когда нужно его фиксировать * отступ расчитывается от последнего, который был * 150 пикселей. Это неправильно. Я ввел проверку, * Если отступ стандартный абсолютный равен * текущему, то, при фиксировании блока * ставим ему оступ фиксированного блока * и отсюда начинаются правильные расчеты */ elementTop = $element.position().top == defaultElementAbsoluteTop ? defaultElementFixedTop : $element.position().top;
if(scrollTop < 60) { /* * Проскролили меньше, чем на 60 пикселей * То оставляем абсолютное позиционирование */ $element.removeClass('fixed'); // И ставим элементу абсолютный отступ сверху $element.css({ top: defaultElementAbsoluteTop }); } else { // Фиксируем элемент $element.addClass('fixed'); // TODO: удалить! //return;
/* * Если прошлое положение меньше, * чем текущее, значит двигаемся <вниз> */ if (scrollTop > lastScrollTop){ // Вычисляем разницу перемещения var diff = scrollTop - lastScrollTop; // Даем отступ сверху в n раз меньше, чем скролл $element.css({ top: elementTop - diff/n + 'px' }); // В противном случае, двигаемся <вверх> } else { // Вычисляем разницу перемещения var diff = lastScrollTop - scrollTop; /* * Вычисляем результирующее положение нашего элемента, * с учетом замедления n */ resultElementTop = elementTop + diff/n; /* * Если конечный результат вышел больше, * чем отступ сверху по умолчанию, * то даем стандартный отступ. * Иначе даем результирующий отступ */ resultElementTop = resultElementTop > defaultElementFixedTop ? defaultElementFixedTop : resultElementTop; // Позиционируем элемент $element.css({ top: resultElementTop + 'px' }); } } // Запоминаем последнюю позицию скролла lastScrollTop = scrollTop; });
Нужно, чтобы блок сначала был с position: absolute, при прокрутке до определенного участка блок получает position:fixed и прокручиваетс медленнее. При прокрутке страницы ещё ниже, блок опять становится абсолютно спизиционированным. При рокрутке обратно вверх блок получает фиксированное позиционирование и прокручивается вниз с того момента, на котором остановился при прокрутке вверх.


Ответ

Поковырялся, вот что получилось.
firstPosScroll = []; // позиция курсора, с которой объект видим windowH = $(window).height(); // высота окна getPosScroll(); // заполнение вышеуказанных позиций $(window).resize(function() { // при изменении размера окна пересчитываем позиции getPosScroll(); }) $(window).scroll(function() { //обработчик скролла posScroll = $(this).scrollTop(); // текущая позиция курсора posMiddle = windowH / 2; // середина окна $('.prlx').each(function(i, v) { // для каждого объекта offsetObj = $(this).offset().top; // положение объекта относительно верха документа posObj = offsetObj - posScroll; // текущая позиция объекта koef = 1 - ($(this).find('.logo').height() / $(this).find('.desc').height()); // коэффициент замедления обратно пропорционален разнице высот картинки и описания if (posObj < posMiddle && posObj + $(this).height() > posMiddle) { //условие видимости объекта $(this).find('.logo').css({ 'top': (posScroll - firstPosScroll[i] - posMiddle) * koef + 'px' }); // задаем высоту } }); }); function getPosScroll() { $('.prlx').each(function(i, v) { firstPosScroll[i] = $(this).offset().top - windowH < 0 ? 0 : $(this).offset().top - windowH; }); } section {position: relative;} section.left-logo>div.logo {left: 0;} section.left-logo>div.desc {float: right;width: 50%;} section.right-logo>div.logo {right: 0;} div.logo {position: absolute;width: 50%;} section.right-logo>div.desc {float: left;width: 50%;} header {height: 800px;background: #e6e6e6;} img {max-width: 100%;} div.p {margin: 20px 0;} div.clear {clear: both;width: 100%;}


Комментариев нет:

Отправить комментарий