Skip to content

Instantly share code, notes, and snippets.

@kobitoDevelopment
Last active August 28, 2022 12:21
Show Gist options
  • Select an option

  • Save kobitoDevelopment/d88940c529ab7388015823b443f99111 to your computer and use it in GitHub Desktop.

Select an option

Save kobitoDevelopment/d88940c529ab7388015823b443f99111 to your computer and use it in GitHub Desktop.
<div class="parallax">
<div class="parallax__inner js-parallax">
<div class="count">
<video src="assets/images/movie.mp4" autoplay muted playsinline class="count__video"></video>
</div>
</div>
</div>
<div class="parallax-end"></div>
/* スクロールアニメーションを設定 */
// アニメーションさせる要素を取得
const count = document.querySelector(".count");
// スクロール率を取得
let scrollPercent = 0;
// 線形補完 第一引数:開始時 第二引数:終了時 第三引数:上限
function lerp(x, y, a) {
return (1 - a) * x + a * y;
}
function scalePercent(start, end) {
return (scrollPercent - start) / (end - start);
}
// アニメーション配列を設定
const animationScripts = [];
animationScripts.push(
{
start: 0, // アニメーションが開始される位置
end: 50, // アニメーションが終了する位置
function() {
// 線形補完の引数にstart end の数値を一致させる事でアニメーションが実行されるスクロール範囲とアニメーションの開始終了が一致する
count.style.scale = lerp(0.5, 0.8, scalePercent(0, 50));
},
},
{
start: 51, // アニメーションが開始される位置
end: 70, // アニメーションが終了する位置
function() {
// 線形補完の引数にstart end の数値を一致させる事でアニメーションが実行されるスクロール範囲とアニメーションの開始終了が一致する
count.style.scale = lerp(0.8, 1, scalePercent(51, 70));
},
},
{
start: 71, // アニメーションが開始される位置
end: 100, // アニメーションが終了する位置
function() {
// 線形補完の引数にstart end の数値を一致させる事でアニメーションが実行されるスクロール範囲とアニメーションの開始終了が一致する
count.style.scale = lerp(1, 1, scalePercent(71, 100));
},
}
);
// アニメーション関数を設定
function playScrollAnimation() {
animationScripts.forEach(function (animation) {
if (scrollPercent >= animation.start && scrollPercent <= animation.end) {
animation.function();
}
});
}
//
const parallax = document.querySelector(".parallax");
const parallaxContent = document.querySelector(".js-parallax");
const parallaxContentHeight = parallaxContent.offsetHeight;
const parallaxEnd = document.querySelector(".parallax-end");
const scrollHeight = parallax.offsetHeight; // パララックス要素の総スクロール量を取得
const clientHeight = document.documentElement.clientHeight; // デバイス表示領域の高さを取得
let windowHeight = window.innerHeight;
let isIntersecting;
/* パララックス要素が画面内にある場合のみスクロールイベントを発火 開始 */
const observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
window.addEventListener("scroll", parallaxAction, { passive: true });
//画面内判定フラグ
isIntersecting = true;
} else {
window.removeEventListener("scroll", parallaxAction, { passive: true });
//画面内判定フラグ
isIntersecting = false;
}
});
});
//observer監視開始
observer.observe(parallax);
/* パララックス要素が画面内にある場合のみスクロールイベントを発火 終了 */
function parallaxAction() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const windowBottom = scrollTop + windowHeight;
const parallaxRect = parallax.getBoundingClientRect();
const parallaxTop = parallaxRect.top + scrollTop;
const parallaxEndRect = parallaxEnd.getBoundingClientRect();
const parallaxEndTop = parallaxEndRect.top + scrollTop;
const scrollDif = scrollTop - parallaxTop; // スクロール量をアニメーション数値に利用したい場合に使用
scrollPercent = (scrollDif / (scrollHeight - clientHeight)) * 100; // 何%スクロールしているかを算出
/* パララックス要素1つ目 */
if (scrollTop > parallaxTop && windowBottom > parallaxEndTop) {
// パララックス終了位置を通過した場合
parallaxContent.classList.remove("is-fixed");
parallaxContent.classList.add("is-finished");
count.style.scale = 1;
} else {
// パララックス開始位置を通過した場合
if (scrollTop > parallaxTop) {
playScrollAnimation();
parallaxContent.classList.add("is-fixed");
parallaxContent.classList.remove("is-finished");
} else {
// パララックス開始位置に到達する前
parallaxContent.classList.remove("is-fixed");
count.style.scale = 0.5;
}
}
}
.parallax {
height: 300vh; // 希望の固定し続けたい高さ
width: 100%;
position: relative;
/*デバッグ用*/
margin-top: 50vh;
/*デバッグ用*/
&__inner {
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 100%;
&.is-fixed {
position: fixed;
top: 0;
}
&.is-finished {
position: absolute;
top: 200vh; // 希望の固定し続けたい高さ - パララックス要素の高さ
}
.count {
width: 100%;
height: 100%;
scale: 0.5;
transform-origin: center;
background-color: green;
}
}
}
/*デバッグ用*/
.parallax-end {
margin-bottom: 50vh;
}
/*デバッグ用*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment