Conveyer - Image carousel - 2019 made in 2.5 hours

by Julien Etienne

HTML

<div class="gal" id="gal">
  <div class="gal-next" id="gal-next">▶</div>
  <div class="gal-previous" id="gal-previous">◀</div>
  <nav class="gal-images">
    <a href="#">
      <img src="https://picsum.photos/id/237/800/400" alt="A">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/456/800/400" alt="B">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/124/800/400" alt="C">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/354/800/400" alt="D">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/338/800/400" alt="E">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/564/800/400" alt="F">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/145/800/400" alt="G">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/387/800/400" alt="H">
    </a>
    <a href="#">
      <img src="https://picsum.photos/id/866/200/300" alt="K">
    </a>
  </nav>
</div>

CSS

.gal {
  overflow: hidden;
  position: absolute;
  /* height: 100%; */

  >.gal-images {
    position: absolute;
    display: block;
    height: 100%;
    background: #222;

    >a {
      background: #222;
      display: grid;
      position: relative;
      float: left;
      height: 100%;
      align-items: center;
      justify-items: center;
      transition: filter 200ms linear;
      
      >img {
        display: block;
        height: 100%;
      }
    }

  }

  > :is(.gal-next, .gal-previous) {
    background: rgb(0, 0, 0, 0.8);
    position: absolute;
    z-index: 3;
    width: 4rem;
    height: 4rem;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.6em;
    color: rgba(255, 255, 255, 0.7);
    top: calc(50% - 2rem);
    cursor: pointer;
  }

  >.gal-next {
    right: 0;
  }

  >.gal-previous {
    left: 0;
  }
}

JavaScript

const conveyer = ({
  selector,
  transition,
  size,
  prevSelector,
  nextSelector,
  itemSelector,
  transitionStart,
  transitionEnd
}) => {
  const gal = document.querySelector(selector)
  const galImages = gal.querySelector('nav')
  const getGalLinks = () => Array.from(galImages.children)
  const galLinks = getGalLinks()
  const [width, height, partialPercent] = size
  const px = 'px'
  const pc = '%'
  const raf = window.requestAnimationFrame
  let galImagesLeft = 0
  const controller = new Map()
  controller.set(prevSelector, false)
  controller.set(nextSelector, true)


  const convey = direction => () => {
    galImages.style.transition = transition
    const x = (width / 100 * partialPercent)
    galImagesLeft += direction === 'toLeft' ? -(x) : x
    //console.log('convey', galImagesLeft + px)
    galImages.style.left = galImagesLeft + px
  }


  const progressCollection = canCopy => {
    //console.log('canCopy', canCopy)
    const currentGalLinks = getGalLinks()
    const linksIndex = canCopy ? 0 : currentGalLinks.length - 1
    const currentLastLink = currentGalLinks[linksIndex]
    const position = canCopy ? 'beforeend' : 'afterbegin'
    //console.log('currentLastLink', currentLastLink)
    galImages.insertAdjacentElement(position, currentLastLink)
    const partial = (width / 100 * partialPercent)
    galImagesLeft += canCopy ? (partial) : -(partial)
    galImages.style.transition = 'none'
    galImages.style.left = galImagesLeft + px
    raf(convey(canCopy ? 'toLeft' : 'toRight'))
  }


  const setGallerySize = (width, height) => {
    const imagesWidth = galLinks.length * width
    galImages.style.width = imagesWidth + px
    galImages.style.marginLeft = -(partialPercent - ((100 - partialPercent) / 2)) + pc
    gal.style.width = width + px
    gal.style.height = height + px
    galLinks.forEach(link => link.style.width = (100 / galLinks.length) * (partialPercent / 100) + pc)
  }

  const...