PageSourceSearch

https://www.four25sanpedroapts.com/gridmedia/js/__homepage.js

js four25sanpedroapts.com collected 2026-10-07 07:57:19 UTC 10,024 bytes, 264 lines download raw bytes

1const { animate, scroll, stagger } = Motion;
2
3const stickyNav = document.querySelector('.sticky-nav');
4const heroPanelEl = document.querySelector('.hero-panel');
5const quickLinksSection = document.querySelector('.quick-links-section');
6
7let hasLeftTop = false;
8let showAt = null;
9
10const computeShowAt = () => {
11  if (!quickLinksSection) return null;
12  const rect = quickLinksSection.getBoundingClientRect();
13  return rect.top + window.scrollY;
14};
15
16const onScroll = () => {
17  if (showAt === null) showAt = computeShowAt();
18
19  if (stickyNav && showAt !== null) {
20    if (window.scrollY >= showAt) {
21      stickyNav.classList.add('is-visible');
22    } else {
23      stickyNav.classList.remove('is-visible');
24    }
25  }
26
27  if (window.scrollY > 0) hasLeftTop = true;
28
29//   if (hasLeftTop && window.scrollY === 0 && heroPanelEl) {
30//     heroPanelEl.classList.add('active');
31//   }
32};
33
34window.addEventListener('scroll', onScroll, { passive: true });
35window.addEventListener('resize', () => {
36  showAt = computeShowAt();
37  onScroll();
38});
39
40showAt = computeShowAt();
41onScroll();
42
43
44/// Hero and Swipers ///
45function loadCinemagraph() {
46    const hero = document.querySelector('.hero');
47    const cinemagraph = document.querySelector('.cinemagraph')
48    let currentVideoWidth;
49
50    if (cinemagraph) {
51        const cinemagraphVideo = cinemagraph.querySelector('#cinemagraph_video');
52        const homepageIntroObserver = new ResizeObserver(entries => {
53
54            entries.forEach(entry => {
55                let width = entry.contentRect.width;
56                // Gather all urls and breakpoints
57                let allVideoUrls = {};
58                cinemagraphVideo.querySelectorAll('source').forEach(source => {
59                    allVideoUrls = {
60                        ...allVideoUrls,
61                        [source.dataset.mw]: source.dataset.src
62                    }
63                });
64
65                // select which video dimension should show depending on width
66                if (width < 767) {
67                    return;
68                }
69                if (width < 960 && currentVideoWidth !== 960) {
70                    currentVideoWidth = 960;
71                    cinemagraphVideo.src = allVideoUrls[960];
72                }
73                if ((width >= 960 && width < 1366) && currentVideoWidth !== 1366) {
74                    currentVideoWidth = 1366;
75                    cinemagraphVideo.src = allVideoUrls[1366];
76                }
77                if (width >= 1366 && currentVideoWidth !== 1920) {
78                    currentVideoWidth = 1920;
79                    cinemagraphVideo.src = allVideoUrls[1920];
80                }
81            });
82        });
83        homepageIntroObserver.observe(hero);
84    }
85}
86
87function checkSwiperSlides(swiper) {
88    if(!swiper) return;
89    return (swiper.querySelectorAll('.swiper-slide').length > 1) ? true : false;
90}
91
92function initSwipers() {
93    let heroSwiper = document.querySelector('.hero-swiper');
94    if (checkSwiperSlides(heroSwiper)) {
95        new Swiper(heroSwiper, {
96            loop: true,
97            effect: 'fade',
98            speed: 800,
99            autoplay: {
100                delay: 4000, // delay between transitions in ms
101                disableOnInteraction: true, // continue autoplay when user interacts
102            },
103        });
104    }
105}
106
107function heroPanel(){
108    const panel = document.querySelector('.hero-panel');
109    panel.querySelector('.open-panel').addEventListener('click', () => {panel.classList.add('active')});
110    panel.querySelector('.close-panel').addEventListener('click', () => {panel.classList.remove('active')});
111}
112
113/// Animations ///
114function heroAnimation() {
115    const hero = document.querySelector('.hero');
116    const heroImg = hero.querySelector('.image-bg');
117    const heroPanel = hero.querySelector('.hero-panel');
118    const easeType = 'ease';
119
120    animate(hero, { opacity: 0 });
121
122    useIntersectionObserver(hero, (_) => {
123        animate([
124            [hero, { opacity: [0, 1] }, { duration: 0.1, ease: easeType }],
125            [heroImg, { filter: ['blur(10px)', 'blur(0px)'] }, { duration: .35, at: "+0.1", ease: easeType }],
126            [heroPanel, { opacity: [0, 1] }, { duration: .35, at: "+0.1", ease: easeType }]
127        ])
128    
129        if (window.keepHeroPanelActive) return;
130        
131        setTimeout(() => {
132            document.querySelector('.hero-panel').classList.remove('active');
133        }, 3000);
134    }, { threshold: 0.4 })
135}
136
137function quickLinkAnimation() {
138    const section = document.querySelector('.quick-links-section');
139    const firstImg = section.querySelector('.first-img');
140    const secondImg = section.querySelector('.second-img');
141    const title = section.querySelector('.title');
142    const links = section.querySelectorAll('.link-item');
143    const easeType = 'easeOut';
144
145    animate(section, { opacity: 0 });
146
147    useIntersectionObserver(section, (_) => {
148        animate([
149            [section, { opacity: [0, 1] }, { duration: 0.1 }],
150            [firstImg, { y: [-20, 0], opacity: [0, 1] }, { duration: .35, at: "+0", ease: easeType }],
151            [secondImg, { y: [-20, 0], opacity: [0, 1] }, { duration: .35, at: "+0", ease: easeType }],
152            [title, { x: [-20, 0], opacity: [0, 1] }, { duration: .35, at: "+.02", ease: easeType }],
153            [links, { x: [-5, 0], opacity: [0, 1] }, { duration: .35, at: "+.02", delay: stagger(0.1), ease: easeType }],
154        ])
155    }, { threshold: 0.2 })
156}
157
158function hptOneAnimation() {
159    const section = document.querySelector('.hpt');
160    const text = section.querySelector('.text');
161    const accentImgWrapper = document.querySelector('.accent-image-container');
162    const accentImg = accentImgWrapper.querySelector('.accent-image');
163
164    animate(text, { opacity: 0, y: -10 });
165
166    useIntersectionObserver(section, () => {
167        animate(text, { opacity: 1, y: 0 })
168    }, { threshold: 0.4 })
169
170    animate(accentImg, { scale: 1.02 })
171
172    useIntersectionObserver(accentImgWrapper, () => {
173        animate([
174            [accentImg, { scale: [1.02, 1] }, { duration: 0.35, ease: 'easeOut' }],
175        ])
176    }, { threshold: 0.4 })
177}
178
179function neighborhoodAnimation() {
180    const section = document.querySelector('.neighborhood-section');
181    const bgImg = section.querySelector('.image-bg');
182    const title = section.querySelector('.title');
183    const text = section.querySelector('.text');
184    const button = section.querySelector('.button');
185    const easeType = 'ease';
186
187    animate(section, { opacity: 0 });
188
189    useIntersectionObserver(section, () => {
190        animate([
191            [section, { opacity: [0, 1] }, { duration: 0.1, ease: easeType }],
192            [bgImg, { opacity: [0, 1] }, { duration: 0.25, ease: easeType }],
193            [title, { opacity: [0, 1], y: [-10, 0] }, { duration: 0.4, at: "-.05", ease: easeType }],
194            [text, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: "-.2", ease: easeType }],
195            [button, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: "-.1", ease: easeType }],
196        ])
197    }, { threshold: 0.2 })
198}
199
200function exploreAnimation() {
201    const section = document.querySelector('.explore-community');
202    const columnOneImg = section.querySelector('.column-one');
203    const columnTwoImg = section.querySelector('.image-accent');
204    const title = section.querySelector('.title');
205    const text = section.querySelector('.text');
206    const button = section.querySelector('.button');
207    const easeType = 'ease';
208
209    animate(section, { opacity: 0 });
210
211    useIntersectionObserver(section, () => {
212        animate([
213            [section, { opacity: [0, 1] }, { duration: 0.2, ease: easeType }],
214            [columnOneImg, { opacity: [0, 1], filter: ['blur(10px)', 'blur(0px)'] }, { duration: 0.35, ease: easeType }],
215            [columnTwoImg, { opacity: [0, 1], y: [10, 0] }, { duration: 0.35, ease: easeType }],
216            [title, { opacity: [0, 1], y: [-10, 0] }, { duration: 0.4, at: "-.05", ease: easeType }],
217            [text, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: "-.2", ease: easeType }],
218            [button, { opacity: [0, 1], x: [10, 0] }, { duration: 0.35, at: "<", ease: easeType }],
219        ])
220    }, { threshold: 0.2 })
221}
222
223function floorPlansAnimation() {
224    const section = document.querySelector('.floorplans-section');
225    const fpImg = section.querySelector('.fp-img-wrapper');
226    const fpBgImg = section.querySelector('.right-column');
227    const fpBBText = section.querySelector('.subtext');
228    const title = section.querySelector('.title');
229    const subtitle = section.querySelector('.subtitle');
230    const text = section.querySelector('.text');
231    const button = section.querySelector('.hp-button');
232    const easeType = 'ease';
233
234    animate(section, { opacity: 0 });
235    animate(text, { opacity: 0, x: -10 });
236    animate(button, { opacity: 0, x: -10 });
237
238    useIntersectionObserver(section, () => {
239        animate([
240            [section, { opacity: [0, 1] }, { duration: 0.2, ease: easeType }],
241            [fpImg, { opacity: [0, 1], filter: ['blur(10px)', 'blur(0px)'], x: [-10, 0] }, { duration: 0.35, ease: easeType }],
242            [fpBgImg, { opacity: [0, 0.3] }, { duration: 0.35, at: '<', ease: easeType }],
243            [fpBBText, { opacity: [0, 1], y: [10, 0] }, { duration: 0.35, at: '-0.15', ease: easeType }],
244            [title, { opacity: [0, 1], y: [-10, 0] }, { duration: 0.4, ease: easeType }],
245            [subtitle, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: '-.1', ease: easeType }],
246            [text, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: '-.05', ease: easeType }],
247            [button, { opacity: [0, 1], x: [-10, 0] }, { duration: 0.35, at: '<', ease: easeType }],
248        ])
249    }, { threshold: 0.3 })
250}
251
252function startAnimations() {
253    heroAnimation();
254    quickLinkAnimation();
255    hptOneAnimation();
256    neighborhoodAnimation();
257    exploreAnimation();
258    floorPlansAnimation();
259}
260
261loadCinemagraph();
262initSwipers();
263heroPanel();
264startAnimations();

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.