<div class="wrapper">
  <h6>Center</h6>
  <div class="container">
    <svg>
      <defs>
        <filter id="ripple-filter1">
          <feImage class="feImage1" x="125" y="150" width="0%" height="0%" result="rippleImage" />
          <feDisplacementMap id="displacement-map1" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="rippleImage" result="displacementMap" color-interpolation-filters="sRGB" scale="0" />
          <feComposite operator="in" in2="rippleImage"></feComposite>
        </filter>
      </defs>
      <g id="logo">
        <image id="logo-image" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1_1.jpg" />
        <image id="logo-overlay" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1_1.jpg" filter="url(#ripple-filter1)" />
        <image id="woman" width="300" height="250" xlink:href="https://assets.codepen.io/323880/woman.png" />
      </g>
    </svg>
  </div>
</div>
<!--  -->
<div class="wrapper">
  <h6>Bottom right</h6>
  <div class="container">
    <svg>
      <defs>
        <filter id="ripple-filter2">
          <feImage class="feImage2" x="250" y="250" width="0%" height="0%" result="rippleImage" />
          <feDisplacementMap id="displacement-map2" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="rippleImage" result="displacementMap" color-interpolation-filters="sRGB" scale="0" />
          <feComposite operator="in" in2="rippleImage"></feComposite>
        </filter>
      </defs>
      <g id="logo">
        <image id="logo-image" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1%403x.jpg" />
        <image id="logo-overlay" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1%403x.jpg" filter="url(#ripple-filter2)" />
        <image id="woman" width="300" height="250" xlink:href="https://assets.codepen.io/323880/woman.png" />
      </g>
    </svg>
  </div>
</div>

<div class="wrapper">
  <h6>Bottom right (slower)</h6>
  <div class="container">
    <svg>
      <defs>
        <filter id="ripple-filter3">
          <feImage class="feImage3" x="250" y="250" width="0%" height="0%" result="rippleImage" />
          <feDisplacementMap id="displacement-map3" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="rippleImage" result="displacementMap" color-interpolation-filters="sRGB" scale="0" />
          <feComposite operator="in" in2="rippleImage"></feComposite>
        </filter>
      </defs>
      <g id="logo">
        <image id="logo-image" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1%403x.jpg" />
        <image id="logo-overlay" width="300" height="250" xlink:href="https://assets.codepen.io/323880/zmbz-photo-1%403x.jpg" filter="url(#ripple-filter3)" />
        <image id="woman" width="300" height="250" xlink:href="https://assets.codepen.io/323880/woman.png" />
      </g>
    </svg>
  </div>
</div>
// html,
// body {
//  height: 100%;
// }

body {
  font-family: "Open Sans", sans-serif;
  background: linear-gradient(
    0deg,
    rgba(161, 139, 211, 1) 0%,
    rgba(251, 194, 235, 1) 100%
  );
  min-height: 100vh;
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-direction: row;
  flex-wrap: wrap;
  padding: 0 2rem;
}

.wrapper {
  h6 {
    font-weight: 500;
    color: hsla(0, 0%, 0%, 1);
    font-size: 1.2em;
    margin-bottom: 1rem;
  }
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
}
.container {
  width: 300px;
  height: 250px;
  position: relative;
  overflow: hidden;
  border: 1px solid hsla(243, 44%, 18%, 1);
}
svg {
  width: 300px;
  height: 250px;
  top: 50%;
  left: 50%;
  position: relative;
  transform: translate(-50%, -50%);
}
View Compiled
const xlink   = "http://www.w3.org/1999/xlink",
      imgUrl  = "https://assets.codepen.io/323880/ripple%40512x512.png",
      feImage = document.querySelector(".feImage1"),
      feImage2 = document.querySelector(".feImage2"),
      feImage3 = document.querySelector(".feImage3");


toBase64(imgUrl, function(data) {
  feImage.setAttributeNS(xlink, "xlink:href", data);
  var tl = new TimelineMax({ repeat: -1, repeatDelay: 1 });
  tl.from("#displacement-map1", 3.5, { attr: { scale: 90 }}, 0)
    .to(".feImage1", 3.5, { attr: { x: -125, y: -150, width: "200%", height: "200%" }}, 0);
})

toBase642(imgUrl, function(data) {
  feImage2.setAttributeNS(xlink, "xlink:href", data);
   var t2 = gsap.timeline({ repeat: -1, repeatDelay: 1 });
  t2.from("#displacement-map2", 3.5, { attr: { scale: 100 }}, 0)
    .to(".feImage2", 3.5, { attr: { x: -190, y: -190, width: "300%", height: "300%" }}, 0);
})

toBase643(imgUrl, function(data) {
  feImage3.setAttributeNS(xlink, "xlink:href", data);
   var t3 = gsap.timeline({ repeat: -1, repeatDelay: 1 });
  t3.from("#displacement-map3", 9, { attr: { scale: 100 }}, 0)
    .to(".feImage3", 9, { attr: { x: -190, y: -190, width: "300%", height: "300%" }}, 0);
})

function toBase64(url, callback){
  var img = new Image();
  img.crossOrigin = "anonymous";
  img.onload = function(){
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    
    var dataURL = canvas.toDataURL("image/png");
    callback(dataURL);
    canvas = null; 
  };
  
  img.src = url;
}


function toBase642(url, callback){
  var img = new Image();
  img.crossOrigin = "anonymous";
  img.onload = function(){
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    
    var dataURL = canvas.toDataURL("image/png");
    callback(dataURL);
    canvas = null; 
  };
  
  img.src = url;
}
function toBase643(url, callback){
  var img = new Image();
  img.crossOrigin = "anonymous";
  img.onload = function(){
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    
    var dataURL = canvas.toDataURL("image/png");
    callback(dataURL);
    canvas = null; 
  };
  
  img.src = url;
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.co/gsap@3/dist/gsap.min.js