<div class="container" id="container">

        <div class="slide-container" id="slide-container">

            <div class="panel active green">
                <h1>Forest</h1>
                <div class="circle">
                    <img src="https://i.imgur.com/XdoDMOu.png" alt="">
                </div>
                <div class="circle-1"></div>
                <div class="circle-2"></div>
                <div class="circle-3"></div>
                <div class="background"></div>
                <canvas class="canvas"></canvas>

            </div>

            <div class="panel blue">
                <h1>Mountains</h1>
                <div class="circle">
                    <img src="https://i.imgur.com/UfpZnPA.png" alt="">
                </div>
                <div class="circle-1"></div>
                <div class="circle-2"></div>
                <div class="circle-3"></div>
                <div class="background"></div>
                <canvas class="canvas"></canvas>

            </div>

            <div class="panel purple">
                <h1>Rain</h1>
                <div class="circle">
                    <img src="https://i.imgur.com/8nLpgOM.png" alt="">
                </div>
                <div class="circle-1"></div>
                <div class="circle-2"></div>
                <div class="circle-3"></div>
                <div class="background"></div>
                <canvas class="canvas"></canvas>

            </div>

        </div>

        <div class="prev hide"> <a href="#"> &lsaquo; </a></div>
        <div class="next"> <a href="#"> &rsaquo; </a></div>

    </div>
*
  box-sizing: border-box


body    
    background: #dee0dd
    font-family: serif

a
    text-decoration: none;
    color: #eee;

.noselect
    -webkit-touch-callout: none
    -webkit-user-select: none
    -khtml-user-select: none
    -moz-user-select: none
    -ms-user-select: none
    user-select: none

circle(radius)
    border-radius: radius
    width: radius
    height: radius

.transitions
    -webkit-transition: transform 0.3s cubic-bezier(.76,.16,.19,.78)
    -o-transition: transform 0.3s cubic-bezier(.76,.16,.19,.78)
    transition: transform 0.3s cubic-bezier(.76,.16,.19,.78)

h1
    text-align: center
    color: #eee
    /*text-transform: uppercase*/
    padding: 15px 0
    font-weight: normal;
    -webkit-filter: blur(0.000001px);
    @extend .transitions

.panel-next h1
    transform: translate(-200%, 0)

.panel-prev h1
    transform: translate(200%,0)

.center
    position: absolute
    top: 50%
    left: 50%
    transform: translateX(-50%) translateY(-50%)

.container
    width: 540px
    height: 540px
    overflow: hidden
    background: #21313E
    @extend .center
      
.slide-container
    width: 400%
    height: 100%
    transform: translate(0, 0)
    position: relative
    will-change: transform

.circle-1
    circle(320px)
    z-index: 2
    transition-delay: 0.25s
    transition-duration: 0.55s
    @extend .center

.circle-2
    circle(280px)
    z-index: 3
    transition-delay: 0.2s
    transition-duration: 0.5s
    @extend .center

.circle-3
    circle(240px)
    z-index: 4
    transition-delay: 0.1s;
    transition-duration: 0.4s
    @extend .center

.circle
    circle(200px)
    background: #D06F79
    z-index: 5
    border: 4px solid #eee
    overflow: hidden
    @extend .center
    img
        margin: -4px 0 0 -4px


.panel
    &.active
        .circle-1
        .circle-2
        .circle-3
            transform: translate(-50%, -50%) scale(1)
            transition-timing-function: cubic-bezier(0.71, 0.13, 0.13, 1.4)

.circle-1
.circle-2
.circle-3
    transform: translate(-50%, -50%) scale(0)
    transition-delay: 0
    @extend .transitions


.canvas
    z-index: 4
    position: absolute
    @extend .center
    @extend .noselect

.background
    z-index: 4
    background: #eee
    position: absolute
    top: 50%
    width: 100%
    height: 50%

.next
.prev
    z-index: 6
    position: absolute
    top: 50%
    font-size: 4em
    transform: translate(0, -120%)
    font-family: serif
    @extend .transitions
    @extend .noselect

.next
    right: 15px
    &.hide
        transform: translate(200%, -120%)

.prev
    left: 15px
    &.hide
        transform: translate(-200%, -120%)

.panel
    display: inline-block
    width: 25%
    height: 100%
    float: left
    position: relative
    will-change: transform

color_set(color1, color2, color3, color4, color5, color6)
  /*background: color1*/
  .circle-1
    background: color2
  .circle-2
    background: color3
  .circle-3
    background: color4
  .circle
    background: color5
  /*.background
    border-bottom: 5px solid color6*/


