21.09.2018, 14:37
|
Профессор
|
|
Регистрация: 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.
|
|
21.09.2018, 14:58
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
s24344,
делали бы макет целиком
|
|
22.09.2018, 06:40
|
Профессор
|
|
Регистрация: 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.
|
|
22.09.2018, 09:21
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
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.
|
|
22.09.2018, 15:44
|
Профессор
|
|
Регистрация: 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.
|
|
22.09.2018, 17:23
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
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.
|
|
22.09.2018, 19:47
|
Профессор
|
|
Регистрация: 12.08.2015
Сообщений: 206
|
|
Рони, спасибо Вам за помощь. Небольшое несовпадение с позицией элемента есть, но это уже ерунда. Можно поиграться со значениями this.strafeAmount. Вы очень помогли.
|
|
|
|