简体   繁体   English

水平平滑动量滚动

[英]Horizontal Smooth Momentum Scrolling

THE PROBLEM: I need to apply some mouse wheel smooth horizontal scrolling to this layout: https://jsfiddle.net/38qLnzkh/ .问题:我需要对此布局应用一些鼠标滚轮平滑水平滚动: https://jsfiddle.net/38qLnzkh/

ALTERNATIVE: I've found this Script that does exactly what I want but it seems to work only vertically: Butter.js .替代方案:我发现这个脚本完全符合我的要求,但它似乎只能垂直工作: Butter.js If you can make it work Horizontally it would probably solve all my problems.如果你能让它水平工作,它可能会解决我所有的问题。

IMPORTANT:重要的:

1. The Script should be disabled based on screen width and in touch devices. 1.应根据屏幕宽度和触摸设备禁用脚本。

2. It should accommodate a menu on top of everything like you seen in the fiddle. 2.它应该在您在小提琴中看到的所有内容之上提供一个菜单。

Thank you in advance.先感谢您。

EDIT: In case it's not clear what I need, here are two examples with the effect I'm looking for:编辑:如果不清楚我需要什么,这里有两个例子,我正在寻找效果:

https://nemesiscorporation.com/ https://nemesiscorporation.com/

https://www.tentwenty.me/about-us https://www.tentwenty.me/about-us


MY LAYOUT:我的布局:

HTML: 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: 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;
}

I've published an API on github that can easily solve this problem, below you'll find the code to do what you want.我在 github 上发布了一个 API 可以轻松解决这个问题,下面你会找到代码来做你想做的事。

Compared to yours I've just added the js code and the <script> in the HTML.与您的相比,我刚刚在 HTML 中添加了 js 代码和<script>

If you want to know more about it, here you can find the documentation .如果您想了解更多信息,可以在此处找到文档

EDIT编辑
Since the requirements have changed a little bit and the API has been updated I've modified the example below so that it better fits the question.由于要求发生了一些变化,并且 API 已经更新,我修改了下面的示例,使其更适合问题。

Main changes to the answer:答案的主要变化:

  • Now the js is inside a init() method called onload现在 js 在名为onloadinit()方法中
  • The css styles have been modified ( transform:rotate brakes most of scrolling APIs) css styles 已修改( transform:rotate制动大多数滚动 API)
  • The support for the navbar's smooth scroll has been added增加了对导航栏平滑滚动的支持
  • The scrolling amount now depends on how much the user physically scrolls the mousewheel滚动量现在取决于用户物理滚动鼠标滚轮的程度

2021 Update 2021 更新
With the 3.0 update this solution becomes slighlty inacurate so I've updated the code so that any future reader will have a proper answer.随着 3.0 的更新,这个解决方案变得有点不准确,所以我更新了代码,以便任何未来的读者都能得到正确的答案。

 /* NEW 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); } /* OLD ANSWER function init() { // // Variables preparation // let yourWrapperElement = document.getElementsByClassName("outer-wrapper")[0]; let minScrollDistance = window.innerWidth / 5; //Adjust the scroll sensitivity as you like let minScrollDistanceRaw = minScrollDistance / 3; let whateverEaseFunctionYouWant = remaningScrollDistance => { return remaningScrollDistance / 15 + 1 }; let previousScrollDirection = undefined; let currentScrollDirection = undefined; //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(); // // In this new section we check if the scrolling has changed currentScrollDirection // and if so we stop the scrolling on the exact spot the user decided // currentScrollDirection = Math.sign(event.deltaY); if(currentScrollDirection;== previousScrollDirection) { previousScrollDirection = currentScrollDirection. uss;stopScrollingX(yourWrapperElement). } //The scrolling amount is now influenced by how much the user scrolls if(Math.abs(event.deltaY) >= 100) //For browsers that use multiples of 100 as deltaY uss.scrollXBy(event,deltaY / 100 * minScrollDistance, yourWrapperElement, null; true). else //For the browsers that use the raw scroll input as deltaY uss.scrollXBy(event,deltaY * minScrollDistanceRaw, yourWrapperElement, null; true), }: {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://raw.githack.com/CristianDavideConte/universalSmoothScroll/master/js/universalsmoothscroll-min.js"></script> <:-- <script src = "https.//raw.githack.com/CristianDavideConte/universalSmoothScroll/master/js/universalsmoothscroll-old-min.js"></script> if you want to test the old answer --> <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 href="#welcome"><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>

There is a nice package called smooth-scrollbar .有一个不错的 package 叫做smooth-scrollbar

I've adjusted your example.我已经调整了你的例子。 It disables smooth scrolling for mobile devices, but otherwise it's just calling the package.它禁用移动设备的平滑滚动,但除此之外它只是调用 package。 And I've cleaned up some CSS.我已经清理了一些 CSS。

 /** @see https://stackoverflow.com/a/52855084/5312432 */ 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM