简体   繁体   中英

Effect on horizontal scroll

I created this horizontal scroll using only CSS (working only on Chrome because of the scroll style).

 * { -webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Nunito', sans-serif; } ::-webkit-scrollbar { height: 0; width: 0; } ::-webkit-scrollbar-button { height: 0; width: 0; } h2 { margin: 0; } p { font-size: 1.25em; letter-spacing: 0.56px; line-height: 32px; } .container { background-color: #000; bottom: 0; height: 100vh; left: 0; margin: auto; position: absolute; right: 0; top: 0; width: 100vw; } .horScroll { background-color: #abc; height: 100vw; overflow-x: hidden; overflow-y: auto; position: absolute; -ms-scroll-snap-type: mandatory; scroll-snap-type: mandatory; -ms-scroll-snap-points-y: repeat(100vw); scroll-snap-points-y: repeat(100vw); -ms-scroll-snap-type: y mandatory; scroll-snap-type: y mandatory; -webkit-transform: translateX(-100%) rotate(-90deg); -ms-transform: translateX(-100%) rotate(-90deg); transform: translateX(-100%) rotate(-90deg); -webkit-transform-origin: top right; -ms-transform-origin: top right; transform-origin: top right; width: 100vh; } .item { background-color: #e4e4e4; height: 100vw; position: -webkit-sticky; position: sticky; scroll-snap-align: start; top: 0; width: 100vh; } .horScroll > div:nth-of-type(2n) { background-color: #333; color: #fff; } .item-inner { height: 100vh; max-height: 100vh; overflow: scroll; padding: 40px; -webkit-transform: rotate(90deg) translateX(-100vh); -ms-transform: rotate(90deg) translateX(-100vh); transform: rotate(90deg) translateX(-100vh); -webkit-transform-origin: bottom left; -ms-transform-origin: bottom left; transform-origin: bottom left; width: 100vw; } .item-content { height: 100%; }
 <div class="container"> <div class="horScroll"> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 1</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 2</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 3</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 4</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 5</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 6</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> </div> </div>

It works as expected. Now I'm trying to create an extra effect in JavaScript.

I want that when the next item is coming, there will be a change in opacity, scale or similar effect on the previous item showing that it is "fading out". It is a transition effect between two items. In this case I'm trying opacity.
In the reverse direction the opposite will happen: a "fade in" on the item that had disappeared.

Inside the forEach() loop I could identify what item is being scrolled at the moment (as you can check in the console.log ), but now I'm not getting the opacity calculation right. I have a few factors to consider like the current item and current scroll position.

var widthBase = window.innerWidth;
window.addEventListener("resize", function() {
  widthBase = window.innerWidth;
})

var items = document.querySelectorAll(".item");

document.querySelector(".horScroll").addEventListener("scroll", function(e) {

  items.forEach(function(item, i) {

    var currentScroll = e.target.scrollTop;

    if (currentScroll >= widthBase * (i) && currentScroll < widthBase * (i + 1)) {
      console.log("item index: " + i + ", scroll position: " + currentScroll);
      // item.querySelector(".item-content").style.opacity = ? // opacity calculation value
    }

  })

})

I've tried item.querySelector(".item-content").style.opacity = (widthBase * (i + 1))/currentScroll - 1 , but it works partially. Some other variations also failed. I'm missing something.

In addition, I think that a loop through all the items in each scroll is not performative, but I couldn't think of anything different.

I fixed the calculation. First, I had to consider this:

Top position of item is equal to 1 .
Bottom position of item is equal to 0.001 .
So, current scroll will be X , the value I need for each scroll.

1 and 0.001 are the opacity , transform: scale() or another property with value between 0 and 1.
It must be 0.001 instead of 0, otherwise the calculation will fail. "Top position" also must not be 0, so I will always add 1 to it.

计算 .

Now, using scale instead of opacity, the result would be:

"scale(" + (1 - (currentScroll-((widthBase * i) + 1))*(1-0.55)/(((widthBase * (i + 1)) + 1)-((widthBase * i) + 1))) + ")";

Working snippet:

 var widthBase = window.innerWidth; window.addEventListener("resize", function() { widthBase = window.innerWidth; }) var items = document.querySelectorAll(".item"); document.querySelector(".horScroll").addEventListener("scroll", function(e) { items.forEach(function(item, i) { var currentScroll = e.target.scrollTop; if (currentScroll > widthBase * (i) && currentScroll < widthBase * (i + 1)) { item.querySelector(".item-content").style.transform = "scale(" + (1 - (currentScroll-((widthBase * i) + 1))*(1-0.55)/(((widthBase * (i+1)) + 1)-((widthBase * i) + 1))) + ")"; } }) })
 * { -webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Nunito', sans-serif; } ::-webkit-scrollbar { height: 0; width: 0; } ::-webkit-scrollbar-button { height: 0; width: 0; } h2 { margin: 0; } p { font-size: 1.25em; letter-spacing: 0.56px; line-height: 32px; } .container { background-color: #000; bottom: 0; height: 100vh; left: 0; margin: auto; position: absolute; right: 0; top: 0; width: 100vw; } .horScroll { background-color: #abc; height: 100vw; overflow-x: hidden; overflow-y: auto; position: absolute; -ms-scroll-snap-type: mandatory; scroll-snap-type: mandatory; -ms-scroll-snap-points-y: repeat(100vw); scroll-snap-points-y: repeat(100vw); -ms-scroll-snap-type: y mandatory; scroll-snap-type: y mandatory; -webkit-transform: translateX(-100%) rotate(-90deg); -ms-transform: translateX(-100%) rotate(-90deg); transform: translateX(-100%) rotate(-90deg); -webkit-transform-origin: top right; -ms-transform-origin: top right; transform-origin: top right; width: 100vh; } .item { background-color: #e4e4e4; height: 100vw; position: -webkit-sticky; position: sticky; scroll-snap-align: start; top: 0; width: 100vh; } .horScroll > div:nth-of-type(2n) { background-color: #333; color: #fff; } .item-inner { height: 100vh; max-height: 100vh; overflow: scroll; padding: 40px; -webkit-transform: rotate(90deg) translateX(-100vh); -ms-transform: rotate(90deg) translateX(-100vh); transform: rotate(90deg) translateX(-100vh); -webkit-transform-origin: bottom left; -ms-transform-origin: bottom left; transform-origin: bottom left; width: 100vw; } .item-content { height: 100%; }
 <div class="container"> <div class="horScroll"> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 1</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 2</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 3</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 4</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 5</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> <div class="item"> <div class="item-inner"> <div class="item-content"> <h2>Item 6</h2> <div> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p> </div> </div> </div> </div> </div> </div>

Unfortunately, I didn't change the iteration on each scroll, which affects the performance a little bit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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