Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.09.2018, 14:37
Профессор
Отправить личное сообщение для s24344 Посмотреть профиль Найти все сообщения от s24344
 
Регистрация: 12.08.2015
Сообщений: 206

Как реализовать parallax не привязанный к window.pageYOffset
Здравствуйте. Подскажите пожалуйста как решить следующую задачу.
Реализован следующий функционал parallax. Сейчас он воздействует на элементы сразуже при скролле. Как мне реализовать следующее, начинать воздействие на элементы только при появлении их во viewport. А затем в обратном направлении.
CodePen
https://codepen.io/s24344/pen/WgmVbP

<section class="anime__section">
    <div class="anime__large">
        <div class="anime__small"></div>
    </div>
</section>

<section class="anime__section">
    <div class="anime__large">
        <div class="anime__small"></div>
    </div>
</section>

var parallax = (function() {

  var bg = document.querySelectorAll('.anime__small');

  return {
    move: function(block, windowScroll, strafeAmount) {
      var strafe = windowScroll / -strafeAmount + '%';
      var transformString = 'translate3d(0,' + strafe + ', 0)';

      var elements = [...block];

      elements.forEach(item => {
        item.style.transform = transformString;
        item.style.webkitTransform = transformString;
      });
      
      style.transform = transformString;
      style.webkitTransform = transformString;
    },

    init: function(wScroll) {
      this.move(bg, wScroll, 20);
    }
  };
})();

window.onscroll = function() {
  var wScroll = window.pageYOffset;
  parallax.init(wScroll);
};

Последний раз редактировалось s24344, 22.09.2018 в 06:40.
Ответить с цитированием
  #2 (permalink)  
Старый 21.09.2018, 14:58
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

s24344,
делали бы макет целиком
Ответить с цитированием
  #3 (permalink)  
Старый 22.09.2018, 06:40
Профессор
Отправить личное сообщение для s24344 Посмотреть профиль Найти все сообщения от s24344
 
Регистрация: 12.08.2015
Сообщений: 206

CodePen
https://codepen.io/s24344/pen/WgmVbP

Сейчас parallax начинает работать сразу же при скролле (т.к. расчет идет this.wScroll) на все выбранные элементы (data-hero-bg="hero-bg"). Мне же нужно, чтобы он начинал работать при появлении anime__section во viewport.

Последний раз редактировалось s24344, 22.09.2018 в 06:52.
Ответить с цитированием
  #4 (permalink)  
Старый 22.09.2018, 09:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

parallax class
s24344,
не знаю какого эффекта вы хотите достичь, но можно так ...
<!DOCTYPE html><html lang='en' class=''>
<head>
    <meta charset='UTF-8'>


<style class="cp-pen-styles">.app__content {
    padding: 200px 0;
}

.anime__section {
    display: flex;
    justify-content: flex-end;
}

.anime__large {
    position: relative;
    width: 705px;
    height: 694px;
    background: #61bfad;
}

.anime__small {
    width: 250px;
    height: 250px;
    background: #055a5b;
    position: absolute;
    bottom: -125px;
    left: -125px;
}
</style></head><body>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div class="parallax-app" data-component="parallax">
        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small hero__bg" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section>
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section>
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>
    </div>
</body>

</html>
<script >class AppParallax {
    constructor(el) {
        this.el = el;
        this.strafeAmount = 230;

        this.heroBg = [...this.el.querySelectorAll('[data-hero-bg="hero-bg"]')];

        this.move = this.move.bind(this);

        this.init();
    }

    init() {
        window.addEventListener('scroll', this.move);
    }
    checkViewport(el) {
        var rect = el.getBoundingClientRect();
        var y = rect.bottom / (innerHeight + rect.bottom - rect.top);
        return y
    }

    move() {
          this.heroBg.forEach(item => {
            let parent = item.parentNode;
            let y = this.checkViewport(parent); 
            let strafe = -y * this.strafeAmount + '%';
            let transformString = 'translateY('+strafe+')';
            item.style.transform = transformString;
            item.style.webkitTransform = transformString;
        });

    }}


const appParallax = new AppParallax(
document.querySelector('[data-component="parallax"]'));
</script>
</body></html>

Последний раз редактировалось рони, 22.09.2018 в 09:25.
Ответить с цитированием
  #5 (permalink)  
