我刚刚在这个网站上看到了一个精彩的滚动动画https://thehungryfamily.com/bon-bouquet-cafe/。 当用户滚动时,一些图标会不断旋转。我尝试模仿相同的动画,但无法理解其中的逻辑。
到目前为止我做了什么
但不知何故我仍然错过了一些逻辑。我面临的挑战是确定用户滚动方向(用户是从上到下还是从下到上滚动)
这是我的代码
function getAngle(str)
{
if(str)
{
let angle=str.split("(");
let angleArr=angle[1].split("t");
return parseFloat(angleArr[0]);
}
}
const globeOptions = {
rootMargin: '0px',
threshold: [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]
}
const globeCallback = entries => {
entries.forEach(entry => {
const currentY = entry.boundingClientRect.y
const currentRatio = entry.intersectionRatio
const isIntersecting = entry.isIntersecting;
let prevAngle=
entry.target.style.transform ? getAngle(entry.target.style.transform):0;
if (currentY < previousY) {
if (currentRatio > previousRatio && isIntersecting) {
entry.target.style.transform=`rotate(${prevAngle+0.2}turn)`;
} else {
entry.target.style.transform=`rotate(${prevAngle+0.2}turn)`;
}
} else if (currentY > previousY && isIntersecting) {
if (currentRatio < previousRatio) {
entry.target.style.transform=`rotate(${-(prevAngle-0.2)}turn)`;
} else {
entry.target.style.transform=`rotate(${-(prevAngle-0.2)}turn)`;
}
}
previousY = currentY
previousRatio = currentRatio
})
}
const globeobserver = new IntersectionObserver(globeCallback, globeOptions)
const globeTarget = document.querySelector('.globe-box img')
globeobserver.observe(globeTarget)
我只会监听主监听器上的滚动事件并根据此信息计算旋转。 如果要保证每个元素的初始显示,计算可能会稍微复杂一些,但这种方法仍然有效。
const container = document.querySelector('.container')
const main = document.querySelector('.main')
function handleScroll () {
const icons = document.querySelectorAll('.icon')
const rotate = container.scrollTop / 10
icons.forEach((icon, index) => {
icon.style.transform = `rotate(${index % 2 === 0 ? '' : '-'}${rotate}deg)`
})
}
container.addEventListener('scroll', handleScroll)
body {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
.container {
height: 100%;
width: 100%;
overflow: auto;
}
.main {
height: 2000px;
width: 100%;
}
.icon {
margin: 10px;
display: inline-block;
height: 30px;
width: 30px;
transition: transform 0.15s;
}
.icon:nth-child(odd) {
background-image: url(https://thehungryfamily.com/storage/2024/07/BBV-illustration-elements-11.svg);
background-repeat: no-repeat;
}
.icon:nth-child(even) {
background-image: url(https://thehungryfamily.com/storage/2024/07/BBV-illustration-elements-10.svg);
background-repeat: no-repeat;
}
<div class='container'>
<div class='main'>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
<div class='icon'></div>
</div>
</div>