Last active
August 28, 2022 12:21
-
-
Save kobitoDevelopment/d88940c529ab7388015823b443f99111 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* スクロールアニメーションを設定 */ | |
| // アニメーションさせる要素を取得 | |
| 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; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .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