JSFiddle - React, Tailwind, and code Playground

by Julien Vernet

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <full-screen-background></full-screen-background>
</div>

CSS

.cb-slideshow,
.cb-slideshow li{
  list-style: none;
  margin: 0;
  padding: 0;
}

.cb-slideshow {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0px;
  left: 0px;
  z-index: 0;
}

.cb-slideshow li span {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0px;
  left: 0px;
  color: transparent;
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: none;
  opacity: 0;
  z-index: 0;
}

@keyframes imageAnimation {
  0% {
    opacity: 0;
    animation-timing-function: ease-in;
  }
  10% {
    opacity: 1;
    animation-timing-function: ease-out;
  }
  100% {
    opacity: 0
  }
}

JavaScript

Vue.component('full-screen-background', {
  template: `<ul class="cb-slideshow">
        			 <li v-for="image in images">
               	 <span :style="backgroundClass(image)">Image {{ image.id }}</span>
              </li>
            </ul>`,
  data: function() {
    return {
      images: [{
      	id: 1,
        path: 'https://lorempixel.com/1920/1080/sports/1/'
      }, {
      	id: 2,
        path: 'https://lorempixel.com/1920/1080/sports/2/'
      }, {
      	id: 3,
        path: 'https://lorempixel.com/1920/1080/sports/3/'
      }, {
      	id: 4,
        path: 'https://lorempixel.com/1920/1080/sports/7/'
      }, {
      	id: 5,
        path: 'https://lorempixel.com/1920/1080/sports/5/'
      }, {
      	id: 6,
        path: 'https://lorempixel.com/1920/1080/sports/6/'
      }]
    }
  },
  methods: {
    backgroundClass(image) {
        // determine place of image in array
        let pos = this.images.map(function(x) {
          return x.id;
        }).indexOf(image.id);
        if (pos > 0) {
          let styles = {
          	'animation-name': 'imageAnimation',
            'animation-duration': this.totalBackgroundImages * 6 + 's',
            'animation-delay': pos * 6 + 's',
            'background-image': `url(${image.path})`,
            'animation-iteration-count': 'infinite',
            'animation-fill-mode': 'linear'
          }
          console.log(styles);
          return styles;
        }
        return {
          'animation-name': 'imageAnimation',
          'animation-duration': this.totalBackgroundImages * 6 + 's',
          'background-image': `url(${image.path})`,
          'animation-iteration-count': 'infinite',
          'animation-fill-mode': 'linear',
        }
      },
  },
  computed: {
    totalBackgroundImages() {
      return this.images.length;
    }
  },

});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app'
});