// A set of walkthrough screens in HTML/CSS/JS. A personal experiment with layering images, CSS3 transitions, & flexbox. 

%button.open-walkthrough Start
.walkthrough.show.reveal
  .walkthrough-pagination
    %a.dot.active
    %a.dot
    %a.dot
    %a.dot
    %a.dot
  .walkthrough-body
    %ul.screens.animate

      %li.screen.active
        .media.logo
          %img.logo{src: "https://s3.amazonaws.com/jebbles-codepen/icon.png"}
        %h3
          Product Intro
          %br Walkthrough
        %p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

      %li.screen
        .media.books
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/book_icon_1.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/book_icon_2.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/book_icon_3.png"}
        %h3
          Data and File
          %br Management
        %p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

      %li.screen
        .media.bars
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/bar_icon_axis.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/bar_icon_3.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/bar_icon_2.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/bar_icon_1.png"}

        %h3
          Analytics
          %br and Metrics
        %p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

      %li.screen
        .media.files
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/file_icon_1.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/file_icon_2.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/file_icon_3.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/file_icon_4.png"}
        %h3
          Reporting
          %br and Insights
        %p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

      %li.screen
        .media.comm
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/comm_icon_1.png"}
          %img.icon{src: "https://s3.amazonaws.com/jebbles-codepen/comm_icon_2.png"}
        %h3
          Communications
          %br Tools
        %p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

    %button.prev-screen
      %i.icon-angle-left
    %button.next-screen
      %i.icon-angle-right

  .walkthrough-footer
    %button.button.next-screen Next
    %button.button.finish.close{disabled: "true"} Finish
View Compiled

@mixin material-shadow() {
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.23), 0 10px 40px rgba(0, 0, 0, 0.19);
}
$module-font-size: 14px;
$bezier: cubic-bezier(.25,.8,.25,1);

