見出し画像

【Keen Slider】サムネイル付きのスライドショーで、サムネイルにナビゲーションをつけて、メイン画像はループさせる

以下のようなスライドショーを、Keen Sliderで実現します。

メイン画像はループさせます。

HTML

<div id="my-keen-slider" class="keen-slider">
  <div class="keen-slider__slide"><img src="assets/images/slide01.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide02.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide03.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide04.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide05.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide06.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide07.jpg" alt=""></div>
  <div class="keen-slider__slide"><img src="assets/images/slide08.jpg" alt=""></div>
</div>
<div class="thumbnail-items">
  <div id="thumbnails" class="keen-slider thumbnail">
      <div class="keen-slider__slide"><img src="assets/images/slide01.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide02.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide03.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide04.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide05.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide06.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide07.jpg" alt=""></div>
      <div class="keen-slider__slide"><img src="assets/images/slide08.jpg" alt=""></div>
      <svg id="arrow-left" class="arrow arrow--left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
          <path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"></path>
      </svg>
      <svg id="arrow-right" class="arrow arrow--right" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
          <path d="M5 3l3.057-3 11.943 12-11.943 12-3.057-3 9-9z"></path>
      </svg>
  </div>
</div>

CSS

.arrow {
width: 30px;
height: 30px;
position: absolute;
top: 50%;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
fill: #000;
cursor: pointer;
z-index: 50;
}

.arrow--left {
left: 5px;
}

.arrow--right {
left: auto;
right: 5px;
}

.arrow--disabled {
fill: rgba(255, 255, 255, 0.5);
}

.thumbnail-items {
position: relative;
overflow: hidden;
}

JS

function ThumbnailPlugin(main) {
  return (slider) => {
    function removeActive() {
      slider.slides.forEach((slide) => {
        slide.classList.remove("active")
      })
    }
    function addActive(idx) {
      slider.slides[idx].classList.add("active")
    }

    function addClickEvents() {
      slider.slides.forEach((slide, idx) => {
        slide.addEventListener("click", () => {
          main.moveToIdx(idx)
        })
      })
    }

    slider.on("created", () => {
      addActive(slider.track.details.rel)
      addClickEvents()
      main.on("animationStarted", (main) => {
        removeActive()
        const next = main.animator.targetIdx || 0
        addActive(main.track.absToRel(next))
        slider.moveToIdx(next)
      })
    })

    //矢印
    let wrapper, arrowLeft, arrowRight

    function markup(remove) {
      wrapperMarkup(remove)
      arrowMarkup(remove)
    }

    function removeElement(elment) {
      elment.parentNode.removeChild(elment)
    }
    function createDiv(className) {
      var div = document.createElement("div")
      var classNames = className.split(" ")
      classNames.forEach((name) => div.classList.add(name))
      return div
    }

    function arrowMarkup(remove) {
      if (remove) {
        removeElement(arrowLeft)
        removeElement(arrowRight)
        return
      }
      arrowLeft = createDiv("arrow arrow--left")
      arrowLeft.addEventListener("click", () => slider.prev())
      arrowRight = createDiv("arrow arrow--right")
      arrowRight.addEventListener("click", () => slider.next())

      wrapper.appendChild(arrowLeft)
      wrapper.appendChild(arrowRight)
    }

    function wrapperMarkup(remove) {
      if (remove) {
        var parent = wrapper.parentNode
        while (wrapper.firstChild)
          parent.insertBefore(wrapper.firstChild, wrapper)
        removeElement(wrapper)
        return
      }
      wrapper = createDiv("navigation-wrapper")
      slider.container.parentNode.appendChild(wrapper)
      wrapper.appendChild(slider.container)
    }

    function updateClasses() {
      var slide = slider.track.details.rel
      slide === 0
        ? arrowLeft.classList.add("arrow--disabled")
        : arrowLeft.classList.remove("arrow--disabled")
      slide === slider.track.details.slides.length - 1
        ? arrowRight.classList.add("arrow--disabled")
        : arrowRight.classList.remove("arrow--disabled")
    }

    slider.on("created", () => {
      markup()
      updateClasses()
    })
    slider.on("optionsChanged", () => {
      console.log(2)
      markup(true)
      markup()
      updateClasses()
    })
    slider.on("slideChanged", () => {
      updateClasses()
    })
    slider.on("destroyed", () => {
      markup(true)
    })
    //矢印ここまで
  }
}
var slider = new KeenSlider(
  "#my-keen-slider",
  {
    loop: true,
  },
  [
    (slider) => {
      let timeout
      let mouseOver = false
      function clearNextTimeout() {
        clearTimeout(timeout)
      }
      function nextTimeout() {
        clearTimeout(timeout)
        if (mouseOver) return
        timeout = setTimeout(() => {
          slider.next()
        }, 3000)
      }
      slider.on("created", () => {
        slider.container.addEventListener("mouseover", () => {
          mouseOver = true
          clearNextTimeout()
        })
        slider.container.addEventListener("mouseout", () => {
          mouseOver = false
          nextTimeout()
        })
        nextTimeout()
      })
      slider.on("dragStarted", clearNextTimeout)
      slider.on("animationEnded", nextTimeout)
      slider.on("updated", nextTimeout)
    },
  ]
)
var thumbnails = new KeenSlider(
  "#thumbnails",
  {
    initial: 0,
    slides: {
      perView: 4,
      spacing: 10,

    },
  },
  [ThumbnailPlugin(this.slider)]
)

この記事が気に入ったらサポートをしてみませんか?