为什么使用.bind(mousewheel)绑定的滚轮滚动体验非常不自然?
类iOS日期选择器滚动效果实现方案
现有代码问题
- 直接监听mousewheel事件时固定每次增减1度,滚动速度和滚轮滑动幅度完全无关,所以速度始终固定
- 给
.outer_box设置的0.1s过渡时长过短,且每次wheel事件触发都会打断正在进行的过渡,完全没有惯性缓动效果 scroll事件不触发是因为你给body设置了overflow-y: hidden,页面本身没有可滚动高度,自然不会触发scroll事件
修改方案
通过维护目标旋转值、当前渲染值做差值缓动计算,配合requestAnimationFrame实现平滑的惯性滚动效果,修改后的代码如下:
修改后的JavaScript代码
var targetCounter = 0; // 目标旋转角度 var currentCounter = 0; // 当前实际渲染的角度 var easeFactor = 0.08; // 缓动系数,数值越大滚动响应越快 var step = 16.36363636; // 每个选项对应的旋转角度,和CSS中每个in_box的rotateX差值保持一致 // 兼容全浏览器的wheel事件监听 $(document).on("wheel", function(event) { event.preventDefault(); // 根据滚轮滚动方向和幅度计算,向下滚增加角度,向上滚减少角度 var delta = event.originalEvent.deltaY > 0 ? step : -step; targetCounter += delta; // 可选:添加边界限制,避免无意义的无效滚动 targetCounter = Math.max(0, Math.min(targetCounter, 360)); }) // 逐帧渲染实现平滑过渡 function animate() { // 缓动计算:当前值逐步靠近目标值,模拟惯性效果 currentCounter += (targetCounter - currentCounter) * easeFactor; // 浮点误差修正,避免无限次小数运算 if (Math.abs(targetCounter - currentCounter) < 0.01) { currentCounter = targetCounter; } $(".outer_box").css({"transform":"perspective(1000px) rotateX("+currentCounter+"deg)"}) requestAnimationFrame(animate); } // 启动动画循环 animate();
CSS调整
把.outer_box的transition属性移除即可,避免和JS动画冲突:
.outer_box{ width: 100vw; height: 100%; position: relative; transform: perspective(1000px) rotateX(.1deg); transform-style: preserve-3d; transition: none; }
调整后滚动速度会和滚轮滑动幅度正相关,停止滚动时会有自然的减速缓出效果,和原生滚动体验一致,也可以根据自己的需求调整easeFactor参数调整滚动灵敏度。
内容的提问来源于stack exchange,提问作者m4424
相关产品推荐
相关产品推荐

