Vanilla JS Carousel
Last active
October 1, 2020 21:02
-
-
Save GGrassiant/8428cb8ae9919aab628949943af84ba2 to your computer and use it in GitHub Desktop.
Vanilla JS Carousel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <title>Hero Slider</title> | |
| <link rel="stylesheet" href="style/style.css" /> | |
| <link | |
| href="https://fonts.googleapis.com/css?family=Chivo" | |
| rel="stylesheet" | |
| /> | |
| </head> | |
| <body> | |
| <div> | |
| <div id="wbn-slider" > | |
| <div class="wbn-slide"> | |
| <img src="img/slide1_unsplash.jpg" /> | |
| </div> | |
| <div class="wbn-slide"> | |
| <img src="img/slide2_unsplash.jpg" /> | |
| <div class="wbn-overlay-text"> | |
| <span class="wbn-header">HEADER TEST</span> | |
| <span class="wbn-text"> | |
| Fusce pellentesque dui blandit, tristique lectus id, pulvinar lacus. | |
| Suspendisse potenti. Aliquam in varius magna. Sed eleifend suscipit | |
| eros, non consectetur enim varius quis. Sed semper semper lacus nec | |
| porttitor. | |
| </span> | |
| </div> | |
| </div> | |
| <div class="wbn-slide active"><img src="img/slide3_unsplash.jpg" /></div> | |
| <div class="wbn-slide"><img src="img/slide4_unsplash.jpg" /></div> | |
| <div class="wbn-slide"><img src="img/slide5_unsplash.jpg" /></div> | |
| <div class="wbn-buttons"> | |
| <div class="wbn-slider-back-btn"> | |
| <span>◀</span> | |
| </div> | |
| <div class="wbn-slider-next-btn"> | |
| <span>▶</span> | |
| </div> | |
| </div> | |
| <div id="dots-container"></div> | |
| </div> | |
| </div> | |
| <!-- Import the Slider --> | |
| <script src="src/wbn-slider.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| #wbn-slider { | |
| position: relative; | |
| height: 50vw; | |
| overflow: hidden; | |
| } | |
| .wbn-slide { | |
| position: absolute; | |
| width: 100%; | |
| z-index: 500; | |
| height: 50vw; | |
| } | |
| .wbn-slide img { | |
| object-fit: cover; | |
| width: 100%; | |
| pointer-events: none; | |
| } | |
| .active { | |
| z-index: 1000; | |
| } | |
| .slideInLeft { | |
| animation-name: animateInLeft; | |
| z-index: 1000; | |
| } | |
| .slideInRight { | |
| animation-name: animateInRight; | |
| z-index: 1000; | |
| } | |
| .slideOutLeft { | |
| transform: translateX(-100%); | |
| } | |
| .slideOutRight { | |
| transform: translateX(100%); | |
| } | |
| @keyframes animateInLeft { | |
| 0% { | |
| transform: translateX(-100%); | |
| } | |
| 100% { | |
| transform: translateX(0%); | |
| } | |
| } | |
| @keyframes animateInRight { | |
| 0% { | |
| transform: translateX(100%); | |
| } | |
| 100% { | |
| transform: translateX(0%); | |
| } | |
| } | |
| .wbn-buttons { | |
| position: absolute; | |
| display: flex; | |
| flex-direction: row; | |
| justify-content: space-between; | |
| align-items: center; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 20000; | |
| } | |
| .wbn-slider-back-btn, | |
| .wbn-slider-next-btn { | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| background: #fff; | |
| font-size: 20px; | |
| opacity: 0.7; | |
| border-radius: 50px; | |
| width: 50px; | |
| height: 50px; | |
| transition: all 0.2s; | |
| margin: 20px; | |
| } | |
| .wbn-slider-back-btn:hover, | |
| .wbn-slider-next-btn:hover { | |
| transform: scale(1.1); | |
| opacity: 0.8; | |
| cursor: pointer; | |
| } | |
| .wbn-overlay-text { | |
| position: absolute; | |
| display: flex; | |
| display: -ms-flexbox; | |
| display: -webkit-flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| width: 100%; | |
| height: 100%; | |
| color: white; | |
| top: 0; | |
| left: 0; | |
| z-index: 10000; | |
| opacity: 1; | |
| } | |
| .wbn-overlay-text .wbn-header { | |
| font-family: 'Chivo', sans-serif; | |
| font-size: 80px; | |
| font-weight: 800; | |
| } | |
| .wbn-overlay-text .wbn-text { | |
| font-family: Arial, Helvetica, sans-serif; | |
| text-align: center; | |
| font-size: 22px; | |
| line-height: 30px; | |
| color: white; | |
| max-width: 30%; | |
| } | |
| #dots-container { | |
| position: absolute; | |
| bottom: 5%; | |
| left: 40%; | |
| width: 20%; | |
| z-index: 1001; | |
| display: flex; | |
| height: 2rem; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .dot-element { | |
| height: 2rem; | |
| width: 2rem; | |
| border-radius: 1rem; | |
| background-color: aquamarine; | |
| opacity: 0.5; | |
| transition: background-color 0.3s ease-in-out; | |
| } | |
| .active-dot { | |
| background-color: red; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| document.addEventListener('DOMContentLoaded', () => { | |
| // CHANGE ONLY THIS | |
| const SLIDE_TIME = 500; //ms | |
| // -------------------------- | |
| // Buttons | |
| const backButton = document.querySelector('.wbn-slider-back-btn'); | |
| const forwardButton = document.querySelector('.wbn-slider-next-btn'); | |
| // Select all slides and convert node to array for easy handling | |
| // const allSlides = Array.from(document.querySelectorAll('.wbn-slide')); | |
| const allSlides = [...document.querySelectorAll('.wbn-slide')]; | |
| // create progress dots | |
| const dotsContainer = document.getElementById('dots-container'); | |
| allSlides.forEach(() => { | |
| const dotElement = document.createElement('div'); | |
| dotElement.classList.add('dot-element'); | |
| dotsContainer.appendChild(dotElement); | |
| }); | |
| const allDots = document.querySelectorAll('.dot-element'); | |
| // Helpers for active and newly active slides | |
| let active; | |
| const getActive = () => { | |
| return document.querySelector('.active'); | |
| } | |
| const getCurrentActiveIndex = () => { | |
| return allSlides.indexOf(active); | |
| } | |
| let newActive = null; | |
| const getNewActive = () => { | |
| const activeSlideIndex = getCurrentActiveIndex(); | |
| return allSlides[(activeSlideIndex - 1 + allSlides.length) % allSlides.length]; | |
| } | |
| const getCurrentNewActiveIndex = () => { | |
| return allSlides.indexOf(newActive); | |
| } | |
| // Helpers to disable the arrows | |
| let clickable = true; | |
| function initSlider() { | |
| active = getActive(); | |
| allSlides.forEach((slide) => { | |
| // Set the CSS transition on the slides to the value we specified in SLIDE_TIME above | |
| slide.setAttribute( | |
| 'style', | |
| `transition: transform ${SLIDE_TIME}ms ease; | |
| animation-duration: ${SLIDE_TIME}ms`, | |
| ); | |
| // Add css transitions | |
| slide.addEventListener('transitionstart', _e => { | |
| allDots[getCurrentActiveIndex()].classList.remove('active-dot'); | |
| allDots[getCurrentNewActiveIndex()].classList.add('active-dot'); | |
| }); | |
| slide.addEventListener('transitionend', _e => { | |
| // Check for the old active transition and if clickable is false | |
| // to not trigger it more than once | |
| if (slide === active && !clickable) { | |
| clickable = true; | |
| // Remove all CSS animation classes on old active | |
| active.className = 'wbn-slide'; | |
| } | |
| }); | |
| }); | |
| // Fist launch of the slider | |
| if (allDots) { | |
| allDots[getCurrentActiveIndex()].classList.add('active-dot'); | |
| } | |
| } | |
| function changeSlide(forward) { | |
| if (clickable) { | |
| clickable = false; | |
| active = getActive(); | |
| const activeSlideIndex = getCurrentActiveIndex(); | |
| if (forward) { | |
| newActive = allSlides[(activeSlideIndex + 1) % allSlides.length]; | |
| active.classList.add('slideOutLeft'); | |
| newActive.classList.add('slideInRight', 'active'); | |
| } else { | |
| newActive = getNewActive(); | |
| active.classList.add('slideOutRight'); | |
| newActive.classList.add('slideInLeft', 'active'); | |
| } | |
| } | |
| } | |
| //Event listeners | |
| forwardButton.addEventListener('click', () => { | |
| changeSlide(true); | |
| }); | |
| backButton.addEventListener('click', () => { | |
| changeSlide(false); | |
| }); | |
| // Init the slider | |
| initSlider(); | |
| }); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on https://github.com/weibenfalk/vanilla-js-slider-starter-files