Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom scrolling animations - pausing sections and scrolling elements horizontally

There are some single page applications where a user can carry on vertically scrolling -- but the page looks paused and scrolls horizontally - and then clears a section.

  • https://color-of-the-year.com/
  • https://highline.huffingtonpost.com/articles/en/poor-millennials/
  • https://ascc.bornfight.com/
  • https://kubrick.life/clockwork11/

I am unsure though how they do this -- I've seen transform styles being applied but not really sure what happens to the elements that would have been there naturally if the user were to scroll normally.

I've added the jquery wayward function to detect when a nested spread is displayed.

Something like this:

enter image description here

Here is the HTML fragment. Slide 1 is a full page element, as is slide 5 and 6. These could be anchors to a menu. The behavior I am interested in creating here - is as the user approaches the nested unit - it locks at the top of slide 2, then transforms slides 3 and 4.

$win.on('scroll', function() {
  var top = $win.scrollTop() / 3;
  console.log("top", top);
  $nested.css('transform', 'translate(' + -top + 'px, 0)');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section">slide 1</div>
<div class="nested">
  <div class="section first">slide 2</div>
  <div class="section second">slide 3</div>
  <div class="section third">slide 4</div>
</div>
<div class="section">slide 5</div>
<div class="section">slide 6</div>

JSFiddle Example

like image 742
The Old County Avatar asked Mar 03 '23 19:03

The Old County


1 Answers

This is just to give you an idea how it can be achieved. You need a placeholder container that retains the vertical space when your slides become fixed elements.

The following code can handle multiple slides in the same page, you can also implement your own once you get the idea.

$('.nested').each(function() {
  let $window = $(window), $body = $('body');
  let $nested = $(this), $nestedPlaceholder = $nested.parent();
  let verticalScrollRange, upperMargin, lowerMargin;
  $window.resize(function(){
    $nested.removeClass("sticky").css({left: 0});
    let placeholderHeight = $nestedPlaceholder.css({height: ''}).height();
    verticalScrollRange = placeholderHeight - $window.height();
    upperMargin = $nestedPlaceholder.offset().top;
    lowerMargin = upperMargin + verticalScrollRange;
    $nestedPlaceholder.height(placeholderHeight);
  });
  $window.scroll(function() {
    let scrollTop = $window.scrollTop();
    if (scrollTop > upperMargin && scrollTop < lowerMargin) {
      $nested.addClass("sticky");
      let horizontalScrollRange = $nested.width() - $body.width();
      let verticalScrollPosition = scrollTop - upperMargin;
      let horizontalScrollPosition = verticalScrollPosition / verticalScrollRange * horizontalScrollRange;
      $nested.css({left: -horizontalScrollPosition});
    } else {
      $nested.removeClass("sticky");
    }
  });
  $window.resize();
});
body {
  background: linear-gradient(to bottom, #ffcb77 0%, #deaaff 100%);
}

.section {
  height: 100vh;
  font-size: 5em;
  text-align: center;
  position: relative;
  border: 1px solid red;
}

.nested .section {
  width: 100vw;
}

.nested-placeholder {
  overflow: hidden;
}

.sticky {
  position: fixed;
  z-index: 1;
  top: 0;
  height: 100vh;
  white-space: nowrap;
}

.sticky .section {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section">Start scrolling down!</div>
<div class="section">slide 1</div>
<div class="nested-placeholder">
  <div class="nested">
    <div class="section first">slide 2</div>
    <div class="section second">slide 3</div>
    <div class="section third">slide 4</div>
  </div>
</div>
<div class="section">slide 5</div>
<div class="section">slide 6</div>
like image 102
Munim Munna Avatar answered Mar 06 '23 09:03

Munim Munna