Recreating GTA 6 Landing Page Scrolling Effect in Elementor

 

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

I want it as Ready Template

 

Code Snippet for Scrolling Effect:

<style>

/* For Desktop */

.mdw-gta6-effect{
    --svg-image-zoom-origin-x: 0px;
    --svg-image-zoom-origin-y: 0px;
    --gradient-heading-color-1: #ff00f7;
    --gradient-heading-color-2: #ff003d;
    --gradient-heading-color-3: #8e00ff;
    
    /* Refresh Required */
    /*--banner-hd-url: url('HD_IMAGE_URL');*/
    --banner-maximum-zoom: 1.3;
    --banner-initial-zoom: 200px;
    --banner-entrance-transition: 1.5s;
    --svg-image-height: 120px;
    --svg-image-bottom-gap: 50px;
    --svg-image-maximum-zoom: 400;
    --svg-image-background: #121212;
}

/* For Tablet */

@media (max-width:1024px){
.mdw-gta6-effect{

}
}

/* For Mobile */

@media (max-width:767){
.mdw-gta6-effect{
    
}
}

.mdw-gta6-effect > *{
    position: absolute;
    top: 0;
}
.mdw-gta6-effect > *.sticky{
    position: fixed;
    top: 0;
}
.mdw-gta6-effect > *.sticky-end{
    position: absolute;
    bottom: 0;
    top: auto !important;
}
.mdw-gta6-effect p{
    margin-bottom: 0;
}
html.elementor-html .mdw-gta6-banner,
.mdw-gta6-banner.loaded{
    --banner-initial-zoom: 0px;
}
.mdw-gta6-banner:before,
.mdw-gta6-banner .elementor-widget  > *{
    opacity: 0;
}
.mdw-gta6-banner:before{
    transform: scale(var(--banner-zoom,1));
    background-size: cover;
    background-position: center center;
    top: calc(-1*var(--banner-initial-zoom,0px));
    left: calc(-1*var(--banner-initial-zoom,0px));
    height: calc(100% + var(--banner-initial-zoom,0px) * 2);
    width: calc(100% + var(--banner-initial-zoom,0px) * 2);
    filter: blur(calc(var(--banner-initial-zoom,0px)/4));
    transition: opacity var(--banner-entrance-transition,0s) ease-in-out, top var(--banner-entrance-transition,0s) ease-in-out, left var(--banner-entrance-transition,0s) ease-in-out, height var(--banner-entrance-transition,0s) ease-in-out, width var(--banner-entrance-transition,0s) ease-in-out, filter var(--banner-entrance-transition,0s) ease-in-out;
}
.mdw-gta6-banner.hd-bg:before{
    background-image: var(--banner-hd-url) !important;
}
.mdw-gta6-banner .elementor-widget > *{
    filter: blur(calc(var(--banner-initial-zoom,0px)/4));
    transition: all calc(var(--banner-entrance-transition,0s)/2) linear calc(var(--banner-entrance-transition,0s)/2) !important;
}
.mdw-gta6-banner.loaded:before,
html.elementor-html .mdw-gta6-banner:before,
.mdw-gta6-banner.loaded .elementor-widget > *,
html.elementor-html .mdw-gta6-banner .elementor-widget > *{
    opacity: 1;
}
.mdw-gta6-container{
    --svg-image-top-gap: 0px;
    position: relative;
}
.mdw-gta6-container:before{
    opacity: var(--overlay-opacity-2,0);
    transition: none;
}
.mdw-gta6-container:after{
    content: "";
    background: red;
    height: 5px;
    width: 5px;
    position: absolute;
    top: calc(var(--svg-image-top-gap,0px) + var(--svg-image-height,0px)/2 + var(--svg-image-zoom-origin-y,0px));
    left: calc(50% + var(--svg-image-zoom-origin-x,0px));
    transform: translate(-50%,-50%);
    z-index: 10;
    border-radius: 50px;
    opacity: 0.9;
    display: none;
}
html.elementor-html .mdw-gta6-container:after{
    display: block;
}
html:not(.elementor-html) .mdw-gta6-container,
html:not(.elementor-html) .mdw-gta6-container > *{
    pointer-events: none;
}
html:not(.elementor-html) .mdw-gta6-container.clickable,
html:not(.elementor-html) .mdw-gta6-container.clickable > *{
    pointer-events: auto;
}
html:not(.elementor-html) .mdw-gta6-container > .elementor-element{
    opacity: 0;
}
html:not(.elementor-html) .mdw-gta6-container.clickable > .elementor-element{
    opacity: 1;
}
.mdw-gta6-container svg{
    min-height: var(--min-height,100vh);
    width: 100%;
    transform: scale(var(--svg-image-maximum-zoom,400));
    transform-origin: calc(50% + var(--svg-image-zoom-origin-x,0px)) calc(var(--svg-image-top-gap) + var(--svg-image-height)/2 + var(--svg-image-zoom-origin-y,0px));
    opacity: 0;
}
.mdw-gta6-container svg path{
    transform: scale(var(--svg-image-size,1)) translateX(calc(50%/var(--svg-image-size,1) - var(--svg-image-natural-width,0px)/2)) translateY(calc(var(--svg-image-top-gap,0px)/var(--svg-image-size,1)));
}
.mdw-gta6-text{
    bottom: var(--svg-image-top-gap,0px) !important;
}
.mdw-gta6-heading-1 > *{
    background: linear-gradient(to bottom, var(--svg-image-background,#000) calc(var(--gradient-heading-start, 0)*1%), var(--gradient-heading-color-1,#fff) calc(var(--gradient-heading-start, 0)*1% + 70%), var(--gradient-heading-color-2,#fff) calc(var(--gradient-heading-start, 0)*1% + 120%), var(--gradient-heading-color-3,#fff) calc(var(--gradient-heading-start, 0)*1% + 170%));
    background-clip: text;
    -webkit-background-clip: text;
}
@media (min-width:768px){
.mdw-gta6-banner,
.mdw-gta6-container,
.mdw-gta6-container svg{
    height: 500px;
}
}
@media (min-width:1025px){
.mdw-gta6-banner,
.mdw-gta6-container,
.mdw-gta6-container svg{
    height: 600px;
}
}
@media (max-width:767px){
.mdw-gta6-effect{
    --banner-initial-zoom: 0px;
}
.mdw-gta6-effect > *,
.mdw-gta6-effect > *.sticky,
.mdw-gta6-effect > *.sticky-end{
    position: relative !important;
    top: unset !important;
}
.mdw-gta6-banner:before{
    opacity: 1;
    transform: none;
}
.mdw-gta6-container:before{
    opacity: 0 !important;
}
html.elementor-html .mdw-gta6-container:before,
.mdw-gta6-container.svg-added:before{
    opacity: 1 !important;
}
html:not(.elementor-html) .mdw-gta6-container,
html:not(.elementor-html) .mdw-gta6-container > *{
    pointer-events: auto;
}
.mdw-gta6-container > *{
    z-index: 1;
}
.mdw-gta6-container svg,
.mdw-gta6-container > .elementor-element,
.mdw-gta6-heading-1,
.mdw-gta6-heading-2{
    opacity: 1 !important;
}
.mdw-gta6-container svg{
    transform: none !important;
}
.mdw-gta6-heading-1 > *{
    --gradient-heading-start: -70 !important;
}
}
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
if(!MDWNonce118){
var MDWNonce118 = true
;(function($){
var selector = '.mdw-gta6-effect'
$(document).ready(function(){
$(selector).each(function(i){

var $this = $(this),
reached = false,
loaded = false

function getCSS(el, prop, defaultVal = ''){
    var css = getComputedStyle(el[0]).getPropertyValue(prop)
    return css ? css.trim() : defaultVal
}

function setCSS(el, prop, val){
    el[0].style.setProperty(prop, val)
}

function setHDBackground(){
    var hdURL = getCSS($this, '--banner-hd-url')
    if(hdURL){ $this.find('.mdw-gta6-banner').addClass('hd-bg') }
}

function entranceBanner(){
    var image = new Image(),
    banner = $this.find('.mdw-gta6-banner')[0],
    bannerBefore = window.getComputedStyle(banner, '::before'),
    bannerBg = bannerBefore.getPropertyValue('background-image'),
    bannerBgURL = bannerBg.replace(/^url\(["']?/, '').replace(/["']?\)$/, '')
    
    image.src = bannerBgURL
    
    image.onload = function(){
        loaded = true
        if(reached && loaded){ $this.find('.mdw-gta6-banner').addClass('loaded') }
    }
    if(image.complete){
        image.onload()
    }
}

function createSVG(){
    var svgSrc = $this.find('.mdw-gta6-svg img').attr('src')
    
    fetch(svgSrc)
    .then(function(res){
        return res.text()
    })
    .then(function(svgText){
        var parser = new DOMParser(),
        doc = parser.parseFromString(svgText, 'image/svg+xml'),
        svg = doc.querySelector('svg'),
        d = $(svg).find('path').attr('d'),
        svgBackground = getCSS($this, '--svg-image-background', '#000'),
        svgHTML = `<svg>
            <defs>
                <mask class="mdw-gta6-mask" id="mdw-gta6-mask-${i+1}">
                    <rect width="100%" height="100%" fill="white"></rect>
                    <path fill-rule="evenodd" fill="#000000" d="${d}"/>
                </mask>
            </defs>
            <rect width="100%" height="100%" fill="${svgBackground}" mask="url(#mdw-gta6-mask-${i+1})"></rect>
        </svg>`
        
        $this.find('.mdw-gta6-container').prepend(svgHTML).addClass('svg-added')
    })
}

function adjustElements(){
    var svgNaturalWidth = $this.find('.mdw-gta6-svg img')[0].naturalWidth,
    svgNaturalHeight = $this.find('.mdw-gta6-svg img')[0].naturalHeight,
    svgHeight = parseFloat(getCSS($this, '--svg-image-height', 0)),
    svgImageSize = svgHeight/svgNaturalHeight,
    svgBottomGap = parseFloat(getCSS($this, '--svg-image-bottom-gap', 0)),
    topGap = ($this.find('.mdw-gta6-container').outerHeight() - svgHeight - $this.find('.mdw-gta6-text').outerHeight() - svgBottomGap)/2
    
    setCSS($this, '--svg-image-size', svgImageSize)
    setCSS($this.find('.mdw-gta6-container'), '--svg-image-natural-width', svgNaturalWidth + 'px')
    setCSS($this.find('.mdw-gta6-container'), '--svg-image-top-gap', topGap+'px')
}
function init(){
    setHDBackground()
    entranceBanner()
    createSVG()
    adjustElements()
}

function mapRange(value, inMin, inMax, outMin, outMax){
    return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin
}

function limit(value, min, max){
    return Math.max(min, Math.min(value, max))
}
function easing(value, power){
    return 1 - Math.pow((1 - value), power)
}

function setSticky(){
    var rect = $this[0].getBoundingClientRect(),
    inner = $this.children(),
    seenPercentage = 20
    
    rect.top <= 0 ? inner.addClass('sticky') : inner.removeClass('sticky')
    rect.bottom < $(window).height() ? inner.addClass('sticky-end') : inner.removeClass('sticky-end')
    
    if(($(window).height() - rect.top)/$(window).height() > seenPercentage/100){
        reached = true
        if(reached && loaded){ $this.find('.mdw-gta6-banner').addClass('loaded') }
    }
}

function scrollAnimation(){
    var progress = ($(window).scrollTop() - $this.offset().top)/($this.height()-$(window).height()),
    bannerMaxZoom = parseFloat(getCSS($this, '--banner-maximum-zoom', 1)),
    bannerZoom = bannerMaxZoom - (bannerMaxZoom - 1)*easing(limit(mapRange(progress, 0, 0.6, 0, 1), 0, 1), 3),
    bannerValue = 1 - limit(mapRange(progress, 0, 0.3, 0, 1), 0, 1),
    bannerContentTransform = 50,
    overlayOpacity = easing(limit(mapRange(progress, 0.3, 0.6, 0, 1), 0, 1), 2),
    svgOpacity = limit(mapRange(progress, 0, 0.3, 0, 1), 0, 1)
    s = easing(limit(mapRange(progress, 0.3, 0.6, 0, 1), 0, 1), 4),
    svgMaxZoom = parseFloat(getCSS($this, '--svg-image-maximum-zoom', 1)),
    svgZoom = limit(mapRange(s, 0, 1, svgMaxZoom, 1), 1, svgMaxZoom)
    heading1Gradient = limit(mapRange(progress, 0.6, 0.9, 100, -70), -70, 100),
    heading1Opacity = limit(mapRange(progress, 0.6, 0.9, 0.3, 1), 0.3, 1),
    heading2Opacity = limit(mapRange(progress, .7, 1, 0, 1), 0, 1)
    
    setCSS($this, '--banner-zoom', bannerZoom)
    $this.find('.mdw-gta6-banner > *').css({
        'opacity': bannerValue,
        'transform': 'translateY(' + ((bannerValue-1)*bannerContentTransform) + 'px)'
    })
    setCSS($this.find('.mdw-gta6-container'), '--overlay-opacity-2', overlayOpacity)
    $this.find('.mdw-gta6-container svg').css({
        'transform': 'scale(' + svgZoom + ')',
        'opacity': svgOpacity
    })
    if(progress >= .6){
        $this.find('.mdw-gta6-container').addClass('clickable')
    }else{
        $this.find('.mdw-gta6-container').removeClass('clickable')
    }
    setCSS($this.find('.mdw-gta6-heading-1'), '--gradient-heading-start', heading1Gradient)
    $this.find('.mdw-gta6-heading-1').css({'opacity': heading1Opacity})
    $this.find('.mdw-gta6-heading-2').css({'opacity': heading2Opacity})
}

init()
$(window).on('load resize', adjustElements)
$(window).on('load scroll resize', function(){
    setSticky()
    scrollAnimation()
})
})
})
})(jQuery)
}
</script>

<!-- Lenis 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 lenis = new Lenis()
function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
})
</script>