.green
  color_set(#21313E, #24545F, #247B79, #39A287, #68CA8A, #A8EF85)

.blue
  color_set(#21313E, #314D5F, #416B81, #4F8BA4, #5BADC8, #66D0ED)

.purple
  color_set(#21313E, #40445A, #685573, #966587, #C77594, #F6869A)
View Compiled
const PI_TWO = Math.PI * 2;
const TO_DEG = 180 / Math.PI;
const TO_RAD = Math.PI / 180;

const $container = $('#container');
const $sliceContainer = $('#slide-container');

let nextPanelPosition = 0;
let panelIndex = 0;
let state = 'forward';
let start = 0;
let end = 0;
let barSize = 0;
let per = 0;

const $next = $('.next');
const $prev = $('.prev');

const panels = [];

const colors = [
    '#A8EF85',
    '#66D0ED',
    '#F6869A'
  ];

const tween = new TWEEN.Tween( {x: 0} )
        .to( { x: 25 }, 500 )
        .easing( TWEEN.Easing.Exponential.InOut )
        .onUpdate( function () {

          $sliceContainer.css('transform', `translate(-${this.x}%, 0)`);

        } ).onStart(function() {

          nextPanelPosition = Math.max(0, Math.min(50, nextPanelPosition))
          tween.to( { x: nextPanelPosition } );
          panelIndex = nextPanelPosition / 25 >> 0;
          app.loader.reset();
          app.loader.stop();

          checkNavigation();

          panels[panelIndex].container.addClass('active');
          panels[panelIndex].container.removeClass('panel-prev panel-next');

        }).onComplete(function(){

          app.loader.start();

        });

class Panel{
  constructor($element, index){

    this.container = $element;
    this.index = index;
    this.canvas = $element.children('canvas')[0];
    this.ctx = this.canvas.getContext('2d');
    this.color = colors[index];

    this.canvas.width = 540;
    this.canvas.height = 210;

  }
}

$('.panel').forEach(function(item, index){

  panels[index] = new Panel($(item), index)

});

$(window).on('resize', function(){

  for (let i = 0; i < panels.length; i++) {
    panels[i].canvas.width = panels[i].container.width();
  };

});

function checkNavigation(){
  if(panelIndex == 0){
    $prev.addClass('hide');
  } else {
    $prev.removeClass('hide');
  }

  if(panelIndex == panels.length - 1){
    $next.addClass('hide');
  } else {
    $next.removeClass('hide');
  }
}


function next(){
  tween.stop();
  panels[panelIndex].container.removeClass('active');
  panels[panelIndex].container.addClass('panel-next');
  nextPanelPosition += 25;
  tween.start();
  state = 'forward';
}

function prev(){
  tween.stop();
  panels[panelIndex].container.removeClass('active');
  panels[panelIndex].container.addClass('panel-prev');
  nextPanelPosition -= 25;
  tween.start();
  state = 'back';
}

$next.on('click', next);
$prev.on('click', prev);

class Loader{

  constructor(){
    var self = this;
    /*
    * Percentage in float numbers
    */
    this.percentage = 0;

    this.radialPercentage = 0;

    this.pause = false;

    this.tween =  new TWEEN.Tween( {percentage: 0} )
        .to( { percentage: 1 }, 5000 )
        .easing( TWEEN.Easing.Circular.In )
        .onUpdate( function () {

          self.percentage = this.percentage;

        } ).onStart(function() {

          this.percentage = 0;

        }).onComplete(function(){

          if(panelIndex == 0) state = 'forward';
          if(panelIndex == panels.length - 1) state = 'back';

          if(state == 'forward') {
            next();
            return false;
          };

          prev();

        });

    this.tween.start();

  }

  setPercentage(percentage = 0){
    this.percentage = percentage;
  }

  reset(){

    this.percentage = 0;
    this.radialPercentage = 0;

  }

  start(){
    this.pause = false;
    this.tween.start();
  }

  stop(){
    this.pause = true;
    this.tween.stop();
  }

}

class APP{
  constructor(){

    this.loader = new Loader();

    //set the right size on start
    for (let i = 0; i < panels.length; i++) {
      panels[i].canvas.width = panels[i].container.width();
    };

    requestAnimationFrame(this.step.bind(this));

  }

  update(){

    start = (panels[panelIndex].canvas.width / 2) - 100;
    end = (panels[panelIndex].canvas.width / 2) + 100;
    barSize = (panels[panelIndex].canvas.width * this.loader.percentage) - start;
    per = ((barSize) / (end - start));

    this.loader.radialPercentage = (per);

  }

  draw(){


    panels[panelIndex].ctx.save();
    panels[panelIndex].ctx.strokeStyle = panels[panelIndex].color;
    panels[panelIndex].ctx.fillStyle = panels[panelIndex].color;
    panels[panelIndex].ctx.fillRect(0, (panels[panelIndex].canvas.height / 2) - 2, panels[panelIndex].canvas.width * this.loader.percentage, 4);

    panels[panelIndex].ctx.translate(panels[panelIndex].canvas.width / 2, panels[panelIndex].canvas.height / 2);
    panels[panelIndex].ctx.rotate(180 * TO_RAD);
    panels[panelIndex].ctx.translate(-(panels[panelIndex].canvas.width / 2), -(panels[panelIndex].canvas.height / 2));

    panels[panelIndex].ctx.lineWidth = 4;
    panels[panelIndex].ctx.beginPath();
    panels[panelIndex].ctx.arc(panels[panelIndex].canvas.width / 2, panels[panelIndex].canvas.height / 2, 102, 0, (Math.PI) * Math.max(0, Math.min(1, this.loader.radialPercentage)), false);
    panels[panelIndex].ctx.stroke();

    panels[panelIndex].ctx.beginPath();
    panels[panelIndex].ctx.globalCompositeOperation = 'destination-out';
    panels[panelIndex].ctx.arc(panels[panelIndex].canvas.width / 2, panels[panelIndex].canvas.height / 2, 100, 0, PI_TWO, false);
    panels[panelIndex].ctx.closePath();
    panels[panelIndex].ctx.fill();

    panels[panelIndex].ctx.restore();


  }

  step(){
    requestAnimationFrame(this.step.bind(this));

    var delta = Date.now() - this.lastTick;
    this.lastTick = Date.now();

    var dt = delta / 1000;

    this.elapsed = dt;

    TWEEN.update();

    panels[panelIndex].ctx.clearRect(0,0,panels[panelIndex].canvas.width, panels[panelIndex].canvas.height);

    this.update();

    this.draw();

  }

}

const app = new APP();
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/zepto/1.1.4/zepto.min.js
  2. https://cdn.rawgit.com/EduardoLopes/parallax-scroll-experiment/gh-pages/js/vendor/Tween.js