Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <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>
              
            
!

CSS

              
                *
  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)
              
            
!

JS

              
                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();
              
            
!
999px

Console