<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
This Pen doesn't use any external CSS resources.