// 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 @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; } } } } } } } $(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
// 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 @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; } } } } } } } $(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