Netflix Style Infinite Carousel With Vanilla JavaScript – netflix-slider

Category: Javascript , Slider | April 9, 2021
Author: trandrew96
Views Total: 1,413 views
Official Page: Go to website
Last Update: April 9, 2021
License: MIT

Preview:

Netflix Style Infinite Carousel With Vanilla JavaScript – netflix-slider

Description:

A Netflix-inspired infinite carousel slider written in vanilla JavaScript.

More Features:

  • Touch-enabled.
  • Navigation arrows.
  • Smooth hover effect.

How to use it:

1. Load the needed Font Awesome iconic font in the document.

<script src="https://kit.fontawesome.com/a0043d9bc2.js" crossorigin="anonymous"></script>

2. Build the HTML structure for the carousel slider.

<div class="container">
  <button type="button" id="moveLeft" class="btn-nav">
    ᐊ
  </button>
  <div class="container-indicators">
    <div class="indicator active" data-index=0></div>
    <div class="indicator" data-index=1></div>
    <div class="indicator" data-index=2></div>
  </div>
  <div class="slider" id="mySlider">
    <div class="movie" id="movie0">
      <img src="movie1.jpg" alt="" srcset="" />
      <div class="description">
        <div class="description__buttons-container">
          <div class="description__button"><i class="fas fa-play"></i></div>
          <div class="description__button"><i class="fas fa-plus"></i></div>
          <div class="description__button"><i class="fas fa-thumbs-up"></i></div>
          <div class="description__button"><i class="fas fa-thumbs-down"></i></div>
          <div class="description__button"><i class="fas fa-chevron-down"></i></div>
        </div>
        <div class="description__text-container">
          <span class="description__match">97% Match</span>
          <span class="description__rating">TV-14</span>
          <span class="description__length">2h 11m</span>
          <br><br>
          <span>Explosive</span>
          <span>&middot;</span>
          <span>Exciting</span>
          <span>&middot;</span>
          <span>Family</span>
        </div>
      </div>
    </div>
  </div>
  <button type="button" id="moveRight" class="btn-nav">
    ᐅ
  </button>
</div>

3. The necessary CSS/CSS3 styles.

:root {
  --movie-width: 15.5vw;
  --movie-height: 200px;
  --arrow-width: 50px;
  --slider-py: 200px;
}
@media only screen and (max-width: 1000px) {
  :root {
    --movie-width: 25vw;
  }
}

/*
*
* THE SLIDER CONTAINER
*
*********************************/
.slider {
  width: 100%;
  overflow-x: scroll;
  overflow-y: visible;
  white-space: nowrap;
  position: relative;
  padding-top: var(--slider-py);
  padding-bottom: var(--slider-py);
}

/*
*
* SLIDER INDICATORS
*
*********************************/
.container-indicators {
  width: 100px;
  position: absolute;
  right: 0;
  top: calc(var(--slider-py) - 60px);
  visibility: hidden;
}
.indicator {
  width: 15px;
  height: 2px;
  background-color: grey;
  display: inline-block;
}
.indicator.active {
  background-color: white;
}

/*
*
* MOVIE ELEMENTS!
*
*********************************/
.movie {
  width: var(--movie-width);
  height: var(--movie-height);
  display: inline-block;
  position: relative;
  color: white;
  padding: 0 2px;
  font-size: 0.8rem;
  transition: all 0.8s ease-in-out;
}

.movie:nth-of-type(1) {
  margin-left: var(--arrow-width);
}

.movie:hover {
  transform: scale(1.3);
  z-index: 2;
}

.movie img {
  object-fit: cover;
  height: 100%;
  width: 100%;
  border-radius: 10px;
}

.description {
  position: absolute;
  display: none;
  z-index: 9999;
  background-color: #272727;
  width: var(--movie-width);
  margin-top: -10px;
  padding: 10px 0;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}

/* Make description visible when movie is hovered */
.movie:hover > .description {
  display: block;
}

.movie:hover > img {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.description__buttons-container {
  display: flex;
  flex-direction: row;
  padding: 10px;
}

.description__text-container {
  padding: 10px;
}

.description__match {
  color: green;
}

.description__rating {
  outline: 1px solid white;
  padding: 0 3px;
  margin: 0 5px;
}

.description__button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 2px solid white;
  text-align: center;
  font-size: 8px;
  margin-right: 5px;
  border-radius: 100%;
}

