Want to get this as ready made template with just 1 CLICK INSTALL?
Code Snippet for Image Turbulence Reveal Effect:
<style>
body{
--smooth-scroll: true;
--fallback-circle: true;
}
[class^='mdw-turbulence-effect'],
[class*=' mdw-turbulence-effect']{
--text-gap: 20px;
}
[class^='mdw-turbulence-effect'].anim .elementor-widget-heading,
[class*=' mdw-turbulence-effect'].anim .elementor-widget-heading,
[class^='mdw-turbulence-effect'].anim .elementor-widget-image svg,
[class*=' mdw-turbulence-effect'].anim .elementor-widget-image svg{
transition: all 1s cubic-bezier(0,.33,.07,1.03);
}
[class^='mdw-turbulence-effect'] .elementor-widget-heading,
[class*=' mdw-turbulence-effect'] .elementor-widget-heading{
opacity: 0;
white-space: nowrap;
max-width: unset !important;
display: flex;
justify-content: center;
}
[class^='mdw-turbulence-effect'] .elementor-widget-heading.show,
[class*=' mdw-turbulence-effect'] .elementor-widget-heading.show,
html.elementor-html [class^='mdw-turbulence-effect'] .elementor-widget-heading,
html.elementor-html [class*=' mdw-turbulence-effect'] .elementor-widget-heading{
opacity: 1;
}
[class^='mdw-turbulence-effect'] p,
[class*=' mdw-turbulence-effect'] p{
margin-bottom: 0;
}
[class^='mdw-turbulence-effect'] .elementor-widget-image svg,
[class*=' mdw-turbulence-effect'] .elementor-widget-image svg{
position: absolute;
left: 0;
top: unset;
}
[class^='mdw-turbulence-effect'] .elementor-widget-image.eye image,
[class*=' mdw-turbulence-effect'] .elementor-widget-image.eye image{
transform: none !important;
}
[class^='mdw-turbulence-effect'] .elementor-widget-image.eye.blur g,
[class*=' mdw-turbulence-effect'] .elementor-widget-image.eye.blur g{
transform: scale(0.95);
transform-origin: center;
}
[class^='mdw-turbulence-effect'] .elementor-widget-image.eye.blur image,
[class*=' mdw-turbulence-effect'] .elementor-widget-image.eye.blur image{
transform: scale(1.05) !important;
}
[class^='mdw-turbulence-effect'] .elementor-widget-image img,
[class*=' mdw-turbulence-effect'] .elementor-widget-image img{
opacity: 0;
}
html.elementor-html [class^='mdw-turbulence-effect'] .elementor-widget-image img,
html.elementor-html [class*=' mdw-turbulence-effect'] .elementor-widget-image img{
opacity: 1;
}
[class^='mdw-turbulence-effect'] .elementor-widget-text-editor,
[class*=' mdw-turbulence-effect'] .elementor-widget-text-editor{
max-width: var(--container-widget-width, 100%) !important;
}
@media (max-width:767px){
[class^='mdw-turbulence-effect'],
[class*=' mdw-turbulence-effect']{
--text-gap: 10px;
}
[class^='mdw-turbulence-effect'] .elementor-widget-heading,
[class*=' mdw-turbulence-effect'] .elementor-widget-heading,
[class^='mdw-turbulence-effect'] .elementor-widget-text-editor,
[class*=' mdw-turbulence-effect'] .elementor-widget-text-editor{
position: static !important;
}
[class^='mdw-turbulence-effect'] .elementor-widget-heading,
[class*=' mdw-turbulence-effect'] .elementor-widget-heading{
max-width: 100% !important;
}
}
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
if(!MDWNonce110){
var MDWNonce110 = true
;(function($){
var selector = "[class^='mdw-turbulence-effect'], [class*=' mdw-turbulence-effect']",
image = [],
img = [],
title1 = [],
title2 = [],
heading1 = [],
heading2 = [],
windowHeight,
windowWidth,
imgWidth = [],
imgHeight = [],
imgOffset = [],
maxRadius = [],
translate = [],
type = [],
brightness = { start: 0.8, end: 1.0 },
scale = { start: 0.9, end: 1.0 },
isSafari,
fallbackCircle,
previousWidth
function getValue(el, prop){ return getComputedStyle(el[0]).getPropertyValue(prop) }
function init(){
$(selector).each(function(i){
var $this = $(this)
image[i] = $this.find('.elementor-widget-image')
img[i] = image[i].find('img')
title1[i] = $this.find('.elementor-widget-heading').eq(0)
title2[i] = $this.find('.elementor-widget-heading').eq(1)
heading1[i] = title1[i].find('.elementor-heading-title')
heading2[i] = title2[i].find('.elementor-heading-title')
$('body').append('<div class="mdw-100vh" style="height: 100vh;display: none;"></div>')
isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
fallbackCircle = getValue($('body'),'--fallback-circle') && getValue($('body'),'--fallback-circle') == 'true'
})
}
function setValues(){
windowHeight = $('.mdw-100vh').height()
windowWidth = $(window).width()
$(selector).each(function(i){
var $this = $(this)
imgWidth[i] = img[i].width()
imgHeight[i] = img[i].height()
maxRadius[i] = Math.sqrt(Math.pow(imgWidth[i]/2,2)+Math.pow(imgHeight[i]/2,2))+10
if(isSafari && !fallbackCircle && maxRadius[i] > 850) maxRadius[i] = 850
})
}
function setSVG(){
$(selector).each(function(i){
var $this = $(this),
imgNaturalWidth = img[i][0].naturalWidth,
imgNaturalHeight = img[i][0].naturalHeight,
imgContainer = image[i].find('.elementor-widget-container'),
imgSrcset = img[i].attr('srcset').split(' '),
imgUrl = imgSrcset[imgSrcset.length - 2],
className = $this.attr('class'),
classNameIndex = className.indexOf('mdw-turbulence-effect'),
shortClass = className.substring(classNameIndex, className.indexOf(' ',classNameIndex)),
values = shortClass.split('-'),
blurHTML = shortClass.search('blur') == -1 || windowWidth < 768 || isSafari ? '' : '<feGaussianBlur in="displacement" stdDeviation="10"></feGaussianBlur>',
shapeHTML = `<circle cx="50%" cy="50%" fill="white" class="mask" style="filter: url(#MDWFilter${i+1});"></circle>`,
eyeClass = '',
effectResolution = 0.03,
effectArea = 50,
effectOctave = 3,
effectHTML,
svgHTML
values.forEach(function(value, index){
if(value=='resolution' && values[index+1] && !isNaN(values[index+1])){ effectResolution = parseFloat(values[index+1])*0.003 }
if(value=='area' && values[index+1] && !isNaN(values[index+1])){ effectArea = parseFloat(values[index+1])*5 }
})
if(effectArea > 100) effectOctave = 1
if(blurHTML){
image[i].addClass('blur')
effectResolution = 0.01
effectArea = 150
effectOctave = 3
}
type[i] = 'circle'
if(shortClass.search('eye') != -1){
type[i] = 'eye'
image[i].addClass('eye')
effectResolution = 0.06
if(blurHTML) effectResolution = 0
effectArea = 50
shapeHTML = `<path d="M 0 ${imgHeight[i]/2} Q ${imgWidth[i]/2} ${3*imgHeight[i]/2 - 2*12} ${imgWidth[i]} ${imgHeight[i]/2} Q ${imgWidth[i]/2} ${2*12 - imgHeight[i]/2} 0 ${imgHeight[i]/2}" fill="white" class="mask" style="filter: url(#MDWFilter${i+1});"></path>`
}
if( fallbackCircle && (windowWidth < 768 || isSafari) ){
effectHTML = ''
}else{
effectHTML =
`<defs>
<filter id="MDWFilter${i+1}">
<feTurbulence type="fractalNoise" baseFrequency="${effectResolution}" numOctaves="${effectOctave}" result="noise"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="${effectArea}" xChannelSelector="R" yChannelSelector="G"></feDisplacementMap>
${blurHTML}
</filter>
<mask id="MDWCircle${i+1}">
${shapeHTML}
</mask>
</defs>`
}
svgHTML =
`<svg width="${imgWidth[i]}" height="${imgHeight[i]}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 ${imgWidth[i]} ${imgHeight[i]}">
${effectHTML}
<g mask="url(#MDWCircle${i+1})">
<image href="${imgUrl}" width="${imgWidth[i]}" height="${imgHeight[i]}" style="transform: scale(${scale.start}); transform-origin: center center; filter: brightness(${brightness.start});" preserveAspectRatio="xMidYMid slice"></image>
</g>
</svg>`
imgContainer.find('svg').remove()
imgContainer.append(svgHTML)
})
}
function getOffset(el){
var left = 0, top = 0
do{
if (!isNaN(el.offsetLeft)) left += el.offsetLeft
if (!isNaN(el.offsetTop)) top += el.offsetTop
}while(el = el.offsetParent)
return { top, left }
}
function setInitTranslate(){
var scrollTop = $(window).scrollTop()
$(selector).each(function(i){
var $this = $(this),
H1Offset = getOffset(heading1[i][0]),
H2Offset = getOffset(heading2[i][0]),
imgOffset = getOffset(img[i][0]),
textGap = !isNaN(parseFloat(getValue($this, '--text-gap'))) ? parseFloat(getValue($this, '--text-gap')) : 20,
T1X,T1Y,T2X,T2Y
T1X = - H1Offset.left + (windowWidth - heading1[i].width() - heading2[i].width() - textGap) / 2
T1Y = imgOffset.top - H1Offset.top + (imgHeight[i] - heading1[i].height())/2
T2X = - H2Offset.left + (windowWidth + heading1[i].width() - heading2[i].width() + textGap) / 2
T2Y = imgOffset.top - H2Offset.top + (imgHeight[i] - heading2[i].height())/2
translate[i] = {T1X,T1Y,T2X,T2Y}
})
}
function getScrollValue(imgOffset, imgHeight, startPercent, endPercent, inverse= false){
var start = startPercent/100*windowHeight,
end = endPercent/100*windowHeight,
scrollValue = (imgOffset.top+imgHeight/2-start)/(end - start),
value = Math.max(Math.min(scrollValue,1),0)
if(inverse) value = 1 - value
return value
}
function revealImage(startPercent){
var imgStartPercent = 90,
imgEndPercent = 60
$(selector).each(function(i){
imgOffset[i] = img[i][0].getBoundingClientRect()
var svg = image[i].find('svg'),
svgCircle = svg.find('circle'),
svgPath = svg.find('path'),
svgGroup = svg.find('g'),
svgImage = svg.find('image'),
revealAmount = getScrollValue(imgOffset[i], imgHeight[i], imgStartPercent, imgEndPercent),
currentBrightness = brightness.start + (brightness.end - brightness.start)*revealAmount,
currentScale = scale.start + (scale.end - scale.start)*revealAmount,
curretRadius = maxRadius[i]*revealAmount
svgImage.css({
'filter': `brightness(${currentBrightness})`,
'transform': `scale(${currentScale})`
})
if( fallbackCircle && (windowWidth < 768 || isSafari) ){
if( type[i] == 'circle' ) {
svg.css('clip-path', `circle(${curretRadius}px at 50% 50%)`)
}else{
svg.css('clip-path', `ellipse(50% ${revealAmount*50}% at 50% 50%)`)
}
}else{
if( type[i] == 'circle' ) {
svgCircle.attr('r', curretRadius)
}else{
svgGroup.attr('mask', `url(#MDWCircle${i+1})`)
svgPath.attr('d', `M 0 ${imgHeight[i]/2} Q ${imgWidth[i]/2} ${imgHeight[i]/2 + (imgHeight[i] - 2*12)*revealAmount} ${imgWidth[i]} ${imgHeight[i]/2} Q ${imgWidth[i]/2} ${imgHeight[i]/2 + (2*12 - imgHeight[i])*revealAmount} 0 ${imgHeight[i]/2}`)
}
}
})
}
function moveText(startPercent){
var titleStartPercent = 90,
titleEndPercent = 50
$(selector).each(function(i){
var $this = $(this),
translateAmount = getScrollValue(imgOffset[i], imgHeight[i], titleStartPercent, titleEndPercent, true),
T1T = {x: translate[i].T1X*translateAmount, y: translate[i].T1Y*translateAmount}
T2T = {x: translate[i].T2X*translateAmount, y: translate[i].T2Y*translateAmount}
title1[i].css('transform', `translate(${T1T.x}px, ${T1T.y}px)`)
title2[i].css('transform', `translate(${T2T.x}px, ${T2T.y}px)`)
title1[i].addClass('show')
title2[i].addClass('show')
setTimeout(function(){ $this.addClass('anim') }, 50)
})
}
function scrollAnimation(){
revealImage()
moveText()
}
function runAnimation(e){
if(e.type=='load') init()
setValues()
setSVG()
setInitTranslate()
scrollAnimation()
}
$(document).ready(init)
$(window).on('scroll', scrollAnimation)
$(window).on('load resize', function(e){
if(e.type=='resize' && $(window).width() < 768 && $(window).width() == previousWidth) return
runAnimation(e)
setTimeout(function(){ runAnimation(e) }, 100)
setTimeout(function(){ runAnimation(e) }, 500)
setTimeout(function(){ runAnimation(e) }, 1000)
previousWidth = $(window).width()
})
})(jQuery)
}
</script>
<!-- Smooth Scroll with Lenis JS -->
<style>
html.lenis, html.lenis body {
height: auto;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain;
}
.lenis.lenis-stopped {
overflow: hidden;
}
.lenis.lenis-smooth iframe {
pointer-events: none;
}
</style>
<script src="https://unpkg.com/lenis@1.1.11/dist/lenis.min.js"></script>
<script>
$(document).ready(function(){
var smoothScroll = getComputedStyle(document.body).getPropertyValue('--smooth-scroll'),
smoothScroll = smoothScroll && smoothScroll == 'true'
if(smoothScroll){
var lenis = new Lenis()
function raf(time) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
}
})
</script>


