水平平滑动量滚动

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>