body {
  color: white;
  font-family: "Lato";
  font-weight: light;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: linear-gradient(150deg, #e6d3f9 0%, #e6d3f9 50%, #cea0f1 50%, #cea0f1 100%);
}

.open-walkthrough {
  border: 0;
  background: #5da3f2;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  font-size: 12px;
  height: 40px;
  width: 120px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -20px;
  margin-left: -60px;
}

// =================================================================================================
// Walkthrough
// =================================================================================================
.walkthrough {
  @include material-shadow();
  background: linear-gradient(to right bottom, #9e66c6 , #6027e1);
  border-radius: 0;
  display: none;
  flex-direction: column;
  flex: 0 0 auto;
  font-size: $module-font-size;
  height: 464px;
  overflow: hidden;
  transition: opacity 0.4s $bezier, transform 0.4s $bezier, box-shadow 0.4s $bezier;
  width: 280px;
  z-index: 1000;

  &.show {
    display: flex;
    opacity: 0;
    transform: translateY(72px);
  }

  &.reveal {
    opacity: 1;
    transform: translateY(0);
  }

  .walkthrough-body {
    align-items: center;
    display: flex;
    flex: 1;
    text-align: center;

    .prev-screen,
    .next-screen {
      align-self: stretch;
      background: none;
      border: 0;
      margin-top: 40px;
      color: rgba(white, 0.25);
      cursor: pointer;
      flex: 0 0 auto;
      font-size: 24px;
      opacity: 1;
      outline: none;
      padding: 16px;
      transform: scale(1);
      transition: transform 0.4s $bezier, color 0.4s $bezier, opacity 0.4s $bezier;
      z-index: 1000;

      &:hover,
      &:active {
        color: white;
        transform-origin: center;
        transform: scale(1.25);
      }

      &:disabled {
        opacity: 0;
      }
    }

    .prev-screen {
      order: 1;
    }

    .next-screen {
      order: 3;
    }

    .screens {
      flex: 1;
      align-self: stretch;
      position: relative;
      margin: 0 -16px;
      padding: 0;
      order: 2;

      .screen {
        position: absolute;
        list-style-type: none;
      }
    }

    .media {
      background: rgba(white, 0.25);
      border-radius: 132px;
      height: 132px;
      margin: 32px auto;
      width: 132px;
    }

    h3 {
      font-size: 15px;
      line-height: 1.4em;
      text-transform: uppercase;
      letter-spacing: 0.15em;
    }

    p {
      line-height: 1.6em;
      font-size: 13px;
      margin-top: 16px;
      padding-top: 0;
      color: rgba(white, 0.8);
    }
  }

  .walkthrough-pagination {
    align-items: center;
    display: flex;
    justify-content: center;
    margin-top: 24px;

    .dot {
      background: rgba(black, 0.25);
      border-radius: 8px;
      height: 8px;
      margin: 0 4px;
      transform: scale(0.75);
      transition: transform 0.4s $bezier, background 0.4s $bezier;
      width: 8px;

      &.active {
        background: white;
        transform: scale(1);
        transition-delay: 0.4s;
      }
    }
  }

  .walkthrough-footer {
    display: flex;
    flex: 0 0 auto;
    justify-content: space-around;
    padding: 0;

    button {
      height: 40px;
      border: 0;
      background: #5da3f2;
      font-weight: bold;
      text-transform: uppercase;
      letter-spacing: 0.15em;
      border-radius: 0;
      color: white;
      flex: 1;
      font-size: 12px;
      margin: 0;
      outline: 0;
      padding: 12px;
      transition: opacity 0.4s $bezier, background 0.4s $bezier;
      cursor: pointer;
      &:hover {
        background: lighten(#5da3f2, 3%);
      }
      &:active {
        background: #5da3f2;
      }

      &:disabled {
        cursor: pointer;
      }

      &.finish {
        background: #3e94f5;
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        opacity:0;
        transform: scale(0, 1);
        transform-origin: center;
        transition: opacity 0.4s $bezier, background 0.4s $bezier, transform 0.4s $bezier;
        &:hover {
          background: lighten(#3e94f5, 3%);
        }
        &:active {
          background: #3e94f5;
        }
        &.active {
          transform: scale(1, 1);
          opacity: 1;
        }
      }
    }
  }

  //Animation styles

  .screens {
    margin: 0;

    .media {
      .status-badge {
        left: 136px;
        opacity: 0;
        position: absolute;
        top: 104px;
        transform: scale(0);
        transition: opacity 0.4s $bezier, transform 0.4s $bezier;
        transition-delay: 0.6s;

        i {
          display: inline;
        }
      }

      &.logo {
        .logo {
          margin-top: 20px;
          opacity: 0;
          transform: translateY(-60px);
          transition: opacity 0.4s $bezier, transform 0.4s $bezier;
          width: 80px;
        }
      }
      .icon {
        position: absolute;
        opacity: 0;
        transform: translateY(-30px);
        transition: opacity 0.4s $bezier, transform 0.4s $bezier;
        width: 132px;
        left: 48px;
        top: 32px;
      }
      &.bars {
        .icon {
          transform: translate(40px, 20px);
          &:nth-of-type(2) {
            transform: scale(0.25);
            transform-origin: 30% 54%;
          }
          &:nth-of-type(3) {
            transform: scale(0.25);
            transform-origin: 30% 40%;
          }
          &:nth-of-type(4) {
            transform: scale(0.25);
            transform-origin: 30% 26%;
          }
        }
      }
      &.files {
        .icon {
          transform: translate(40px, 20px);
        }
      }
      &.comm {
        .icon {
          transform: scale(0.25);
          transform-origin: 29% 73%;

          &:nth-child(2) {
          transform-origin: 66% 85%;
          }
        }
      }
    }

    .screen {
      opacity: 0;
      position: absolute;
      transform: translateX(-72px);
      transition: all 0.4s $bezier;

      &.active {
        opacity: 1;
        transform: translateX(0) scale(1);
        transition-delay: 0.4s;

        ~ .screen {
          opacity: 0;
          transform: translateX(72px);
        }

        .media {
          .status-badge {
            opacity: 1;
            transform: scale(1.75);
          }

          &.logo {

            .logo {
              opacity: 0.8;
              transform: translateY(0);
              transition-delay: 0.6s;
            }

            .status-badge {
              transition-delay: 1s;
            }
          }

          &.books {
            .icon {
              opacity: 1;
              transform: translateY(0);
              transition-delay: 0.6s;
              &:nth-child(2) {
                transition-delay: 0.725s;
              }
              &:nth-child(3) {
                transition-delay: 0.850s;
              }
            }
            .status-badge {
              transition-delay: 1.4s;
            }
          }

          &.bars {
            .icon {
              opacity: 1;
              transform: translate(0) scale(1);
              transition-delay: 0.6s;
              &:nth-child(2) {
                transition-delay: 1.050s;
              }
              &:nth-child(3) {
                transition-delay: 0.925s;
              }
              &:nth-child(4) {
                transition-delay: 0.8s;
              }
            }
          }
          &.files {
            .icon {
              opacity: 1;
              transform: translateY(0);
              transition-delay: 0.9s;
              &:nth-child(3) {
                transition-delay: 0.8s;
              }
              &:nth-child(2) {
                transition-delay: 0.7s;
              }
              &:nth-child(1) {
                transition-delay: 0.6s;
              }
            }
            .status-badge {
              transition-delay: 1.6s;
            }
          }
          &.comm {
            .icon {
              opacity: 1;
              transform: scale(1);
              transition-delay: 0.6s;
              &:nth-child(2) {
                transition-delay: 0.8s;
              }
            }
            .status-badge {
              transition-delay: 1.6s;
            }
          }
        }
      }
    }
  }
}
View Compiled
$(document).ready ->
  walkthrough =
    index: 0
    
    nextScreen: ->
      if @index < @indexMax()
        @index++
        @updateScreen()

    prevScreen: ->
      if @index > 0
        @index--
        @updateScreen()
        
    updateScreen: ->
      @reset()
      @goTo @index
      @setBtns()
      
    setBtns: ->
      $nextBtn = $('.next-screen')
      $prevBtn = $('.prev-screen')
      $lastBtn = $('.finish')
      
      if walkthrough.index == walkthrough.indexMax()
        $nextBtn.prop('disabled', true);
        $prevBtn.prop('disabled', false);
        $lastBtn.addClass('active').prop('disabled', false);
        
      else if walkthrough.index == 0
        $nextBtn.prop('disabled', false)
        $prevBtn.prop('disabled', true)
        $lastBtn.removeClass('active').prop('disabled', true)
        
      else
        $nextBtn.prop('disabled', false)
        $prevBtn.prop('disabled', false)
        $lastBtn.removeClass('active').prop('disabled', true)


    goTo: (index) ->
      $('.screen').eq(index).addClass 'active'
      $('.dot').eq(index).addClass 'active'

    reset: ->
      $('.screen, .dot').removeClass 'active'

    indexMax: ->
      $('.screen').length - 1

    closeModal: ->
      $('.walkthrough, .shade').removeClass('reveal')
      setTimeout (=>
        $('.walkthrough, .shade').removeClass('show')
        @index = 0
        @updateScreen()
      ), 200

    openModal: ->
      $('.walkthrough, .shade').addClass('show')
      setTimeout (=>
        $('.walkthrough, .shade').addClass('reveal')
      ), 200
      @updateScreen()

  $('.next-screen').click ->
    walkthrough.nextScreen()

  $('.prev-screen').click ->
    walkthrough.prevScreen()

  $('.close').click ->
    walkthrough.closeModal()
    
  $('.open-walkthrough').click ->
    walkthrough.openModal()
    
  walkthrough.openModal()
 
  # Optionally use arrow keys to navigate walkthrough
  $(document).keydown (e) ->
    switch e.which
      when 37
        # left
        walkthrough.prevScreen()
      when 38
        # up
        walkthrough.openModal()
      when 39
        # right
        walkthrough.nextScreen()
      when 40
        # down
        walkthrough.closeModal()
      else
        return
    e.preventDefault()
    return
View Compiled

External CSS

  1. https://fonts.googleapis.com/css?family=Lato:700,300
  2. //netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css
  3. https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css

External JavaScript

  1. https://code.jquery.com/jquery-1.12.0.min.js