PageSourceSearch

https://www.lodge-saintehelene.com/wp-content/themes/diadao-021-sd…/js/sdktemplate-animations.js?v=1791245716

js lodge-saintehelene.com collected 2026-10-06 00:15:55 UTC 42,368 bytes, 854 lines download raw bytes

1(function( $ ) {
2    'use strict';   
3    
4    // MARK: DEBUG
5    let m_debugGsap = false;
6    let m_debugScrollTimeOut = true;
7    let m_debugOffcanvas = true;
8    let m_debugFancybox = false;
9
10    // don't touch this palalala
11    let m_scrollTriggerAction = false;
12    let m_scrollTriggerDelay = 1000;
13
14    let m_gsapAnimationsEnabled = true;
15    let m_gsapAnimateH1 = true;
16    let m_gsapAnimateBannerBg = true; 
17    let m_gsapAnimateBannerLogo = true;
18    let m_gsapAnimateBannerContent = true;
19    let m_gsapAnimatePartnerLogo = true;
20
21    // Animations light -> à remettre à true et le paramétrer dans les thèmes uniquement
22    // dans le fichier wp-content/themes/diadao-021-sdktemplate/diadao-starter/config.php
23    let m_gsapAnimationsFullEnabled = window['diadao_sdk_gsap_anims_full_enabled']; // if(m_gsapAnimationsFullEnabled) on active certaines animations que pour la version full
24    if( m_gsapAnimationsFullEnabled ) {
25        if(document.querySelector( '.content-medias.has-medias.media-fullscreen' )) {
26            document.querySelector( '.content-medias.has-medias.media-fullscreen' ).classList.add( 'sdk-animations-full' );
27        }
28    } else {
29        m_gsapAnimateH1 = false;
30        m_gsapAnimateBannerBg = false;
31        m_gsapAnimateBannerLogo = false;
32        m_gsapAnimateBannerContent = false;
33        m_gsapAnimatePartnerLogo = false;
34    }
35 
36    function sdkScrollTriggerRefresh( $origin = null ) {
37        if( m_scrollTriggerAction == false  && ScrollTrigger !== null ) {
38            ScrollTrigger.refresh();
39            m_scrollTriggerAction = true;
40
41            if( m_debugScrollTimeOut ) {
42                console.log( 'scroll refreshed :', $origin );
43            }
44
45            setTimeout(() => {
46                m_scrollTriggerAction = false;
47            }, m_scrollTriggerDelay)
48        }
49    }    
50    
51    window.addEventListener( 'DiadaoWpSdkStarted', event => {
52        startScript();
53    } );
54
55    $(window).on('resize', function() {
56        sdkScrollTriggerRefresh('window resized');
57    });
58    
59    function startScript()
60    {
61        if( m_gsapAnimationsEnabled )
62        {
63            // wait until DOM is ready
64            if( m_debugGsap ) console.log( '-> gsap init ');
65
66            document.querySelector( 'body' ).classList.add( 'sdk-dom-content-loaded' );
67
68            // !!! only for desktop !!!
69            if( document.querySelector( 'body' ).classList.contains( 'device-desktop' )) {
70                console.log('ok before lenis init');
71                
72                // MARK: init LENIS smooth scroll
73                const lenis = new Lenis();
74                lenis.on('scroll', ScrollTrigger.update);
75                gsap.ticker.add((time)=> {
76                    lenis.raf(time * 1000);
77                })
78                gsap.ticker.lagSmoothing(0);
79
80                // handle SDK offcanvas panels with lenis
81                window.addEventListener( 't_sdkbsOffCanvasChanged', (e) => {   
82                    
83                    if( m_debugOffcanvas ) console.log("event t_sdkbsOffCanvasChanged received", e.detail);
84
85                    const popupStarted = sessionStorage.getItem('popupStarted') === 'true';
86                    
87                    if( e.detail > 0 ) {
88                        stopLenis();
89                    }
90                    if( e.detail == 0 ) {
91                        startLenis();
92                    }
93                })
94
95                // handle SDK Fancybox panels with lenis
96                window.addEventListener( 'fancyBoxOpen', (e) => {   
97                    if( m_debugFancybox ) console.log("event fancyBoxOpen received");
98                    
99                    // si on n'est pas déjà dans un panneau (exemple panneau chambre)
100                    if( !document.querySelector( 'body' ).classList.contains( 'sdkbs-panel-opened' )) {
101                        stopLenis(); 
102                    }
103                });
104                window.addEventListener( 'fancyBoxClose', (e) => {   
105                    if( m_debugFancybox ) console.log("event fancyBoxClose received");
106
107                    // si on n'est pas déjà dans un panneau (exemple panneau chambre)
108                    if( !document.querySelector( 'body' ).classList.contains( 'sdkbs-panel-opened' )) {
109                        startLenis(); 
110                    }
111                });
112
113                // MARK: lenis on panel opened : Smart Display Popup
114                window.addEventListener( 'smartPopUpOpen', stopLenis );
115                window.addEventListener( 'smartPopUpClose', startLenis );
116                
117                function stopLenis() {
118                    lenis.stop();
119                }
120                
121                function startLenis() {
122                    lenis.start();
123                }
124
125                // if url hash is an anchor and not a bootstrap panel  
126                window.addEventListener( 'anchorScrollTo', (e) => anchorScrollTo( e.detail ) );
127
128                function anchorScrollTo( anchorTarget )
129                {
130                    lenis.scrollTo(anchorTarget, {offset: -(navbarButton.offsetHeight), lerp: 0.1})
131                }
132
133                // MARK: anchors links with Lenis smooth scroll
134                let anchorLinks = document.querySelectorAll( '#header-menu-anchors li a[href^="#"], .sdk-anchor-link[href^="#"]' )
135
136                if( anchorLinks.length > 0 )
137                {
138                    anchorLinks.forEach( function(anchorLink) 
139                    {
140                        anchorLink.addEventListener( 'click', (e) => {
141                            const anchorLinkHref = e.currentTarget.attributes.href.value;
142
143                            if(document.querySelector( anchorLinkHref )) {
144                                e.preventDefault();
145                                anchorScrollTo(anchorLinkHref);
146                            }
147                        })
148                    })
149                }
150
151                // MARK: filters links with Lenis smooth scroll
152                let filtersLinks = document.querySelectorAll( '.nav-link.link-filter' );
153                let navbarButton = document.querySelector( '.anim_header_buttons_left' );
154
155                if( filtersLinks.length > 0 )
156                {
157                    filtersLinks.forEach( function(filtersLink) 
158                    {
159                        filtersLink.addEventListener( 'click', (e) => {
160                            e.preventDefault();
161                            // on remonte juste au niveau du container en cas de scroll
162                            lenis.scrollTo('.dia-smartgallery__wrapper', {offset: -(navbarButton.offsetHeight)});
163                        })
164                    })
165                }
166            }
167            // MARK: End Lenis
168            
169            if( document.querySelector( 'body' ).classList.contains( 'device-mobile' )) {
170
171                let navbarButton = document.querySelector( '.anim_header_buttons_left' );
172                
173                // MARK: handle offers filters links for mobile (without Lenis smooth scroll)
174                let filtersLinks = document.querySelectorAll( '.nav-link.link-filter' );
175                let target = document.querySelector('.offers-listing');
176
177                if( filtersLinks.length > 0 )
178                {
179                    filtersLinks.forEach( function(filtersLink) 
180                    {
181                        filtersLink.addEventListener( 'click', (e) => {
182                            console.log('target: ', target);
183                            let elementPosition = target.getBoundingClientRect().top + document.documentElement.scrollTop;
184                            console.log('elementPosition: ', elementPosition);
185                            let offsetPosition = elementPosition - navbarButton.offsetHeight;
186                            console.log('offsetPosition: ', offsetPosition);
187                            e.preventDefault();
188                            // on remonte juste au niveau du container en cas de scroll
189                            window.scrollTo({
190                                top : offsetPosition,
191                                left: 0,
192                                behavior: "smooth",
193                            })
194                        })
195                    })
196                }
197
198                // if url hash is an anchor and not a bootstrap panel  
199                window.addEventListener( 'anchorScrollTo', (e) => anchorScrollToMobile( e.detail ) );
200
201                function anchorScrollToMobile( anchorTarget )
202                {
203                    let anchorTargetElement = document.getElementById(anchorTarget.replace( '#', '' ));
204                    let elementPosition = anchorTargetElement.offsetTop;
205                    // let offsetPosition = elementPosition - navbarButton.offsetHeight
206
207                    if( anchorTargetElement !== undefined && anchorTargetElement !== null )
208                    {
209                        window.scrollTo({
210                            top : elementPosition,
211                            left: 0,
212                            behavior: "smooth",
213                        })
214                    }
215                }
216
217                // MARK: handle anchor links for mobile (without Lenis smooth scroll)
218                let anchorLinks = document.querySelectorAll( '#header-menu-anchors li a, .sdk-anchor-link' );
219
220                if( anchorLinks.length > 0 )
221                {
222                    anchorLinks.forEach( function(anchorLink) 
223                    {
224                        anchorLink.addEventListener( 'click', (e) => {
225                            e.preventDefault();
226                            const anchorLinkHref = e.currentTarget.attributes.href.value;
227                            anchorScrollToMobile(anchorLinkHref);
228                        })
229                    })
230                }
231            }
232
233            // MARK: handle accordion height change and force scrollTrigger refresh
234            let myCollapsible = document.querySelectorAll('.accordion-collapse');
235            if( myCollapsible.length > 0 )
236            {
237                myCollapsible.forEach( function( elem ) 
238                {
239                    elem.addEventListener('hidden.bs.collapse', function () {
240                        sdkScrollTriggerRefresh('accordion closed');
241                    })
242                    elem.addEventListener('shown.bs.collapse', function () {
243                        sdkScrollTriggerRefresh( 'accordion opened' );
244                    })
245                })
246            }
247
248
249            // "TRY TO" refresh scrollTrigger when gallery loaded (not finished yet)
250            window.addEventListener( 'initUniteGallery', event => {
251                sdkScrollTriggerRefresh( 'initUniteGallery' );
252                
253                setTimeout(() => {
254                    sdkScrollTriggerRefresh( 'initUniteGallery' );
255                }, 4000);
256
257            });
258
259            // refresh gform
260            window.addEventListener( 'sdkGformRefresh', sdkScrollTriggerRefresh( 'sdkGformRefresh' ) );
261
262            // refresh after swiper init
263            window.addEventListener( 'sdkSwiperInitRefresh', event => {                
264                setTimeout(() => {
265                    sdkScrollTriggerRefresh( 'sdkSwiperInitRefresh' );
266                }, 1000); // needed because of previous gform refresh and delay in function
267
268            });
269            // window.addEventListener( 'sdkSwiperInitRefresh', sdkScrollTriggerRefresh( 'sdkSwiperInitRefresh' ) );
270
271            // MARK: close lang menu if scroll is detected
272            const langDropdown = document.querySelector( '.dropdown.lang-menu .dropdown-toggle' );
273            const langMenu = document.querySelector( '.dropdown.lang-menu .dropdown-menu' );
274            if( 
275                langDropdown && langDropdown.length 
276                && langMenu && langMenu.length 
277            )
278            {
279                const bootstrapLangMenu = new bootstrap.Dropdown(langMenu);
280                const bootstrapLangDropdown = new bootstrap.Dropdown(langDropdown);
281                langDropdown.addEventListener('show.bs.dropdown', event => {
282                    document.addEventListener("scroll", (e) => {
283                        bootstrapLangDropdown.hide();
284                        bootstrapLangMenu.hide();
285                    })
286                })
287            }
288
289
290            // MARK: Scroll animations
291
292            let mm = gsap.matchMedia(),
293                breakPoint = 992
294            
295            // MARK: Hero 
296            const h1TitleElement = document.querySelector('.banner__h1-title');
297            const partnerLogo = document.querySelector('.banner__partner-logo');
298            const bannerContent = document.querySelector('.banner__content');
299            const bannerBackgroundImg = document.querySelector('.banner__background img');
300            const bannerBackgroundVideoButton = document.querySelector('.banner__background .button-video');
301
302            // Animation de la banner au scroll
303            const bannerScrubTimeline = gsap.timeline({
304                scrollTrigger: {
305                    trigger: '.banner', 
306                    start: "top",
307                    ease: "power1.inOut",
308                    toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
309                    scrub: true,
310                    // markers: true,
311                },
312            })
313
314            if(m_gsapAnimationsFullEnabled) {
315                bannerScrubTimeline.set( '.banner__background', { position: 'fixed' } );
316            } else {
317                bannerScrubTimeline.set( '.banner__background', { position: 'fixed' } );
318                // bannerScrubTimeline.fromTo( '.banner__background', { autoAlpha: 1 }, { autoAlpha: 0 } )
319            }
320
321            // if( !m_gsapAnimateBannerBg )
322            // {
323            //     jQuery('.banner__background').css( 'opacity', 1 );
324            // }
325            // if( !m_gsapAnimateBannerContent )
326            // {
327            //     jQuery('.banner__content').css( 'opacity', 1 );
328            // }
329            // if( !m_gsapAnimateH1 )
330            // {
331            //     jQuery('.banner__h1-title').css( 'opacity', 1 );
332            // }
333
334            if( bannerBackgroundImg && m_gsapAnimateBannerBg ) {
335                bannerScrubTimeline.fromTo( bannerBackgroundImg, { scale: 1 }, { scale: 1.4 } );
336            }
337
338            if( bannerContent && m_gsapAnimateBannerContent ) {
339                bannerScrubTimeline.fromTo( bannerContent, { autoAlpha: 1, yPercent: 0 }, { autoAlpha: 0, yPercent: -60, duration: .5 }, "<" );
340            }
341
342            if( h1TitleElement && m_gsapAnimateH1 ) {
343                bannerScrubTimeline.fromTo( h1TitleElement, { autoAlpha: 1, y: 0 }, { autoAlpha: 0, y: -200, duration: .5 }, "<" );
344            }
345            
346            if( bannerBackgroundVideoButton ) {
347                bannerScrubTimeline.fromTo( bannerBackgroundVideoButton, { autoAlpha: 1, y: 0 }, { autoAlpha: 0, y: -200, duration: .5 }, "<" );
348            }
349
350            if( partnerLogo && m_gsapAnimatePartnerLogo ) {
351                bannerScrubTimeline.fromTo( partnerLogo, { autoAlpha: 1, y: 0 }, { autoAlpha: 0, y: -200, duration: .5 }, "<" );
352            }
353
354            // Animation de la banner au chargement
355            mm.add("(min-width: 992px)", () => {
356                const bigTitleElement = document.querySelector('.banner__big-title');
357                const bannerLogo = document.querySelector('.banner__logo');
358                const bannerScrollDown = document.querySelector('.anim_intro_scrolldown');
359                const bannerTimeline = gsap.timeline();
360
361                if( bannerLogo && m_gsapAnimateBannerLogo ) {
362                    bannerTimeline.fromTo( bannerLogo, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, duration: 1}, "<" );
363                }
364                
365                if( bigTitleElement && m_gsapAnimateBannerContent ) {
366                    bannerTimeline.fromTo( bigTitleElement, { autoAlpha: 0, y: -80 }, { autoAlpha: 1, y: 0, duration: 0.5 }, "<" );
367                    // bannerTimeline.fromTo( bigTitleElement, { autoAlpha: 0, y: -80 }, { autoAlpha: 1, y: 0, duration: 0.5 }, ">-0.1" )
368                }
369
370                if( h1TitleElement && m_gsapAnimateH1 ) {
371                    bannerTimeline.fromTo( h1TitleElement, { autoAlpha: 0, xPercent: -100 }, { autoAlpha: 1, xPercent: 0 }, "<" );
372                }
373                
374                bannerTimeline.fromTo( '.anim_header_buttons_left, .anim_header_buttons_right', { y: -200 }, { y: 0, duration: 0.5 }, "<" );
375                
376                if( bannerScrollDown ) {
377                    bannerTimeline.fromTo( bannerScrollDown, { autoAlpha: 0, y: 100 }, { autoAlpha: 1, y: 0, duration: 0.5 }, "<" );
378                }
379
380                bannerTimeline.to( '.banner__background', { autoAlpha: 1, duration: .5 }, "<" );
381            })
382
383            // MARK: Fade Up
384            const fadeUp = gsap.utils.toArray('.content-medias.media-fullscreen:not(.big-fullscreen-title) .content-medias__content, .thumbnails-list__title, .images-blocks__title, .icons-list__title, .practical-infos__title, .practical-infos__accordion, .practical-infos__list, .customers-reviews__titles');
385
386            fadeUp.forEach((item, i) => {
387                mm.add({
388                    isDesktop: `(min-width: ${breakPoint}px)`,
389                    isMobile: `(max-width: ${breakPoint - 1}px)`
390                }, (context) => {
391                    let { isDesktop, isMobile } = context.conditions;
392                    const fadeUpTimeline = gsap.timeline({
393                        scrollTrigger: {
394                            trigger: item, 
395                            start: isDesktop ? "top 70%" : "top 80%",
396                            ease: "power1.inOut",
397                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
398                            // markers: true,
399                        },
400                    })
401                    fadeUpTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 } );
402                })
403            })
404            
405            // MARK: content-medias Text Fade Up
406            const contentMediasContent = gsap.utils.toArray('.content-medias.media-solo .content-medias__content, .content-medias.media-trio .content-medias__content, .content-medias.map .content-medias__content, .content-medias.instagram .content-medias__content, .content-medias.text-centered .content-medias__content');
407
408            contentMediasContent.forEach((item, i) => {
409                const titleElement = item.querySelector('.content-medias__content__title');
410                const textElement = item.querySelector('.content-medias__content__text');
411                const linkElement = item.querySelector('.content-medias__content__link');
412                const buttonsElement = item.querySelector('.content-medias__content__buttons');
413
414                mm.add({
415                    isDesktop: `(min-width: ${breakPoint}px)`,
416                    isMobile: `(max-width: ${breakPoint - 1}px)`
417                }, (context) => {
418                    let { isDesktop, isMobile } = context.conditions;
419                    const contentMediasContentTimeline = gsap.timeline({
420                        scrollTrigger: {
421                            trigger: item, 
422                            start: isDesktop ? "top 70%" : "top 80%",
423                            ease: "power1.inOut",
424                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
425                            // markers: true,
426                        },
427                    })
428                    
429                    if( titleElement ) { contentMediasContentTimeline.fromTo( titleElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 } ) }
430                    if( textElement ) { contentMediasContentTimeline.fromTo( textElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
431                    if( linkElement ) { contentMediasContentTimeline.fromTo( linkElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
432                    if( buttonsElement ) { contentMediasContentTimeline.fromTo( buttonsElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
433                })
434
435            })
436            
437            // MARK: content-medias Media Solo with content Left & Right
438            const contentMediasSolo = gsap.utils.toArray('.content-medias.media-solo.content-left .content-medias__super-media, .content-medias.media-solo.content-right .content-medias__super-media, .content-medias.instagram .content-medias__instagram');
439
440            contentMediasSolo.forEach((item, i) => {
441                const contentMediasSoloTimeline = gsap.timeline({
442                    scrollTrigger: {
443                        trigger: item, 
444                        start: "top 80%",
445                        ease: "power1.inOut",
446                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
447                    },
448                })
449                const contentMediasSoloScrubTimeline = gsap.timeline({
450                    scrollTrigger: {
451                        trigger: item, 
452                        start: "top 80%",
453                        end: "top 20%",
454                        ease: "power1.inOut",
455                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
456                        scrub: true,
457                        // markers: true,
458                    },
459                })
460                contentMediasSoloTimeline.fromTo( item, { autoAlpha: 0, scale: .8 }, { autoAlpha: 1, scale: 1 } );
461
462                mm.add("(min-width: 992px)", () => {
463                    contentMediasSoloScrubTimeline.fromTo( item, { yPercent: 10 }, { yPercent: -10 } );
464                })
465            })
466            
467            // MARK: content-medias Media Trio
468            const contentMediaTrio = gsap.utils.toArray('.content-medias.media-trio');
469
470            contentMediaTrio.forEach((item, i) => {
471                const superMediaElement = item.querySelector('.content-medias__super-media');
472                const image1Element = item.querySelector('.content-medias__image-1');
473                const image2Element = item.querySelector('.content-medias__image-2');
474
475                const contentMediaTrioTimeline = gsap.timeline({
476                    scrollTrigger: {
477                        trigger: item, 
478                        start: "top 90%",
479                        ease: "power1.inOut",
480                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
481                        // markers: true,
482                    },
483                })
484                const contentMediaTrioTimelineScrub = gsap.timeline({
485                    scrollTrigger: {
486                        trigger: item, 
487                        start: "top 100%",
488                        end: 'bottom 0',
489                        ease: "power1.inOut",
490                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
491                        scrub: 1,
492                        // markers: true,
493                    },
494                })
495                contentMediaTrioTimeline.fromTo( superMediaElement, { autoAlpha: 0, scale: 0.5 }, { autoAlpha: 1, scale: 1 } );
496                contentMediaTrioTimeline.fromTo( image1Element, { autoAlpha: 0, scale: 0.5 }, { autoAlpha: 1, scale: 1 } );
497                contentMediaTrioTimeline.fromTo( image2Element, { autoAlpha: 0, scale: 0.5 }, { autoAlpha: 1, scale: 1 } );
498
499                mm.add("(min-width: 992px)", () => {
500                    // desktop setup code here...
501                    contentMediaTrioTimelineScrub.fromTo( superMediaElement, { y: 50 }, { y: -50 } );
502                    contentMediaTrioTimelineScrub.fromTo( image1Element, { y: 0 }, { y: 100 }, "<" );
503                    contentMediaTrioTimelineScrub.fromTo( image2Element, { y: 0 }, { y: 100 }, "<" );
504                })
505            })
506            
507            // MARK: content-medias Media Solo fullwidth
508            const contentMediaSolo = gsap.utils.toArray('.content-medias.media-solo.content-fullwidth .content-medias__super-media');
509
510            contentMediaSolo.forEach((item, i) => {
511                const contentMediasSoloTimeline = gsap.timeline({
512                    scrollTrigger: {
513                        trigger: item, 
514                        start: m_gsapAnimationsFullEnabled ? "top 90%": "top 60%",
515                        ease: "power1.inOut",
516                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
517                        // markers: true,
518                    },
519                })
520                const contentMediaSoloScrubTimeline = gsap.timeline({
521                    scrollTrigger: {
522                        trigger: item, 
523                        start: "bottom bottom",
524                        end: 'top 25%',
525                        ease: "power1.inOut",
526                        toggleActions: "play none none reverse",
527                        scrub: 1,
528                        // markers: true,
529                    },
530                })
531                
532                if(m_gsapAnimationsFullEnabled) {
533                    contentMediasSoloTimeline.fromTo( item, { autoAlpha: 0 }, { autoAlpha: 1 } );
534                    contentMediaSoloScrubTimeline.fromTo( item, { scale: 0.5 }, { scale: 1 } );
535                } else {
536                    contentMediasSoloTimeline.fromTo( item, { clipPath: 'polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%)' }, { clipPath: 'polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)', duration: 1 } );
537                }
538            })
539                
540            
541
542            // MARK: Anim BG 
543            // const animBackground = gsap.utils.toArray('.anim-bg-content:not(.anim-bg-media-fullscreen)')
544            
545            if(m_gsapAnimationsFullEnabled) {
546                const animBackground = gsap.utils.toArray('.anim-bg-content');
547                if( animBackground !== undefined ) {
548                    animBackground.forEach((item, i) => {
549                        mm.add({
550                            isDesktop: `(min-width: ${breakPoint}px)`,
551                            isMobile: `(max-width: ${breakPoint - 1}px)`
552                        }, (context) => {
553                            let { isDesktop, isMobile } = context.conditions;
554                            const animBackgroundScrubTimeline = gsap.timeline({
555                                scrollTrigger: {
556                                    trigger: item, 
557                                    start: () => isDesktop ? "top 60%" : "top 60%",
558                                    end: () => isDesktop ? "top 20%" : "top 20%",
559                                    ease: "power1.inOut",
560                                    toggleActions: "play none none reverse",
561                                    scrub: 1,
562                                    // markers: true,
563                                }
564                            })
565                            animBackgroundScrubTimeline.fromTo( item, { position: 'absolute', autoAlpha: 0 }, { position: 'fixed', autoAlpha: 1  } );
566                        })
567                    })
568                }
569            } else {
570                // MARK: FOOTER Anim BG            
571    
572                // const animFooterBackground = document.querySelector('footer .anim-bg-content');
573                // if( animFooterBackground !== undefined ) {
574                //     mm.add({
575                //         isDesktop: `(min-width: ${breakPoint}px)`,
576                //         isMobile: `(max-width: ${breakPoint - 1}px)`
577                //     }, (context) => {
578                //         let { isDesktop, isMobile } = context.conditions;
579                //         const animFooterBackgroundTimeline = gsap.timeline({
580                //             scrollTrigger: {
581                //                 trigger: animFooterBackground, 
582                //                 start: () => isDesktop ? "top 60%" : "top 60%",
583                //                 end: () => isDesktop ? "top 20%" : "top 20%",
584                //                 ease: "power1.inOut",
585                //                 toggleActions: "play none none none",
586                //                 scrub: 1,
587                //                 // markers: true,
588                //             }
589                //         })
590                //         animFooterBackgroundTimeline.fromTo( animFooterBackground, { position: 'absolute', autoAlpha: 0 }, { position: 'fixed', autoAlpha: 1  } );
591                //     })
592                // }
593            }
594           
595
596            
597            // MARK: Anim BG fullscreen content medias with super media scale
598            const mediaFullscreen = gsap.utils.toArray('.content-medias.has-medias.media-fullscreen');
599
600            if( m_gsapAnimationsFullEnabled ) {
601                if( mediaFullscreen !== undefined && mediaFullscreen !== null) {
602                    mediaFullscreen.forEach((item, i) => {
603                        const superMediaBgElement = item.querySelector('.anim-bg-media-fullscreen');
604                        mm.add({
605                            isDesktop: `(min-width: ${breakPoint}px)`,
606                            isMobile: `(max-width: ${breakPoint - 1}px)`
607                        }, (context) => {
608                            let { isDesktop, isMobile } = context.conditions;
609                            const scaleBackgroundImageTimeline = gsap.timeline({
610                                scrollTrigger: {
611                                    trigger: superMediaBgElement, 
612                                    // start: isDesktop ? "top 100%" : "top 60%",
613                                    // end: isDesktop ? "bottom 0%" : "bottom 20%",
614                                    start: isDesktop ? "top 60%" : "top 80%",
615                                    end: isDesktop ? "bottom 20%" : "bottom 30%",
616                                    ease: "power1.inOut",
617                                    toggleActions: "play none none reverse",
618                                    scrub: 1,
619                                    // markers: true,
620                                }
621                            })
622
623                            // sctintillement sur Mac Rétina --> semble se produire quand on est en partage d'écran uniquement donc pb ressources, on le laisse 
624                            if( superMediaBgElement && superMediaBgElement !== undefined ) {
625                                mm.add("(max-width: 639px)", () => {
626                                    scaleBackgroundImageTimeline.fromTo( superMediaBgElement, { xPercent: -50 }, { xPercent: 0 } );
627                                })
628                                mm.add("(min-width: 640px)", () => {
629                                    scaleBackgroundImageTimeline.fromTo( superMediaBgElement, { scale: 1.4 }, { scale: 1 } );
630                                })
631                            }
632                        })
633                    })
634                }
635            }
636
637            // MARK: Anim BG Highlights with super media scale
638            const highlightsMedia = gsap.utils.toArray('.highlights');
639
640            if( m_gsapAnimationsFullEnabled ) {
641                if( highlightsMedia.length > 0 && highlightsMedia !== null) {
642                    highlightsMedia.forEach((item, i) => {
643                        const highlightsContainer = item.querySelector('.highlights__container');
644                        const highlightsBgElement = item.querySelectorAll('.anim-bg-content.anim-bg-highlights');
645
646                        mm.add({
647                            isDesktop: `(min-width: ${breakPoint}px)`,
648                            isMobile: `(max-width: ${breakPoint - 1}px)`
649                        }, (context) => {
650                            let { isDesktop, isMobile } = context.conditions;
651                            const scaleBackgroundImageTimeline = gsap.timeline({
652                                scrollTrigger: {
653                                    trigger: highlightsContainer, 
654                                    // start: isDesktop ? "top 100%" : "top 60%",
655                                    // end: isDesktop ? "bottom 0%" : "bottom 20%",
656                                    start: isDesktop ? "top 60%" : "top 60%",
657                                    end: isDesktop ? "bottom 20%" : "bottom 30%",
658                                    ease: "power1.inOut",
659                                    toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
660                                    scrub: 1,
661                                    // markers: true,
662                                }
663                            })
664                            
665                            // Retiré pour l'instant à cause du sctintillement sur Mac Rétina
666                            if( highlightsBgElement && highlightsBgElement !== undefined ) {
667                                mm.add("(max-width: 639px)", () => {
668                                    scaleBackgroundImageTimeline.fromTo( highlightsBgElement, { xPercent: -50 }, { xPercent: 0 } );
669                                })
670                                mm.add("(min-width: 640px)", () => {
671                                    scaleBackgroundImageTimeline.fromTo( highlightsBgElement, { scale: 1.4 }, { scale: 1 } );
672                                })
673                            }
674                        })
675                    })
676                }
677            }
678
679            // MARK: Fullscreen big title (without text)
680            const bigTitleSlideLeft = gsap.utils.toArray('.content-medias.media-fullscreen.big-fullscreen-title .content-medias__content__title');
681
682            if( bigTitleSlideLeft !== undefined ) {
683                bigTitleSlideLeft.forEach((item, i) => {
684                    const bigTitleSlideLeftTimeline = gsap.timeline({
685                        scrollTrigger: {
686                            trigger: '.content-medias.media-fullscreen.big-fullscreen-title', 
687                            start: "top 100%",
688                            end: "bottom 0%",
689                            ease: "power1.inOut",
690                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
691                            scrub: true,
692                            // markers: true,
693                        },
694                    })           
695                    bigTitleSlideLeftTimeline.fromTo( item, { position: 'absolute', xPercent: 110 }, { position: 'fixed', xPercent: -110 } );
696                })
697            }
698
699
700            // MARK: Icons List
701            const iconsList = gsap.utils.toArray('.icons-list .list__item');
702
703            if( iconsList !== undefined ) {
704                iconsList.forEach((item, i) => {
705                    const iconsListTimeline = gsap.timeline({
706                        scrollTrigger: {
707                            trigger: ".icons-list .list__wrapper", 
708                            start: "top 80%",
709                            ease: "power1.inOut",
710                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
711                            // markers: true,
712                        }
713                    })
714                    iconsListTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, delay: i * .05, duration: 1 } );
715                })
716            }
717
718            // MARK: Reviews List
719            const reviewsList = gsap.utils.toArray('.reviews .reviews__item');
720
721            if( reviewsList !== undefined ) {
722                reviewsList.forEach((item, i) => {
723                    const reviewsListTimeline = gsap.timeline({
724                        scrollTrigger: {
725                            trigger: ".customers-reviews__container", 
726                            start: "top 80%",
727                            ease: "power1.inOut",
728                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
729                            // markers: true,
730                        }
731                    })
732                    reviewsListTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, delay: i * .05, duration: 1 } );
733                })
734            }
735
736            // MARK: Thumbnails List -> impossible à cibler via le BO pour les swipers
737            const thumbnailsList = gsap.utils.toArray('.thumbnails-list .list__item');
738
739            if( thumbnailsList !== undefined ) {
740                thumbnailsList.forEach((item, i) => {
741                    const thumbnailsListTimeline = gsap.timeline({
742                        scrollTrigger: {
743                            trigger: ".thumbnails-list .thumbnails-list__swiper", 
744                            start: "top 80%",
745                            ease: "power1.inOut",
746                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
747                            // markers: true,
748                        }
749                    })
750                    thumbnailsListTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, delay: i * .05, duration: 1 } );
751                })
752            }
753
754            // MARK: Images Blocks
755            const imagesBlocks = gsap.utils.toArray('.images-blocks .list__item');
756
757            if( imagesBlocks !== undefined ) {
758                imagesBlocks.forEach((item, i) => {
759                    const imagesBlocksTimeline = gsap.timeline({
760                        scrollTrigger: {
761                            trigger: item, 
762                            start: "top 95%",
763                            ease: "power1.inOut",
764                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
765                            // markers: true,
766                        }
767                    })
768                    imagesBlocksTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, delay: i * .05, duration: 1 } );
769                })
770            }
771
772            // MARK: Rooms Blocks
773            const roomsItems = gsap.utils.toArray('.thumbs-content.v-rooms .diadao-room-item');
774
775            if( roomsItems !== undefined ) {
776                roomsItems.forEach((item, i) => {
777                    const roomsTimeline = gsap.timeline({
778                        scrollTrigger: {
779                            trigger: item, 
780                            start: "top 95%",
781                            ease: "power1.inOut",
782                            toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
783                            // markers: true,
784                        }
785                    })
786                    roomsTimeline.fromTo( item, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0, delay: i * .05, duration: 1 } );
787                })
788            }
789
790            // MARK: Footer Text Fade Up
791            const footerContent = gsap.utils.toArray('#footer.footer');
792
793            footerContent.forEach((item, i) => {
794                const logoElement = item.querySelector('.footer__logo');
795                const infosElement = item.querySelector('.footer__infos');
796                const contactElement = item.querySelector('.footer__contact');
797                const socialsElement = item.querySelector('.footer__socials');
798                const partnersElement = item.querySelector('.footer__partners');
799                const legalsElement = item.querySelector('.footer__legals');
800
801                const footerContentTimeline = gsap.timeline({
802                    scrollTrigger: {
803                        trigger: item, 
804                        start: "top 70%",
805                        ease: "power1.inOut",
806                        toggleActions: m_gsapAnimationsFullEnabled ? "play none none reverse" : "play none none none",
807                        // markers: true,
808                    },
809                })
810
811                if( logoElement ) { footerContentTimeline.fromTo( logoElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 } ) }
812                if( infosElement ) { footerContentTimeline.fromTo( infosElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
813                if( contactElement ) { footerContentTimeline.fromTo( contactElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
814                if( socialsElement ) { footerContentTimeline.fromTo( socialsElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
815                if( partnersElement ) { footerContentTimeline.fromTo( partnersElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
816                if( legalsElement ) { footerContentTimeline.fromTo( legalsElement, { autoAlpha: 0, y: 80 }, { autoAlpha: 1, y: 0 }, ">-0.2" ) }
817            })
818        }
819        else
820        {
821            
822        }
823    }
824
825    // Animation de curseur dynamique
826    /*
827    const roomsContainer = document.querySelector('#rooms-container');
828    const roomItemCursor = roomsContainer.querySelector('.thumb-cursor');
829    roomsContainer.addEventListener("mousemove", cursorControl);
830
831    function cursorControl(e) {
832        let x = e.clientX;
833        let y = e.clientY;
834        roomItemCursor.style.top = y + 'px';
835        roomItemCursor.style.left = x + 'px';
836    }
837
838    const roomItemLink = document.querySelectorAll('.diadao-room-item .thumb-infos');
839
840    roomItemLink.forEach(item => {
841        item.addEventListener('mouseenter', () => {
842            roomItemCursor.classList.add('hover');
843        });
844        item.addEventListener('mouseleave', () => {
845            roomItemCursor.classList.remove('hover');
846        });
847    })
848    */
849
850    /* 
851    Pour les staggers ou fade-up en global cf Anatura portail
852    */
853   
854})( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.