blur-crossfade-bg-image

by maemaemae3

HTML

<div id="app">
  <div class="outer">
    <transition
      name="blur"
      @enter="crossfading = true"
      @after-enter="crossfading = false"
    >
      <div
         :key="imageIndex"
         :style="{'background-image': `url(${images[imageIndex].url})`}"
         class="full"
      ></div>
    </transition>
  </div>
  <div class="overlay" :class="{ 'blur-animation': crossfading }"></div>
</div>

SCSS

$blur-width: 20px;

.full {
  background-position: center;
  background-size: cover;
  position: absolute;
  width: 100%;
  height: 100%;
  transform: scale(1.2);
}

.overlay {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 100%;
  opacity: 0;
  backdrop-filter: blur($blur-width);
  &.blur-animation {
    animation: overlay-blur-animation 4s;
  }
}

.blur-leave-active {
  animation: blur-animation-out 4s;
}
.blur-enter-active {
  animation: blur-animation-in 4s;
}

@keyframes blur-animation-out {
  0% {
    opacity: 1;
  }
  30% {
    opacity: 0.8;
  }
  50% {
    opacity: 0;
  }
}

@keyframes blur-animation-in {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
}

@keyframes overlay-blur-animation {
  10% {
    opacity: 1;
  }
  70% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

Vue

new Vue({
  el: "#app",
  data: {
  	imageIndex: 0,
    crossfading: false,
    images: [
      { url: "https://cdn.stocksnap.io/img-thumbs/960w/old-barn_8GQRWBFOCZ.jpg" },
      { url: "https://cdn.stocksnap.io/img-thumbs/960w/blue-abstract_Z9CLCWFKBH.jpg" },
      { url: "https://cdn.stocksnap.io/img-thumbs/960w/city-skyline_HVKT6YLKOJ.jpg" }
    ]
  },
  mounted() {
    setInterval(() => {
      this.imageIndex = this.imageIndex < (this.images.length - 1) ? this.imageIndex + 1 : 0;
    }, 5000)
  }
})