Старый 22.09.2018, 15:44
Профессор
Отправить личное сообщение для s24344 Посмотреть профиль Найти все сообщения от s24344
 
Регистрация: 12.08.2015
Сообщений: 206

В предложенном вами решении, при первом скролле вниз происходит резкий скачек элемента (на котором parallax), а затем он движется вниз (у меня же он со своей изначальной позиции движется вверх при сколле вниз, а затем возвращается обратно). Я же пытаюсь достичь, что бы вне зависимости от расположения виджета (контейнера) на странице везде был эффект, как на самом верхнем. Я немного изменил pen, но по прежнему не понимаю как избавится от this.wScroll в this.strafe = this.wScroll / -this.strafeAmount + '%'; У вас работает примерно как мне нужно, но как-то наоборот плюс скачок, как я выше описал.
https://codepen.io/s24344/pen/WgmVbP

Последний раз редактировалось s24344, 22.09.2018 в 15:48.
Ответить с цитированием
  #6 (permalink)  
Старый 22.09.2018, 17:23
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

s24344,
не могу понять что вам нужно, так?
<!DOCTYPE html><html lang='en' class=''>
<head>
    <meta charset='UTF-8'>


<style class="cp-pen-styles">.app__content {
    padding: 200px 0;
}

.anime__section {
    display: flex;
    justify-content: flex-end;
}

.anime__large {
    position: relative;
    width: 705px;
    height: 694px;
    background: #61bfad;
}

.anime__small {
    width: 250px;
    height: 250px;
    background: #055a5b;
    position: absolute;
    bottom: -125px;
    left: -125px;
}
</style></head><body>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div class="parallax-app" data-component="parallax">
        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small hero__bg" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section>
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section>
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>

        <section class="anime__section">
            <div class="anime__large">
                <div class="anime__small" data-hero-bg="hero-bg"></div>
            </div>
        </section>

        <section class="app__content">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae, asperiores assumenda vel itaque
                cumque
                eveniet adipisci, laboriosam nulla ipsum ea, mollitia fugit minima natus amet! Deleniti recusandae nam
                reprehenderit atque?
            </p>
        </section>
    </div>
</body>

</html>
<script >class AppParallax {
    constructor(el) {
        this.el = el;
        this.strafeAmount = 190;

        this.heroBg = [...this.el.querySelectorAll('[data-hero-bg="hero-bg"]')];

        this.move = this.move.bind(this);

        this.init();
    }

    init() {
        window.addEventListener('scroll', this.move);
    }
    checkViewport(el) {
        var rect = el.getBoundingClientRect();
        var y =  rect.top ;
        return rect.top < innerHeight && rect.top > -innerHeight ? rect.top/innerHeight : 0
    }

    move() {
          this.heroBg.forEach((item, i) => {
            let parent = item.parentNode;
            let y = this.checkViewport(parent);
            let strafe = y * this.strafeAmount + '%';
            let transformString = 'translateY('+strafe+')';
            if(y){
              item.style.transform = transformString;
            item.style.webkitTransform = transformString;
            }
        });

    }}


const appParallax = new AppParallax(
document.querySelector('[data-component="parallax"]'));
</script>
</body></html>

Последний раз редактировалось рони, 22.09.2018 в 17:34.
Ответить с цитированием
  #7 (permalink)  
Старый 22.09.2018, 19:47
Профессор
Отправить личное сообщение для s24344 Посмотреть профиль Найти все сообщения от s24344
 
Регистрация: 12.08.2015
Сообщений: 206

Рони, спасибо Вам за помощь. Небольшое несовпадение с позицией элемента есть, но это уже ерунда. Можно поиграться со значениями this.strafeAmount. Вы очень помогли.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно реализовать прокрутку меню? goody-goody Элементы интерфейса 2 25.11.2015 18:07
Как реализовать проверку текстового поля? Валерий1996 Общие вопросы Javascript 3 26.08.2015 13:27
Как реализовать динамичное добавление тегов modelfak23 jQuery 1 19.06.2015 14:27
Как правильно реализовать такой функционал? Julian Общие вопросы Javascript 3 16.01.2015 12:34
Как реализовать? Fliand Элементы интерфейса 4 22.08.2009 19:47