Search code examples
javascriptjqueryhtmlcssparallax

Parallax Scrolling (Inception Style) in Website Display Effects


I want to create one page website using a Parallax effect like this one: Parallax Effect. I did all my research but I didn't find any example explaining how to do it, or what is the name of this parallax effect. I really need help!

This effect zooms into the page on scroll, as shown in the GIF below.

enter image description here

Here's what I have so far:

html {
  height: 600vh;
  overflow: -moz-scrollbars-vertical;
  overflow-y: scroll;
}

body {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  position: fixed;
  align-items: center;
  justify-content: end;
}

#parent {
  padding: 0;
  margin: 0;
  height: 600vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  transform-style: preserve-3d;
  perspective: 250px;
}

.page {
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100vw;
  position: absolute;
  background: rgba(0, 0, 0, 0.1);
  text-align: center;
  box-shadow: inset 5px 5px red, inset -5px -5px red;
}

.page:nth-child(1) {
  transform: scale(1);
}

.page:nth-child(2) {
  bottom: -98%;
  transform: translate3d(0, 0, -500px);
}

.page:nth-child(3) {
  bottom: -196%;
  transform: translate3d(0, 0, -1000px);
}

.page:nth-child(4) {
  bottom: -294%;
  transform: translate3d(0, 0, -1500px);
}

.page:nth-child(5) {
  bottom: -392%;
  transform: translate3d(0, 0, -2000px);
}

.page:nth-child(6) {
  bottom: -490%;
  transform: translate3d(0, 0, -2500px);
}
<div id="parent">
  <div class="page">Page 1</div>
  <div class="page">Page 2</div>
  <div class="page">Page 3</div>
  <div class="page">Page 4</div>
  <div class="page">Page 5</div>
  <div class="page">Page 6</div>
</div>

I am stuck at the animation via JavaScript part: On body scroll the pages should scale to a maximum and then disappear one after the other, The next page page2 should take the place of page1 and so on. To make the scroll sticky, scroll-snap-type: y; can be used.


Solution

  • I'm not quite sure what you'd call this scrolling effect - scaling page scrolling? - but it can be achieved in modern browsers with the CSS scale transform and a little JavaScript.

    Style your page sections

    I stacked my sections on top of each other by giving them a position absolute and fixing their CSS coordinates.

    HTML:

    <section style="background-color: red;">
        <h1>This is section number one!!</h1>
    </section>
    
    <section style="background-color: blue;">
        <h1>This is section number two!!</h1>
    </section>
    

    CSS:

    html, body {
        position: relative;
        margin: 0;
        height: 100%;
        overflow: hidden;
    }
    
    section {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0; right: 0;
        top: 0; bottom: 0;
        text-align: center;
    }
    

    Set the initial scale of each section.

    I wanted each section to be one third the size of the previous section. This meant the scale of the first section would be 1; the scale of the second would be 1/3; the third would be 1/9, the fourth 1/27 and so on. Therefore, if n is the index number of each section, the sections should be scaled by (1/3)^n. Scaling the sections is quite easy with the CSS3 transform feature.

    JavaScript:

    document.addEventListener( 'DOMContentLoaded', function() {
        var sections = document.getElementsByTagName( 'section' ),
            i = 0;
        for ( i; i < sections.length; i++ ) {
            sections[i].style.transform = 'scale(' + Math.pow( 1/3, i ) + ')';
        }
    } );
    

    Alter the scale on scroll

    Since the page does not overflow we need to listen to the wheel event. We must also keep a variable consisting of how far we've scrolled between a minimum (0) and a maximum (I picked 1000; you can change sensitivity of the scroll with a larger or smaller value). When the wheel event occurs we find how much the user has scrolled from the event's deltaY property, adjust our scroll counter by that much, and scale our sections accordingly.

    To calculate how much we must scale each section is only a little more complex than calculating the initial scales. It's still a power of 1/3, although we must now subtract the scale multiplied by the total number of sections divided by the maximum counter value from our n.

    You might also like to use requestAnimationFrame for a smoother experience.

    JavaScript:

    var counter = 0,
        counter_max = 1000,
        total = document.getElementsByTagName( 'section' ).length;
    
    window.addEventListener( 'wheel', function( e ) {
        counter += e.deltaY;
        if ( counter > counter_max ) counter = counter_max;
        if ( counter < 0 ) counter = 0;
        requestAnimationFrame( applyScale );
    } );
    
    function applyScale() {
        var sections = document.getElementsByTagName( 'section' ),
            i = 0;
        for ( i; i < sections.length; i++ ) {
            var scale = Math.pow( 1/3, i - counter * total / counter_max );
            sections[i].style.transform = 'scale(' + scale + ')';
        }
    }
    

    Result

    A pen that implements the above may be found at https://codepen.io/jla-/pen/aMNgxy

    This should be a useful framework to get you started. Adding the anchors at the top of the page would involve a click listener that animates the counter variable to the appropriate value, calling the applyScale function on each animation frame.