.description__button:hover {
  border-color: grey;
  color: grey;
  cursor: pointer;
}

.description__button:nth-of-type(5) {
  margin-left: auto;
  margin-right: 0;
}

/*
*
* BUTTONS
*
*********************************/
.btn-nav {
  width: var(--arrow-width);
  height: var(--movie-height);
  border-radius: 5px;
  position: absolute;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.3);
  outline: none;
  border: none;
  color: white;
  top: var(--slider-py);
  z-index: 5;
  visibility: hidden;
}

#moveLeft {
  left: 0;
}

#moveRight {
  right: 0;
}

.container:hover .btn-nav,
.container:hover .container-indicators {
  visibility: visible;
}

4. The JavaScript to enable the carousel slider.

const slider = document.querySelector(".slider");
const btnLeft = document.getElementById("moveLeft");
const btnRight = document.getElementById("moveRight");
const indicators = document.querySelectorAll(".indicator");
let baseSliderWidth = slider.offsetWidth;
let activeIndex = 0; // the current page on the slider
let movies = [
  {
    src: "movie1.jpg",
  },
  {
    src: "movie2.jpg",
  },
  {
    src: "movie3.jpg",
  },
  // ...
];
// Fill the slider with all the movies in the "movies" array
function populateSlider() {
  movies.forEach((image) => {
    // Clone the initial movie thats included in the html, then replace the image with a different one
    const newMovie = document.getElementById("movie0");
    let clone = newMovie.cloneNode(true);
    let img = clone.querySelector("img");
    img.src = image.src;
    slider.insertBefore(clone, slider.childNodes[slider.childNodes.length - 1]);
  });
}
populateSlider();
populateSlider();
// delete the initial movie in the html
const initialMovie = document.getElementById("movie0");
initialMovie.remove();
// Update the indicators that show which page we're currently on
function updateIndicators(index) {
  indicators.forEach((indicator) => {
    indicator.classList.remove("active");
  });
  let newActiveIndicator = indicators[index];
  newActiveIndicator.classList.add("active");
}
// Scroll Left button
btnLeft.addEventListener("click", (e) => {
  let movieWidth = document.querySelector(".movie").getBoundingClientRect()
    .width;
  let scrollDistance = movieWidth * 6; // Scroll the length of 6 movies. TODO: make work for mobile because (4 movies/page instead of 6)
  slider.scrollBy({
    top: 0,
    left: -scrollDistance,
    behavior: "smooth",
  });
  activeIndex = (activeIndex - 1) % 3;
  console.log(activeIndex);
  updateIndicators(activeIndex);
});
// Scroll Right button
btnRight.addEventListener("click", (e) => {
  let movieWidth = document.querySelector(".movie").getBoundingClientRect()
    .width;
  let scrollDistance = movieWidth * 6; // Scroll the length of 6 movies. TODO: make work for mobile because (4 movies/page instead of 6)
  console.log(`movieWidth = ${movieWidth}`);
  console.log(`scrolling right ${scrollDistance}`);
  // if we're on the last page
  if (activeIndex == 2) {
    // duplicate all the items in the slider (this is how we make 'looping' slider)
    populateSlider();
    slider.scrollBy({
      top: 0,
      left: +scrollDistance,
      behavior: "smooth",
    });
    activeIndex = 0;
    updateIndicators(activeIndex);
  } else {
    slider.scrollBy({
      top: 0,
      left: +scrollDistance,
      behavior: "smooth",
    });
    activeIndex = (activeIndex + 1) % 3;
    console.log(activeIndex);
    updateIndicators(activeIndex);
  }
});

You Might Be Interested In:


One thought on “Netflix Style Infinite Carousel With Vanilla JavaScript – netflix-slider

  1. Ullrich Rentel

    Hi,
    a very nice slider! I want to use it in my online movie database. But I have not enough know-how in javascript. How I can change the description nodes of the “movie0” Element (expanding the array is not the problem)? Shoud I use a other element type for that?
    An other problem is, that I need to embed the whole slider in a div instead of an document. I get not the right positions of the nav buttons and the font type is not displayed.
    I have no idea…
    Sincerly,
    Ulli

    Reply

Leave a Reply