Make this Elementor 3D Image Gallery with Scroll

 

Want to get this as ready made template with just 1 CLICK INSTALL?

I want it as Ready Template

 

Code Snippet for 3D Image Gallery:

<style>
body{
    --smooth-scroll: true;
}
[class^='mdw-image-gallery-3d'],
[class*='mdw-image-gallery-3d']{
    --disabled-section-padding-top: 70px;
    --disabled-section-padding-bottom: 50px;
}
[class^='mdw-image-gallery-3d'].disabled,
[class*='mdw-image-gallery-3d'].disabled{
    height: auto !important;
    padding-top: var(--disabled-section-padding-top, 70px);
    padding-bottom: var(--disabled-section-padding-bottom, 50px);
    overflow: hidden;
    position: relative;
}
html:not(.elementor-html) [class^='mdw-image-gallery-3d'] .elementor-widget-html,
html:not(.elementor-html) [class*='mdw-image-gallery-3d'] .elementor-widget-html{
    display: none;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner{
    transform-style: preserve-3d;
    perspective: 750px;
    backface-visibility: hidden;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-bg, 
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-bg{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    opacity: 0.6;
}
[class^='mdw-image-gallery-3d'].disabled .mdw-image-gallery-bg,
[class*='mdw-image-gallery-3d'].disabled .mdw-image-gallery-bg{
    position: absolute !important;
    background-size: cover;
    background-position: center;
    filter: blur(50px);
    transform: scale(1.15);
    height: 100%;
}
[class^='mdw-image-gallery-3d'] .sticky,
[class*='mdw-image-gallery-3d'] .sticky {
    position: fixed;
    top: 0;
}
[class^='mdw-image-gallery-3d'] .sticky-end,
[class*='mdw-image-gallery-3d'] .sticky-end{
    position: absolute;
    bottom: 0;
    top: auto !important;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-bg img,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-bg img{
    position: absolute;
    left: 0;
    top: 0;
    filter: blur(50px);
    transform: scale(1.125); 
    max-width: unset;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
[class^='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner,
[class*='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner{
    flex-direction: row;
    flex-wrap: wrap;
    position: static !important;
    justify-content: center;
    gap: 12px;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container{
    opacity: 0;
    transition: 0s;
    left: 70% !important;
}
[class^='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner > .e-con,
[class*='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner > .e-con,
[class^='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner > .e-container,
[class*='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner > .e-container{
    position: static;
    opacity: 1 !important;
    transform: none !important;
}
html.elementor-html [class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
html.elementor-html [class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
html.elementor-html [class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container,
html.elementor-html [class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container{
    opacity: 1;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con:nth-child(even),
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con:nth-child(even),
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container:nth-child(even),
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container:nth-child(even){
    left: 30% !important;
}
[class^='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner .elementor-widget-image,
[class*='mdw-image-gallery-3d'].disabled .mdw-image-gallery-inner .elementor-widget-image{
    order: -1;
    margin-bottom: 15px;
}
@media (max-width: 1024px){
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con,
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container,
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container{
    left: 80% !important;
}
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con:nth-child(even),
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-con:nth-child(even),
[class^='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container:nth-child(even),
[class*='mdw-image-gallery-3d'] .mdw-image-gallery-inner > .e-container:nth-child(even){
    left: 20% !important;
}
}
</style>

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>

<script>
if(!MDWNonce113){
var MDWNonce113 = true
;(function($){

var selector = '[class^="mdw-image-gallery-3d"], [class*="mdw-image-gallery-3d"]',
    slides = [],
    options = [],
    galleryBgImages = [],
    visibleRange = [],
    winHeight,
    firstTime = true,
    initialZ = [],
    frontRange = []

function mapRange(value, inMin, inMax, outMin, outMax){
    return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
}
function isDisabled(){
    var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent),
    isMobile = $(window).width() < 768,
    d = isSafari || isMobile
    d ? $(selector).addClass('disabled') : $(selector).removeClass('disabled')
    return d
}
function getValues(){
$(selector).each(function(i){
    var className = $(this).attr('class'),
    classNameIndex = className.indexOf('mdw-image-gallery-3d'),
    shortClass = className.substring(classNameIndex, className.indexOf(' ',classNameIndex)),
    values = shortClass.split('-')
    options[i] = {
        scrollPerItem: 500,
        distance: 1500,
        background: true
    }
    values.forEach(function(value, index){
        if(value =='scrollperitem' && values[index+1] && !isNaN(values[index+1])){ options[i].scrollPerItem = parseFloat(values[index+1]) 
        }
        if(value =='distance' && values[index+1] && !isNaN(values[index+1])){ options[i].distance = parseFloat(values[index+1]) 
        }
        if(value =='nobackground'){ options[i].background = false }
    })
})
}

function setHeight(){
    if(isDisabled()) return
    winHeight = $(window).height()
    $(selector).each(function(i){
        $(this).css('height', winHeight + (slides[i].length * options[i].scrollPerItem) + 'px')
    })
}

function initImages(){
if(isDisabled()) return
$(selector).each(function(i){
initialZ[i] = []
frontRange[i] = []
visibleRange[i] = 5000
slides[i].each(function(index){
    initialZ[i][index] = -index*options[i].distance
    frontRange[i][index] = 1000
    $(this).css('transform', `translate3d(-50%, -50%, ${initialZ[i][index]}px)`)
    $(this).css('opacity', mapRange(initialZ[i][index], -visibleRange[i], 0, 0, 1))
})
})
}

function init(){
getValues()
$(selector).each(function(i){
    var $this = $(this)
    slides[i] = $this.find('.mdw-image-gallery-inner > .e-con, .mdw-image-gallery-inner > .e-con-inner > .e-con, .mdw-image-gallery-inner > .e-container')
    slides[i].each(function(si){ $(this).css('z-index', slides[i].length - si) })
    if(options[i].background){
        var galleryBg = $('<div>').addClass('mdw-image-gallery-bg')
        if(isDisabled()){
            galleryBg.css('background-image', `url('${slides[i].find('img').eq(0).attr('src')}')`)
        }else{
            slides[i].each(function(){
                var clonedImg = $(this).find('img').clone()
                galleryBg.append(clonedImg)
            })
        }
        $this.prepend(galleryBg)
        galleryBgImages[i] = galleryBg.find('img')
        galleryBgImages[i].each(function (gi) {
            $(this).css('z-index', galleryBgImages[i].length - gi)
        })
    }
})
setHeight()
initImages()
}
function setSticky(){
if(isDisabled()) return
$(selector).each(function(i){
    var $this = $(this),
    rect = $this[0].getBoundingClientRect(),
    inner = $this.children()
    
    rect.top <= 0 ? inner.addClass('sticky') : inner.removeClass('sticky')
    rect.bottom < winHeight ? inner.addClass('sticky-end') : inner.removeClass('sticky-end')
})
}

function moveImages(){
$(selector).each(function(i){
    var progress = ($(window).scrollTop() - $(this).offset().top)/($(this).height()-$(window).height())
    if(progress >= 0 && progress <= 1){
        zIncrement = progress*options[i].distance*(slides[i].length - 1)
    
        slides[i].each(function(index){
            var currentZ = initialZ[i][index] + zIncrement,
            opacity = mapRange(currentZ, -visibleRange[i], 0, 0, 1),
            opacityBg
            
            if(opacity >= 0){
                if(opacity <= 1 || firstTime) $(this).css('opacity', opacity)
                if(currentZ < frontRange[i][index] || firstTime) $(this).css('transform', `translate3d(-50%, -50%, ${currentZ}px)`)
            }
            if(options[i].background){
                opacityBg = currentZ < 100 ? 1 : 0
                gsap.to($(galleryBgImages[i][index]), {
                    opacity: opacityBg,
                    ease: 'power3.out',
                    duration: 1.5,
                })
            }
        })
        firstTime = false
    }
})
}

$(document).ready(init)
$(window).on('load resize', setHeight)
$(window).on('load resize scroll', function(){
    setSticky()
    moveImages()
})
})(jQuery)
}
</script>

<!-- Smooth Scroll -->
<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>