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>