出典: Duyi フロントエンド
1.効果:
マウス ホイールを使用して Web ページ上の画像の上下の切り替えを制御すると、画像はカルーセルと同様に無限にスクロールします。
2. 一般的な考え方
1. 無限スクロールを実現するには、現在の画像 (cur)、前の画像 (pre)、および次の画像 (next) を考慮するだけでよく、これらは括弧で置き換えられます。
2. アニメーションはトランジションを使用して画像の高さを 0 から 100% まで変更します。
3. マウス ホイール イベント (ホイール) を監視し、返されたデルタに従ってマウス ホイールの方向を判断する必要があります。
4. 画面のスタイルを動的に変更するには、トランジションアニメーションの終了イベントを監視する必要があります
3. 実現
考慮する必要がある 3 つの画像要素は常に変化するため、ここでは JS を使用して画像要素を動的に生成することを選択します。各画像の初期幅はビューポートを満たす必要があります。最初は現在の画像のみが表示され、他の画像要素は画像は隠されています。これは CSS の位置決めを使用して行われます。初期状態では、cur の高さは 100vh で、pre と next の高さは 0 です。Pre が上部に配置され、next が下部に配置されます。マウスホイールの方向に応じてこれら 3 つの画像を再生成し、前後の高さを 100% に変更します。
1. ディレクトリ
2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>视差滚动</title>
</head>
<body>
<div class="scroll-container"></div>
</body>
<script src="./index.js"></script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
}
.item {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
transition: 1s ease-in-out;
}
.item img {
position: absolute;
width: 100%;
height: 100vh;
object-fit: cover;
transition: 1s ease-in-out;
}
.scroll-container {
height: 100vh;
position: relative;
}
.item.pre,
.item.next {
z-index: 1;
height: 0;
}
.item.pre {
top: 0;
}
.item.next {
bottom: 0
}
.item.pre img {
transform: translateY(-10%);
}
.item.next img {
bottom: 0;
transform: translateY(10%);
}
.scroll-up .pre,
.scroll-down .next {
height: 100%;
}
.scroll-up .pre img {
transform: translateY(0);
}
.scroll-up .cur img {
transform: translateY(10%);
}
.scroll-down .next img {
transform: translateY(0);
}
.scroll-down .cur img {
transform: translateY(-10%);
}
</style>
</html>
3.js
const imgs = ['./assets/1.jpg', './assets/2.png', './assets/3.jpg']
let currentIndex = 0
const scrollContainer = document.querySelector('.scroll-container')
function creatItem(index) {
let imgUrl = imgs[index]
const item = document.createElement('div')
item.classList.add('item')
item.innerHTML = `<img src=${imgUrl} />`
scrollContainer.appendChild(item)
return item
}
function init() {
scrollContainer.innerHTML = ''
let preIndex = currentIndex - 1 < 0 ? imgs.length - 1 : currentIndex - 1
let nextIndex = currentIndex + 1 > imgs.length - 1 ? 0 : currentIndex + 1
creatItem(preIndex).classList.add('pre')
creatItem(currentIndex).classList.add('cur')
creatItem(nextIndex).classList.add('next')
}
init()
let isAnimation = false
scrollContainer.addEventListener('wheel', (e) => {
if ((e.deltaY = 0)) {
return
}
if (isAnimation) {
return
}
isAnimation = true
if (e.deltaY > 0) {
//向下滚动
scrollContainer.classList.add('scroll-down')
currentIndex = currentIndex + 1 > imgs.length - 1 ? 0 : currentIndex + 1
} else {
//向上滚动
scrollContainer.classList.add('scroll-up')
currentIndex = currentIndex - 1 < 0 ? imgs.length - 1 : currentIndex - 1
}
})
scrollContainer.addEventListener('transitionend', (e) => {
isAnimation = false
scrollContainer.classList.remove('scroll-up')
scrollContainer.classList.remove('scroll-down')
init()
})