原理:
① 定义一个数组,数组里面包含每张图片的引用以及它们进入、进入完成、离开、完成离开时的百分比
② 监听页面滚动,算出当前的滚动进度
③ 遍历数组,根据当前进度修改图片的状态,修改图片的–progress属性值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| for (const { ele, inEnter, inLeave, outEnter, outLeave } of animeList) { if (progress >= outLeave) { ele.className = 'out-leave' ele.style.setProperty('--progress', 0) } else if (progress >= outEnter) { ele.className = 'out-enter' ele.style.setProperty('--progress', (progress - outEnter) / (outLeave - outEnter)) } else if (progress >= inLeave) { ele.className = 'in-leave' ele.style.setProperty('--progress', (progress - inLeave) / (outEnter - inLeave)) } else if (progress >= inEnter) { ele.className = 'in-enter' ele.style.setProperty('--progress', (progress - inEnter) / (inLeave - inEnter)) } else { ele.className = '' ele.style.setProperty('--progress', 1) } }
|
④ 样式表里设置每张图片的在每个状态(in-enter、in-leave、out-enter、out-leave)的位置和透明度,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #hair-1-1 { transform: translate(-86px, calc(-138px - 280px)); opacity: 0;
&.in-enter { transform: translate(-86px, calc(-138px - 280px * (1 - var(--progress)))); opacity: calc(var(--progress) * 1.5); }
&.in-leave { transform: translate(-86px, -138px); opacity: 1; }
&.out-enter { transform: translate(-86px, -138px); opacity: calc(1 - var(--progress)); }
&.out-leave { transform: translate(-86px, -138px); opacity: 0; } }
|

css变量的兼容性:https://caniuse.com/css-variables
完整代码戳这里
在线演示1、在线演示2