.message Please scroll down ↓
.container
  -for(i=0; i<10; i++)
    div.image
      span.trigger
      svg(viewBox="0 0 800 600")
        defs
          filter(id="filter-"+i filterUnits="userSpaceOnUse")
            feTurbulence(type="fractalNoise" baseFrequency="0.13" seed="20" result="fractalNoise")
            feDisplacementMap(in2="turbulence" in="SourceGraphic" scale="16" xChannelSelector="B" yChannelSelector="G")
        image(filter="url(#filter-"+i+")" id="image-"+i height="100%" width="100%" xlink:href="https://source.unsplash.com/80"+i+"x60"+i)
View Compiled
html { scroll-behavior: smooth; }

.image {
  max-height: 65vh;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 50px auto;
  position: relative;
  overflow: hidden;
  max-width: 70%;
  opacity: .5;
  filter:"grayscale(100%)";
}

svg { height: 65vh; }

.image:last-of-type {
  margin-bottom: 100px;
}

 
.trigger {
  position: absolute;
  top: 10%;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.message {
  position: fixed;
  bottom: 0;
  transform: translateX(-50%);
  left: 50%;
  z-index: 5;
  padding: 10px;
  background-color: #000;
  color: #fff;
  border-radius: 6px 6px 0 0;
  box-shadow: 0 -10px 20px rgba(0,0,0,.3);
}
View Compiled
const svgs = document.querySelectorAll("svg");
const controller = new ScrollMagic.Controller();
 
svgs.forEach((svg, index) => {
  const blurryTween = TweenMax.to(svg.querySelector("feTurbulence"), 4, {
    attr: {
      baseFrequency: "0.13",
      seed: "20"
    }
  });

  const op05 = TweenMax.to(svg.parentNode, 3, {
    opacity: 0.5,
    filter: "grayscale(100%)"
  });

  const op1 = TweenMax.to(svg.parentNode, 3, {
    opacity: 1,
    filter: "grayscale(0%)"
  });

  const blurryScene = new ScrollMagic.Scene({
    triggerElement: svg,
    duration: svg.parentNode.getBoundingClientRect().height - 50,
    triggerHook: 0
  })
    .setTween([blurryTween, op05])
    .on("start", () => {
      document.querySelector(".message") &&
        document.querySelector(".message").remove();
    })
    .addTo(controller);

  const notBlurryTween = TweenMax.to(svg.querySelector("feTurbulence"), 4, {
    attr: {
      baseFrequency: "0",
      seed: "1"
    }
  });

  const notBlurryScene = new ScrollMagic.Scene({
    triggerElement: svg,
    duration: svg.parentNode.getBoundingClientRect().height - 50,
    triggerHook: 0.9
  })
    .setTween([notBlurryTween, op1])
    .addTo(controller);
});

// DEMO

document.addEventListener("DOMContentLoaded", () => {
  document.querySelectorAll("img").forEach(img => {
    img.onerror = function() {
      this.style.display = "none";
    };
  });
});
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/animation.gsap.js