
本教程将深入探讨如何利用javascript和css创建类似weltio网站的平滑粘性滚动动画。我们将通过禁用原生滚动、监听用户输入、利用`requestanimationframe`进行动画插值以及应用css `transform`属性,构建一个高度可控且流畅的自定义滚动系统。文章将详细介绍如何处理滚动边界、实现弹性回弹效果,并为实现复杂交互如全屏粘性水平滑块提供核心技术基础。
引言:超越原生滚动的限制
在现代网页设计中,平滑且具有交互性的滚动体验已成为提升用户体验的关键。许多开发者尝试使用纯CSS解决方案,如scroll-snap-type或position: sticky来创建粘性或分段滚动效果。然而,这些原生CSS属性虽然方便,但在实现如Weltio网站那种高度定制化、流畅且带有物理感的“粘性平滑滚动”动画时,往往力不从心。原生滚动行为的平滑度受浏览器限制,且难以进行精细的动画控制。
要实现这种高级的滚动效果,我们需要绕过浏览器的原生滚动机制,转而使用JavaScript来完全控制页面的滚动行为。核心思想是禁用原生滚动,然后通过监听用户的滚动输入,利用JavaScript计算并平滑地过渡到目标滚动位置,并通过CSS transform: translate3d()(或translateY())来移动页面内容,从而实现GPU加速的流畅动画。
核心机制:自定义滚动系统的构建
构建自定义平滑滚动系统需要以下几个关键步骤:
1. 禁用原生滚动
首先,我们需要阻止浏览器自身的滚动行为,以确保JavaScript可以完全接管滚动控制。这通常通过在body元素上设置overflow: hidden来实现。
立即学习“Java免费学习笔记(深入)”;
html, body { margin: 0; padding: 0;}body { overflow: hidden; /* 禁用原生滚动 */ min-height: 100vh; /* 确保内容有足够的空间 */}/* 示例内容元素样式 */.element { height: 300px; background-color: #112233; margin: 20px; border-radius: 20px;}
2. 捕获用户输入
接下来,我们需要监听用户的滚动输入。对于桌面设备,这主要是通过window对象的wheel事件来实现。event.deltaY属性提供了滚轮滚动的垂直距离。
let desiredScroll = 0; // 目标滚动位置let actualScroll = 0; // 当前实际滚动位置// 监听滚轮事件,更新目标滚动位置window.addEventListener("wheel", event => { desiredScroll += event.deltaY;});
注意:对于触摸设备,需要额外处理touchstart、touchmove和touchend事件来模拟滚动输入。
3. 平滑动画循环
为了实现平滑过渡,我们不能直接将actualScroll设置为desiredScroll。相反,我们需要一个动画循环,让actualScroll逐步趋近desiredScroll。requestAnimationFrame是实现浏览器优化动画的最佳选择。
function updateScroll() { const delay = 10; // 控制平滑度的延迟因子,值越大越平滑 // 插值计算,使actualScroll平滑地趋近desiredScroll actualScroll = actualScroll + (desiredScroll - actualScroll) / delay; updateTransform(); // 更新页面元素的transform window.requestAnimationFrame(updateScroll); // 循环调用}// 应用transform来移动所有需要滚动的元素function updateTransform() { // 可以选择移动所有元素,或者只移动所有内容的父容器 // 这里以移动所有具有'element'类的元素为例 const elements = [...document.getElementsByClassName('element')]; elements.forEach(element => element.style.transform = `translateY(${-actualScroll}px)`); // 如果所有内容都在一个父div中,可以直接移动该父div // document.getElementById('content-wrapper').style.transform = `translateY(${-actualScroll}px)`;}// 启动动画循环window.requestAnimationFrame(updateScroll);
代码示例 1:基础平滑滚动实现
以下是一个结合HTML、CSS和JavaScript的基础平滑滚动实现:
基础平滑滚动 html, body { margin: 0; padding: 0; font-family: sans-serif; color: #fff; } html { background-color: #334499; } body { overflow: hidden; /* 禁用原生滚动 */ min-height: 100vh; /* 确保内容有足够的空间 */ /* 注意:实际内容高度会影响滚动范围,这里只是示例 */ } .element { height: 300px; background-color: #112233; margin: 20px; border-radius: 20px; display: flex; justify-content: center; align-items: center; font-size: 2em; }内容块 1内容块 2内容块 3内容块 4内容块 5内容块 6let desiredScroll = 0; let actualScroll = 0; function updateScroll() { const delay = 10; // 平滑度因子 actualScroll = actualScroll + (desiredScroll - actualScroll) / delay; updateTransform(); window.requestAnimationFrame(updateScroll); } const elements = [...document.getElementsByClassName('element')]; function updateTransform() { // 移动所有内容块的父容器,这里我们假定body是所有内容的直接父容器 // 实际上,最好将所有内容包裹在一个div中,然后移动那个div document.body.style.transform = `translateY(${-actualScroll}px)`; } window.addEventListener("wheel", event => { desiredScroll += event.deltaY; }); window.requestAnimationFrame(updateScroll);
高级优化:滚动边界与弹性回弹
上述基础系统已经实现了平滑滚动,但还需要进一步完善,例如限制滚动范围以及添加“橡皮筋”般的弹性回弹效果。
1. 设置滚动边界
滚动不应无限进行。我们需要计算页面的最大可滚动高度,并限制desiredScroll在这个范围内。
maxScrollHeight = document.body.clientHeight – window.innerHeight;
document.body.clientHeight:所有内容的总高度。window.innerHeight:视口的高度。两者的差值即为内容可滚动的最大距离。
2. 实现弹性回弹效果
类似于iPhone的滚动效果,当用户尝试滚动超出内容边界时,滚动速度会减慢,并在用户停止滚动后自动回弹。
当desiredScroll小于0(向上超出顶部)或大于maxScrollHeight(向下超出底部)时,减缓desiredScroll的增加/减少速度。当actualScroll非常接近desiredScroll时,直接将其设置为desiredScroll,防止微小的抖动。
代码示例 2:带边界和弹性回弹的平滑滚动
平滑滚动与弹性回弹 html, body { margin: 0; padding: 0; font-family: sans-serif; color: #fff; } html { background-color: #334499; } body { overflow: hidden; /* 禁用原生滚动 */ min-height: 100vh; padding: 20px 0; /* 为内容添加一些垂直内边距 */ } .element { height: 300px; background-color: #112233; margin: 20px; border-radius: 20px; display: flex; justify-content: center; align-items: center; font-size: 2em; }内容块 1内容块 2内容块 3内容块 4内容块 5内容块 6内容块 7内容块 8内容块 9内容块 10let desiredScroll = 0; let actualScroll = 0; function updateScroll() { const delay = 10; // 平滑度因子 const maxScrollHeight = document.body.clientHeight - window.innerHeight; // 最大可滚动高度 // 处理超出边界时的desiredScroll(弹性回弹效果) if (desiredScroll < 0) { desiredScroll -= desiredScroll / (delay / 2
以上就是实现JavaScript驱动的平滑粘性滚动效果的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1596137.html
微信扫一扫
支付宝扫一扫