水平平滑动量滚动
Horizontal Smooth Momentum Scrolling
问题: 我需要应用一些平滑的鼠标滚轮 水平 滚动到此布局:https://jsfiddle.net/38qLnzkh/.
备选方案: 我发现这个脚本完全符合我的要求,但它似乎只能垂直工作:Butter.js。如果你能让它水平工作,它可能会解决我所有的问题。
重要提示:
1. 应根据屏幕宽度和触摸设备禁用脚本。
2. 它应该像您在 fiddle.
中看到的那样在所有内容之上包含一个菜单
提前致谢。
编辑:
如果不清楚我需要什么,这里有两个例子,我正在寻找的效果:
https://nemesiscorporation.com/
https://www.tentwenty.me/about-us
我的布局:
HTML:
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
CSS:
.outer-wrapper {
width: auto;
height: 100vw;
transform: rotate(-90deg) translateX(-100vh);
transform-origin: top left;
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
width: auto;
transform: rotate(90deg) translateY(-100vh);
transform-origin: top left;
margin: 0;
padding: 0;
}
.section {
color: #000;
width: 100vw;
height: 100vh;
}
有一个很好的包叫做 smooth-scrollbar。
我已经调整了你的例子。它禁用移动设备的平滑滚动,否则它只是调用包。我已经清理了一些 CSS.
/** @see */
function isTouchDevice() {
return window.matchMedia("(pointer: coarse)").matches;
}
function initSmoothScrolling() {
const options = {
damping: 0.1,
alwaysShowTracks: true
};
const elements = document.querySelectorAll(".smooth-scrollbar");
for (const element of elements) {
Scrollbar.init(element, options);
}
}
if (!isTouchDevice()) {
initSmoothScrolling();
}
body {
margin: 0;
padding: 0;
}
.smooth-scrollbar {
overflow: auto;
}
.wrapper {
display: flex;
flex-direction: row;
}
.section {
width: 100vw;
height: 100vh;
flex-shrink: 0;
}
.section:nth-child(odd) {
background-color: #ccc;
}
.section:nth-child(even) {
background-color: #fff;
}
h2 {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: 200px;
margin: 0;
}
<main class="smooth-scrollbar">
<div class="wrapper">
<article class="section"><h2>01</h2></article>
<article class="section"><h2>02</h2></article>
<article class="section"><h2>03</h2></article>
<article class="section"><h2>04</h2></article>
<article class="section"><h2>05</h2></article>
<article class="section"><h2>06</h2></article>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smooth-scrollbar/8.5.3/smooth-scrollbar.js"></script>
我在 github 上发布了一个 API 可以轻松解决这个问题,您可以在下面找到执行所需操作的代码。
与你的相比,我刚刚在 HTML 中添加了 js 代码和 <script>
。
如果您想了解更多,here you can find the documentation。
编辑
由于要求发生了一些变化并且 API 已更新,我修改了下面的示例,使其更适合问题。
答案的主要变化:
- 现在 js 位于一个名为
onload
的 init()
方法中
- css 样式已修改(
transform:rotate
停止大部分滚动 APIs)
- 添加了对导航栏平滑滚动的支持
- 滚动量现在取决于用户实际滚动鼠标滚轮的程度
/* UPDATED 2022 ANSWER */
function init() {
/*
* Variables preparation
*/
let yourWrapperElement = document.getElementsByClassName("outer-wrapper")[0];
let whateverEaseFunctionYouWant = remaningScrollDistance => { return remaningScrollDistance / 15 + 1 };
//Added support for navbar menu's smooth scrolling
uss.hrefSetup();
/*
* As you asked for, we only apply the custom scrolling for desktop devices
* by using the "wheel" event instead of the "scroll" or "touchmove" events.
*/
yourWrapperElement.addEventListener("wheel", event => {
/*
* We want to overwrite the default scrolling behaviour
* of your outer-wrapper component.
*/
event.preventDefault();
event.stopPropagation();
uss.scrollXBy(event.deltaY, yourWrapperElement, null, false);
}, {passive:false});
/*
* We apply a the custom ease function
* which will be used whenever our component is scrolled by the API
*/
uss.setXStepLengthCalculator(whateverEaseFunctionYouWant, yourWrapperElement);
}
body {
margin: 0;
padding: 0;
}
.outer-wrapper {
width: auto;
height: 100vh; /* Changed to vh */
width: 100vw; /* Added */
/*transform: rotate(-90deg) translateX(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
/*scroll-behavior: smooth; ISN'T NEEDED FOR MY API */
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
/*width: auto; NOT NEEDED IF WE USE FLEX-SHRINK 0
transform: rotate(90deg) translateY(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
margin: 0; /* not really needed */
padding: 0; /* not really needed */
}
.section {
color: #000;
flex-shrink: 0; /* ADDED insted of the width/height of the wrapper */
width: 100vw;
height: 100vh;
}
#a { background-color: #ccc; }
#b { background-color: #fff; }
#c { background-color: #ccc; }
#d { background-color: #fff; }
#e { background-color: #ccc; }
#f { background-color: #fff; }
h2 {
text-align: center;
font-size: 200px;
margin: 0;
}
/* MENU _________________________ */
.logo {
float: left;
}
nav {
width: 100%;
}
/* HEADER */
header {
float: left;
width: 100%;
position: absolute;
z-index: 9999;
}
/* HEADER LARGE */
header.large {
height: 50px;
}
header.large .logo {
width: 225px;
height: 50px;
margin: 20px 0 0 20px;
background: url('../images/logo-fireqa-green-500px.png');
background-repeat: no-repeat;
background-size: contain;
transition: 0.7s all;
-moz-transition: 0.7s all;
-webkit-transition: 0.7s all;
-o-transition: 0.7s all;
}
/* UNORDERED LIST */
header.large ul {
list-style: none;
float: right;
margin-right: 25px;
}
header.small ul {
list-style: none;
float: right;
margin: 0;
}
header.large li {
display: inline;
float: left;
list-style-position: inside;
height: 50px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
transition: all 0.3s ease-in-out;
}
header.large li a {
display: block;
padding: 20px;
color: #0E6245;
text-decoration: none;
font-family: 'Montserrat', 'arial', sans-serif;
font-weight: 600 !important;
letter-spacing: -1px;
font-size: 25px;
background-image: linear-gradient(#0E6245, #0E6245);
background-position: 50% 80%;
background-repeat: no-repeat;
background-size: 0% 4px;
-moz-transition: all 0.3s ease-in-out 0s;
-ms-transition: all 0.3s ease-in-out 0s;
-o-transition: all 0.3s ease-in-out 0s;
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
header.large li a:hover, a:focus {
background-size: 60% 4px;
}
<script src = "https://cdn.jsdelivr.net/npm/universalsmoothscroll@latest/universalsmoothscroll-min.js"></script>
<body onload = init()>
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
<!-- MENU _____________________ -->
<header class="large">
<div class="container">
<nav>
<a><div class="logo"></div></a>
<ul>
<li><a href="#a">01</a></li>
<li><a href="#b">02</a></li>
<li><a href="#c">03</a></li>
<li><a href="#d">04</a></li>
</ul>
</nav>
</div>
</header>
</body>
</html>
问题: 我需要应用一些平滑的鼠标滚轮 水平 滚动到此布局:https://jsfiddle.net/38qLnzkh/.
备选方案: 我发现这个脚本完全符合我的要求,但它似乎只能垂直工作:Butter.js。如果你能让它水平工作,它可能会解决我所有的问题。
重要提示:
1. 应根据屏幕宽度和触摸设备禁用脚本。
2. 它应该像您在 fiddle.
中看到的那样在所有内容之上包含一个菜单提前致谢。
编辑: 如果不清楚我需要什么,这里有两个例子,我正在寻找的效果:
https://nemesiscorporation.com/
https://www.tentwenty.me/about-us
我的布局:
HTML:
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
CSS:
.outer-wrapper {
width: auto;
height: 100vw;
transform: rotate(-90deg) translateX(-100vh);
transform-origin: top left;
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
width: auto;
transform: rotate(90deg) translateY(-100vh);
transform-origin: top left;
margin: 0;
padding: 0;
}
.section {
color: #000;
width: 100vw;
height: 100vh;
}
有一个很好的包叫做 smooth-scrollbar。
我已经调整了你的例子。它禁用移动设备的平滑滚动,否则它只是调用包。我已经清理了一些 CSS.
/** @see */
function isTouchDevice() {
return window.matchMedia("(pointer: coarse)").matches;
}
function initSmoothScrolling() {
const options = {
damping: 0.1,
alwaysShowTracks: true
};
const elements = document.querySelectorAll(".smooth-scrollbar");
for (const element of elements) {
Scrollbar.init(element, options);
}
}
if (!isTouchDevice()) {
initSmoothScrolling();
}
body {
margin: 0;
padding: 0;
}
.smooth-scrollbar {
overflow: auto;
}
.wrapper {
display: flex;
flex-direction: row;
}
.section {
width: 100vw;
height: 100vh;
flex-shrink: 0;
}
.section:nth-child(odd) {
background-color: #ccc;
}
.section:nth-child(even) {
background-color: #fff;
}
h2 {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: 200px;
margin: 0;
}
<main class="smooth-scrollbar">
<div class="wrapper">
<article class="section"><h2>01</h2></article>
<article class="section"><h2>02</h2></article>
<article class="section"><h2>03</h2></article>
<article class="section"><h2>04</h2></article>
<article class="section"><h2>05</h2></article>
<article class="section"><h2>06</h2></article>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smooth-scrollbar/8.5.3/smooth-scrollbar.js"></script>
我在 github 上发布了一个 API 可以轻松解决这个问题,您可以在下面找到执行所需操作的代码。
与你的相比,我刚刚在 HTML 中添加了 js 代码和 <script>
。
如果您想了解更多,here you can find the documentation。
编辑
由于要求发生了一些变化并且 API 已更新,我修改了下面的示例,使其更适合问题。
答案的主要变化:
- 现在 js 位于一个名为
onload
的 - css 样式已修改(
transform:rotate
停止大部分滚动 APIs) - 添加了对导航栏平滑滚动的支持
- 滚动量现在取决于用户实际滚动鼠标滚轮的程度
init()
方法中
/* UPDATED 2022 ANSWER */
function init() {
/*
* Variables preparation
*/
let yourWrapperElement = document.getElementsByClassName("outer-wrapper")[0];
let whateverEaseFunctionYouWant = remaningScrollDistance => { return remaningScrollDistance / 15 + 1 };
//Added support for navbar menu's smooth scrolling
uss.hrefSetup();
/*
* As you asked for, we only apply the custom scrolling for desktop devices
* by using the "wheel" event instead of the "scroll" or "touchmove" events.
*/
yourWrapperElement.addEventListener("wheel", event => {
/*
* We want to overwrite the default scrolling behaviour
* of your outer-wrapper component.
*/
event.preventDefault();
event.stopPropagation();
uss.scrollXBy(event.deltaY, yourWrapperElement, null, false);
}, {passive:false});
/*
* We apply a the custom ease function
* which will be used whenever our component is scrolled by the API
*/
uss.setXStepLengthCalculator(whateverEaseFunctionYouWant, yourWrapperElement);
}
body {
margin: 0;
padding: 0;
}
.outer-wrapper {
width: auto;
height: 100vh; /* Changed to vh */
width: 100vw; /* Added */
/*transform: rotate(-90deg) translateX(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
scrollbar-width: none;
-ms-overflow-style: none;
/*scroll-behavior: smooth; ISN'T NEEDED FOR MY API */
}
::-webkit-scrollbar {
display: none;
}
.wrapper {
display: flex;
flex-direction: row;
/*width: auto; NOT NEEDED IF WE USE FLEX-SHRINK 0
transform: rotate(90deg) translateY(-100vh); ROTATING containers brakes 90% of scrolling APIs
transform-origin: top left;*/
margin: 0; /* not really needed */
padding: 0; /* not really needed */
}
.section {
color: #000;
flex-shrink: 0; /* ADDED insted of the width/height of the wrapper */
width: 100vw;
height: 100vh;
}
#a { background-color: #ccc; }
#b { background-color: #fff; }
#c { background-color: #ccc; }
#d { background-color: #fff; }
#e { background-color: #ccc; }
#f { background-color: #fff; }
h2 {
text-align: center;
font-size: 200px;
margin: 0;
}
/* MENU _________________________ */
.logo {
float: left;
}
nav {
width: 100%;
}
/* HEADER */
header {
float: left;
width: 100%;
position: absolute;
z-index: 9999;
}
/* HEADER LARGE */
header.large {
height: 50px;
}
header.large .logo {
width: 225px;
height: 50px;
margin: 20px 0 0 20px;
background: url('../images/logo-fireqa-green-500px.png');
background-repeat: no-repeat;
background-size: contain;
transition: 0.7s all;
-moz-transition: 0.7s all;
-webkit-transition: 0.7s all;
-o-transition: 0.7s all;
}
/* UNORDERED LIST */
header.large ul {
list-style: none;
float: right;
margin-right: 25px;
}
header.small ul {
list-style: none;
float: right;
margin: 0;
}
header.large li {
display: inline;
float: left;
list-style-position: inside;
height: 50px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
transition: all 0.3s ease-in-out;
}
header.large li a {
display: block;
padding: 20px;
color: #0E6245;
text-decoration: none;
font-family: 'Montserrat', 'arial', sans-serif;
font-weight: 600 !important;
letter-spacing: -1px;
font-size: 25px;
background-image: linear-gradient(#0E6245, #0E6245);
background-position: 50% 80%;
background-repeat: no-repeat;
background-size: 0% 4px;
-moz-transition: all 0.3s ease-in-out 0s;
-ms-transition: all 0.3s ease-in-out 0s;
-o-transition: all 0.3s ease-in-out 0s;
-webkit-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
header.large li a:hover, a:focus {
background-size: 60% 4px;
}
<script src = "https://cdn.jsdelivr.net/npm/universalsmoothscroll@latest/universalsmoothscroll-min.js"></script>
<body onload = init()>
<main class="outer-wrapper">
<div class="wrapper">
<article class="section" id="a"><h2>01</h2></article>
<article class="section" id="b"><h2>02</h2></article>
<article class="section" id="c"><h2>03</h2></article>
<article class="section" id="d"><h2>04</h2></article>
<article class="section" id="e"><h2>05</h2></article>
<article class="section" id="f"><h2>06</h2></article>
</div>
</main>
<!-- MENU _____________________ -->
<header class="large">
<div class="container">
<nav>
<a><div class="logo"></div></a>
<ul>
<li><a href="#a">01</a></li>
<li><a href="#b">02</a></li>
<li><a href="#c">03</a></li>
<li><a href="#d">04</a></li>
</ul>
</nav>
</div>
</header>
</body>
</html>