实现思路:利用粘性定位sticky,以及滚动事件实现。首先我们应该设置滚动动画开始位置和结束位置 ,然后根据位置计算透明度或者transform,scale的值。
首先根据上述图线计算属性值,代码如下:
function createAnimate(scrollStart, scrollEnd, valueStart, valueEnd) {
return function (x) {
if (x < scrollStart) {
return valueStart;
}
if (x > scrollEnd) {
return valueEnd;
}
const bili = (valueEnd - valueStart) / (scrollEnd - scrollStart);
return bili * (x - scrollStart) + valueStart;
};
}
然后考虑到每个dom它的动画不是只有一个属性可能有多个,例如scale,opacity,transform等。然后应该将dom和属性存储到map集合中,key为dom,属性为value。
const items = document.querySelectorAll('.list-item');
const animationMap = new Map();
const getTitleAnimation = (scrollStart, scrollEnd, dom) => {
const opacityAnimation = createAnimate(scrollStart, scrollEnd, 1, 0);
const yAnimation = createAnimate(scrollStart, scrollEnd, 0, -200);
const transform = function (x) {
return `translate(0,${yAnimation(x)}px)`;
};
const opacity = function (x) {
return opacityAnimation(x);
};
return {
transform,
opacity,
};
};
const updateMap=()=>{
for (const item of items) {
animationMap.set(
item,
getTitleAnimation(scrollStart + 50, scrollEnd, item)
);
}
}
然后就是属性赋值:
const updateStyles = () => {
const scrollY = window.scrollY;
for (const [dom, animations] of animationMap) {
for (const prop in animations) {
const value = animations[prop](scrollY);
dom.style[prop] = value;
}
}
};
updateStyles();
window.addEventListener('scroll', updateStyles);
全部代码访问: liuzicheng/web - Gitee.com