1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8" /> 5 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"/> 7 <title>Luxury Real Estate Agency Dubai - Nestwood Realty</title> 8 <!-- <link rel="stylesheet" href="/assets/frontend/css/style.css?v=3.8" /> --> 9 <!-- Critical first-party CSS: render-blocking (needed for above-the-fold layout) --> 10 <link rel="stylesheet" href="/assets/frontend/css/style_minify.css?v=1.8" /> 11 12 <!-- Speed up the async third-party requests below --> 13 <link rel="preconnect" href="https://unpkg.com" crossorigin> 14 <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin> 15 <link rel="preconnect" href="https://fonts.googleapis.com"> 16 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 17 18 <!-- Non-critical CSS (JS-driven sliders, smooth-scroll, web font): load async so it 19 doesn't block first render. media="print" + onload swap applies it once downloaded. --> 20 <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/lenis.css" media="print" onload="this.media='all'"> 21 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css" media="print" onload="this.media='all'"> 22 <link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.css" media="print" onload="this.media='all'"> 23 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap" media="print" onload="this.media='all'"> 24 <noscript> 25 <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/lenis.css"> 26 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css"> 27 <link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.css"> 28 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap"> 29 </noscript> 30 <link rel="icon" type="image/png" href="/assets/frontend/images/favicon.png"> 31 <link rel="canonical" href="https://nestwoodrealty.com/blogs" /> 32 <!-- Google Tag Manager -->
33<script>
vendor: 331 bytes, lines 33-37
33(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 34new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 35j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 36'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 37})(window,document,'script','dataLayer','
37GTM-PX8XF329
vendor: 3 bytes, line 37
37');
37</script>
37 38<!-- End Google Tag Manager --> 39 40</head> 41<body> 42 <!-- protection removed: right-click, copy & selection re-enabled --> 43 44<!-- Google Tag Manager (noscript) -->
vendor: 69 bytes, lines 44-45
44 45<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
45GTM-PX8XF329
vendor: 85 bytes, lines 45-46
45" 46height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
47<!-- End Google Tag Manager (noscript) --> 48 49 50<section class="banner_area_main banner_area_main_inner"> 51 <div class="banner_main_content"> 52 <div class="banner_up_search_area"> 53 <h1>Our Blogs</h1> 54 </div> 55 </div> 56</section> 57 58 59<!-- Header Area Main Start --> 60 61<section class="main_header_area"> 62 63 <div class="header_left"> 64 <a aria-label="Logo" href="/"><img src="/assets/frontend/images/logo.png" alt="img"></a> 65 </div> 66 <div class="header_menu"> 67 <div class="cls_menu"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.9997 10.5865L16.9495 5.63672L18.3637 7.05093L13.4139 12.0007L18.3637 16.9504L16.9495 18.3646L11.9997 13.4149L7.04996 18.3646L5.63574 16.9504L10.5855 12.0007L5.63574 7.05093L7.04996 5.63672L11.9997 10.5865Z"></path></svg></div> 68 <ul> 69 <li><a aria-label="home" href="/">Home</a></li> 70 <li><a aria-label="about us" href="/about-us">About us</a></li> 71 <li class="mobile_dropdown mobile_dropdown1"><a href="/properties">Properties</a> 72 <span class="propert_toggle"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"></path></svg></span> 73 <div class="sub_menu property_submenu"> 74 <ul> 75 76 77 <li><a aria-label="Property name" href="/properties-statuses/ready">Ready</a></li> 78 79 <li><a aria-label="Property name" href="/properties-statuses/off-plan">Off-Plan</a></li> 80 81 <li><a aria-label="Property name" href="/properties-statuses/commercial">Commercial</a></li> 82 83 84 </ul> 85 </div> 86 </li> 87 <li class="mobile_dropdown mobile_dropdown2"><a aria-label="Developers" href="/developers">Developers</a> 88 <span class="developer_toggle"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"></path></svg></span> 89 <div class="sub_menu developer_submenu"> 90 <ul> 91 92 93 <li><a aria-label="Developers name" href="/developers/azizi-developments">Azizi Developments</a></li> 94 95 <li><a aria-label="Developers name" href="/developers/sobha-group">Sobha Group</a></li> 96 97 <li><a aria-label="Developers name" href="/developers/damac">DAMAC</a></li> 98 99 <li><a aria-label="Developers name" href="/developers/emaar-properties">Emaar Properties</a></li> 100 101 <li><a aria-label="Developers name" href="/developers/aldar-properties">Aldar Properties</a></li> 102 103 <li><a aria-label="Developers name" href="/developers/binghatti-developers">Binghatti Developers</a></li> 104 105 <li><a aria-label="Developers name" href="/developers/meraas">Meraas</a></li> 106 107 <li><a aria-label="Developers name" href="/developers/ellington-properties">Ellington Properties</a></li> 108 109 <li><a aria-label="Developers name" href="/developers/nakheel">Nakheel</a></li> 110 111 <li><a aria-label="Developers name" href="/developers/arada">ARADA</a></li> 112 113 <li><a aria-label="Developers name" href="/developers/omniyat">OMNIYAT</a></li> 114 115 <li><a aria-label="Developers name" href="/developers/deyaar">DEYAAR</a></li> 116 117 <li><a aria-label="Developers name" href="/developers/samana-developers">Samana Developers</a></li> 118 119 <li><a aria-label="Developers name" href="/developers/tiger-group">Tiger Group</a></li> 120 121 <li><a aria-label="Developers name" href="/developers/wasl-properties">Wasl Properties</a></li> 122 123 <li><a aria-label="Developers name" href="/developers/reportage-properties">Reportage Properties</a></li> 124 125 <li><a aria-label="Developers name" href="/developers/danube-properties">Danube Properties</a></li> 126 127 <li><a aria-label="Developers name" href="/developers/one-development">One Development</a></li> 128 129 <li><a aria-label="Developers name" href="/developers/pantheon">Pantheon</a></li> 130 131 <li><a aria-label="Developers name" href="/developers/hz-development">HZ Development</a></li> 132 133 <li><a aria-label="Developers name" href="/developers/union-properties">Union Properties</a></li> 134 135 <li><a aria-label="Developers name" href="/developers/karma-developers">Karma Developers</a></li> 136 137 <li><a aria-label="Developers name" href="/developers/confident-group">Confident Group</a></li> 138 139 <li><a aria-label="Developers name" href="/developers/iraz-developments">Iraz Developments</a></li> 140 141 <li><a aria-label="Developers name" href="/developers/aqasa-developers">Aqasa Developers</a></li> 142 143 <li><a aria-label="Developers name" href="/developers/london-gate">London Gate</a></li> 144 145 <li><a aria-label="Developers name" href="/developers/pure-bliss-development">Pure Bliss Development</a></li> 146 147 <li><a aria-label="Developers name" href="/developers/bnw-developments">BNW Developments</a></li> 148 149 <li><a aria-label="Developers name" href="/developers/prescott-development">Prescott Development</a></li> 150 151 <li><a aria-label="Developers name" href="/developers/imtiaz-developments">Imtiaz Developments</a></li> 152 153 <li><a aria-label="Developers name" href="/developers/beyond-developments">Beyond Developments</a></li> 154 155 <li><a aria-label="Developers name" href="/developers/anax-developments">ANAX Developments</a></li> 156 157 <li><a aria-label="Developers name" href="/developers/vision-developments">Vision Developments</a></li> 158 159 <li><a aria-label="Developers name" href="/developers/dar-global">Dar Global</a></li> 160 161 <li><a aria-label="Developers name" href="/developers/aa-hmb-devlelopments">AA HMB Devlelopments</a></li> 162 163 <li><a aria-label="Developers name" href="/developers/object-1">Object 1</a></li> 164 165 <li><a aria-label="Developers name" href="/developers/blue-coast">Blue Coast</a></li> 166 167 <li><a aria-label="Developers name" href="/developers/bnh-developer">B.N.H Developer</a></li> 168 169 <li><a aria-label="Developers name" href="/developers/nshama-development">
169Nshama Development</a></li> 170 171 <li><a aria-label="Developers name" href="/developers/grid-properties">Grid Properties</a></li> 172 173 <li><a aria-label="Developers name" href="/developers/al-habtoor-group">Al Habtoor Group</a></li> 174 175 <li><a aria-label="Developers name" href="/developers/dubai-properties">Dubai Properties</a></li> 176 177 <li><a aria-label="Developers name" href="/developers/mag-property-development">MAG Property Development</a></li> 178 179 <li><a aria-label="Developers name" href="/developers/majid-al-futtaim">Majid Al Futtaim</a></li> 180 181 <li><a aria-label="Developers name" href="/developers/bnh-real-estate-developer">BNH Real Estate Developer</a></li> 182 183 184 </ul> 185 </div> 186 </li> 187 <li><a aria-label="Blog" href="/blogs">Blogs</a></li> 188 <li><a aria-label="Mortgage calculator" href="/mortgage-calculator">Mortgage Calculator</a></li> 189 </ul> 190 </div> 191 <div class="header_right"> 192 <a aria-label="Free quote" href="javascript:void(0)" class="freeQuoteEnquiry"><span class="getqt">Get a Free Quote</span> <span><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg></span></a> 193 <div class="toggle_menu"> 194 <span></span> 195 <span></span> 196 <span></span> 197 </div> 198 </div> 199</section> 200<!-- Home Quote Popup Start 04.27.2026 --> 201 202<div class="nestwood_quote_popup_outer"> 203 <div class="nestwood_quote_popup"> 204 <div class="cls_qut"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.5859 12L2.79297 4.20706L4.20718 2.79285L12.0001 10.5857L19.793 2.79285L21.2072 4.20706L13.4143 12L21.2072 19.7928L19.793 21.2071L12.0001 13.4142L4.20718 21.2071L2.79297 19.7928L10.5859 12Z"></path></svg></div> 205 <h3>Get a Free Quote</h3> 206 <form autocomplete="off" class="getfreequoteForm"> 207 <input type="hidden" name="formAction" value="/submit-enquiry"> 208 <input type="hidden" name="source" value="topbar"> 209 <div class="quote_group"> 210 <div class="quote_group_single"> 211 <input type="text" name="name" placeholder="Your Name"> 212 <span class="text-danger"></span> 213 </div> 214 <div class="quote_group_single"> 215 <input type="text" name="phone_number" placeholder="Phone Number"> 216 <span class="text-danger"></span> 217 </div> 218 </div> 219 <input type="text" name="email" placeholder="Email Id"> 220 <span class="text-danger"></span> 221 <textarea name="message" placeholder="Your Message"></textarea> 222 <span class="text-danger"></span> 223 <div class="submit_button"> 224 <input type="submit" value="Send Message"> 225 </div> 226 <div class="successFreQuoteMessage"></div> 227 </form> 228 </div> 229</div> 230 231<!-- Home Quote Popup End 04.27.2026 --> 232<!-- Header Area Main End --> 233 234 235<!-- Banner Area Main Start --> 236 237<!-- Banner Area Main End --> 238 239<!-- Blog Page Area Start --> 240 241<section class="blog_page_main"> 242 <div class="blog_page_inner"> 243 <div class="blog_page_head"> 244 <p>Stay informed with the latest insights on Dubai real estate, property investment, market trends and opportunities across the UAE!</p> 245 </div> 246 <div class="all_blog_area_main"> 247 <div class="all_blog_area_main_left"> 248 249 250 <div class="single_blog_area"> 251 <div class="single_blog_area_left"> 252 <img src="/uploads/blog/1789477290082-2a5f8f8f-b4bf-4490-968a-f4e2eba7ef80.png" alt="Best Areas to Buy a Property in Dubai in 2026"> 253 </div> 254 <div class="single_blog_area_right"> 255 <h4>September 15, 2026</h4> 256 <h3><a href="/blogs/best-areas-to-buy-property-in-dubai">Best Areas to Buy a Property in Dubai in 2026 </a></h3> 257 <p><p style="text-align: justify;"><span><strong>What is the best area to </strong><strong><a href="https://nestwoodrealty.com/properties">buy property in Dubai</a></strong><strong>?</strong></span><span> Where should you invest?</span></p><p style="text-align: justify;"><span>The answer depends on what you want from your property. An investor chasing </p> 258 <a href="/blogs/best-areas-to-buy-property-in-dubai"><span class="buybtn">Read More</span> <span class="buy_icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg></span></a> 259 </div> 260 </div> 261 262 <div class="single_blog_area"> 263 <div class="single_blog_area_left"> 264 <img src="/uploads/blog/Nestwood Realty Is the Luxury Real Estate Agency in Dubai Trusted by Elite Investors1782117795352.png" alt="Why Choose Nestwood Realty as Your Luxury Real Estate Agency in Dubai?"> 265 </div> 266 <div class="single_blog_area_right"> 267 <h4>June 22, 2026</h4> 268 <h3><a href="/blogs/luxury-real-estate-agency-in-dubai">Why Choose Nestwood Realty as Your Luxury Real Estate Agency in Dubai? </a></h3> 269 <p><p>Dubai has never been short of impressive property choices. New communities continue to take shape while established neighbourhoods remain popular with buyers from around the world. The real difficulty is not finding a beautiful property. It is knowing whether that property is genuinely right for you.</p> 270<p>An attractive brochure can show the v </p> 271 <a href="/blogs/luxury-real-estate-agency-in-dubai"><span class="buybtn">Read More</span> <span class="buy_icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg></span></a> 272 </div> 273 </div> 274 275 <div class="single_blog_area"> 276 <div class="single_blog_area_left"> 277 <img src="/uploads\blog\300x170_1755850186_0a37162e80f0710ed6a71774000451668.png" alt="Dubaiâs Golden Visa- Building your Future in Gold Standard Real Estate"> 278 </div> 279 <div class="single_blog_area_right"> 280 <h4>March 20, 2026</h4> 281 <h3><a href="/blogs/dubais-golden-visa-building-your-future-in-gold-standard-real-estate">Dubaiâs Golden Visa- Building your Future in Gold Standard Real Estate </a></h3> 282 <p><p>Could you imagine a key to a ten-year residency in one of the most cosmopolitan, business-forward cities in the world? It has been secured through luxury property investment. Dubaiâs golden visa, introduced in 2019, transcends the limitations of visa convenience. It empowers investors and global families to form a legacy and lifestyle in a metro </p> 283 <a href="/blogs/dubais-golden-visa-building-your-future-in-gold-standard-real-estate"><span class="buybtn">Read More</span> <span class="buy_icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg></span></a> 284 </div> 285 </div> 286 287 <div class="single_blog_area"> 288 <div class="single_blog_area_left"> 289 <img src="/uploads\blog\300x170_1751867688_14254a1c38611bba5f211774000257532.jpg" alt="Downtown, Business Bay, or Sheikh Zayed Road: Which Dubai Location Offers the Best ROI in 2025?"> 290 </div> 291 <div class="single_blog_area_right"> 292 <h4>March 20, 2026</h4> 293 <h3><a href="/blogs/downtown-business-bay-or-sheikh-zayed-road-which-dubai-location-offers-the-best-roi-in-2025">Downtown, Business Bay, or Sheikh Zayed Road: Which Dubai Location Offers the Best ROI in 2025? </a></h3> 294 <p><p style="text-align: justify;"><em>We understand the magnetism of Dubaiâs high-end districts, where the million-dollar question remains-</em></p> 295<h3 style="text-align: justify;"><em>Where will your next investment in Dubai real estate yield maximum returns?</em></h3> 296<p style="text-align: justify;">In 2025, three epicenters dominate the skyline </p> 297 <a href="/blogs/downtown-business-bay-or-sheikh-zayed-road-which-dubai-location-offers-the-best-roi-in-2025"><span class="buybtn">Read More</span> <span class="buy_icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16.0037 9.41421L7.39712 18.0208L5.98291 16.6066L14.5895 8H7.00373V6H18.0037V17H16.0037V9.41421Z"></path></svg></span></a> 298 </div> 299 </div> 300 301 302 303 </div> 304 <div class="all_blog_area_main_right"> 305 <h3>ENQUIRE NOW</h3> 306 <form autocomplete="off" class="getfreequoteForm"> 307 <input type="hidden" name="formAction" value="/submit-enquiry"> 308 <input type="hidden" name="source" value="blog"> 309 <div class="enq_frm"> 310 <label>Your name</label> 311 <input type="text" name="name" placeholder="Your Name">
312 <span class="text-danger"></span> 313 </div> 314 <div class="enq_frm"> 315 <label>Phone nember</label> 316 <input type="text" name="phone_number" placeholder="Phone"> 317 <span class="text-danger"></span> 318 </div> 319 <div class="enq_frm"> 320 <label>Your e-mail</label> 321 <input type="text" name="email" placeholder="Email"> 322 <span class="text-danger"></span> 323 </div> 324 <div class="enq_submit"> 325 <input type="submit" value="Submit"> 326 </div> 327 <div class="successFreQuoteMessage"></div> 328 </form> 329 </div> 330 </div> 331 </div> 332</section> 333 334<!-- Blog Page Area End --> 335 336<!-- Footer area main start --> 337 338<footer class="main_footer_area"> 339 340 <div class="main_footer_area_inner"> 341 <div class="foot_middle"> 342 <div class="foot_middle_left"> 343 <div class="foot_middle_left_fst"> 344 <div class="foot_middle_left_about"> 345 <p>Dubai is energy and ambition, but also those hidden pockets of comfort where the cityâs sparkle turns into a true sense of belonging.</p><p><br></p> 346<p>Nestwood Realty is a premium real estate agency rooted in Dubai, specializing in the sale and investment of standout properties across the UAE.</p> 347 <div class="logo_foot"> 348 <img src="/assets/frontend/images/logo.png" alt="img"> 349 </div> 350 </div> 351 <div class="foot_middle_left_link"> 352 <ul> 353 <li><a aria-label="About us" href="/about-us">About Us</a></li> 354 <li><a aria-label="Contact us" href="/contact-us">Contact Us</a></li> 355 <li><a aria-label="Careers" href="/careers">Careers</a></li> 356 <li><a aria-label="Awards" href="/awards">Awards</a></li> 357 <li><a aria-label="Properties" href="/properties">Properties</a></li> 358 </ul> 359 <ul> 360 <li><a aria-label="Blog" href="/blogs">Blog</a></li> 361 362 363 <li><a aria-label="Plicies" href="/privacy-policy">Privacy Policy</a></li> 364 365 <li><a aria-label="Plicies" href="/terms-and-conditions">Terms and Conditions</a></li> 366 367 368 <li><a aria-label="Sitemap" href="/sitemap">Sitemap</a></li> 369 </ul> 370 </div> 371 </div> 372 <div class="foot_middle_left_lst"> 373 <h3>Dubai, UAE</h3> 374 <p>1803, The Opal Tower, Business Bay, Dubai, UAE</p> 375 <div class="logo_social"> 376 <ul> 377 378 <li><a aria-label="Facebook" href="https://www.facebook.com/nestwoodrealtyuae/"><img src="/assets/frontend/images/facebook-line.svg" alt="img"></a></li> 379 380 381 <li><a aria-label="Instagram" href="https://www.instagram.com/nestwood_realty/"><img src="/assets/frontend/images/instagram-line.svg" alt="img"></a></li> 382 383 384 <li><a aria-label="Twitter" href="https://x.com/NestWoodRealty"><img src="/assets/frontend/images/twitter-x-fill.svg" alt="img"></a></li> 385 386 387 <li><a aria-label="Linkedin" href="https://www.linkedin.com/company/nestwood-realty/"><img src="/assets/frontend/images/linkedin-line.svg" alt="img"></a></li> 388 389 </ul> 390 </div> 391 </div> 392 </div> 393 <div class="footer_top"> 394 395 </div> 396 397 398 <div class="foot_last_contact"> 399 <div class="need_hlp"> 400 <h4>Need Help?</h4> 401 </div> 402 403 <div class="call_hlp"> 404 <a aria-label="Phone number" href="tel:+971 4 334 4081"><svg viewBox="0 0 24 24" fill="currentColor">
404<path d="M9.36556 10.6821C10.302 12.3288 11.6712 13.698 13.3179 14.6344L14.2024 13.3961C14.4965 12.9845 15.0516 12.8573 15.4956 13.0998C16.9024 13.8683 18.4571 14.3353 20.0789 14.4637C20.599 14.5049 21 14.9389 21 15.4606V19.9234C21 20.4361 20.6122 20.8657 20.1022 20.9181C19.5723 20.9726 19.0377 21 18.5 21C9.93959 21 3 14.0604 3 5.5C3 4.96227 3.02742 4.42771 3.08189 3.89776C3.1343 3.38775 3.56394 3 4.07665 3H8.53942C9.0611 3 9.49513 3.40104 9.5363 3.92109C9.66467 5.54288 10.1317 7.09764 10.9002 8.50444C11.1427 8.9484 11.0155 9.50354 10.6039 9.79757L9.36556 10.6821ZM6.84425 10.0252L8.7442 8.66809C8.20547 7.50514 7.83628 6.27183 7.64727 5H5.00907C5.00303 5.16632 5 5.333 5 5.5C5 12.9558 11.0442 19 18.5 19C18.667 19 18.8337 18.997 19 18.9909V16.3527C17.7282 16.1637 16.4949 15.7945 15.3319 15.2558L13.9748 17.1558C13.4258 16.9425 12.8956 16.6915 12.3874 16.4061L12.3293 16.373C10.3697 15.2587 8.74134 13.6303 7.627 11.6707L7.59394 11.6126C7.30849 11.1044 7.05754 10.5742 6.84425 10.0252Z"></path></svg> +971 4 334 4081</a> 405 </div> 406 407 408 <!-- +971 56 520 3838 --> 409 <div class="call_hlp"> 410 <a aria-label="Whatsapp" href="https://wa.me/+971 56 520 3838?text=Hello%20I%20want%20to%20know%20more"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M7.25361 18.4944L7.97834 18.917C9.18909 19.623 10.5651 20 12.001 20C16.4193 20 20.001 16.4183 20.001 12C20.001 7.58172 16.4193 4 12.001 4C7.5827 4 4.00098 7.58172 4.00098 12C4.00098 13.4363 4.37821 14.8128 5.08466 16.0238L5.50704 16.7478L4.85355 19.1494L7.25361 18.4944ZM2.00516 22L3.35712 17.0315C2.49494 15.5536 2.00098 13.8345 2.00098 12C2.00098 6.47715 6.47813 2 12.001 2C17.5238 2 22.001 6.47715 22.001 12C22.001 17.5228 17.5238 22 12.001 22C10.1671 22 8.44851 21.5064 6.97086 20.6447L2.00516 22ZM8.39232 7.30833C8.5262 7.29892 8.66053 7.29748 8.79459 7.30402C8.84875 7.30758 8.90265 7.31384 8.95659 7.32007C9.11585 7.33846 9.29098 7.43545 9.34986 7.56894C9.64818 8.24536 9.93764 8.92565 10.2182 9.60963C10.2801 9.76062 10.2428 9.95633 10.125 10.1457C10.0652 10.2428 9.97128 10.379 9.86248 10.5183C9.74939 10.663 9.50599 10.9291 9.50599 10.9291C9.50599 10.9291 9.40738 11.0473 9.44455 11.1944C9.45903 11.25 9.50521 11.331 9.54708 11.3991C9.57027 11.4368 9.5918 11.4705 9.60577 11.4938C9.86169 11.9211 10.2057 12.3543 10.6259 12.7616C10.7463 12.8783 10.8631 12.9974 10.9887 13.108C11.457 13.5209 11.9868 13.8583 12.559 14.1082L12.5641 14.1105C12.6486 14.1469 12.692 14.1668 12.8157 14.2193C12.8781 14.2457 12.9419 14.2685 13.0074 14.2858C13.0311 14.292 13.0554 14.2955 13.0798 14.2972C13.2415 14.3069 13.335 14.2032 13.3749 14.1555C14.0984 13.279 14.1646 13.2218 14.1696 13.2222V13.2238C14.2647 13.1236 14.4142 13.0888 14.5476 13.097C14.6085 13.1007 14.6691 13.1124 14.7245 13.1377C15.2563 13.3803 16.1258 13.7587 16.1258 13.7587L16.7073 14.0201C16.8047 14.0671 16.8936 14.1778 16.8979 14.2854C16.9005 14.3523 16.9077 14.4603 16.8838 14.6579C16.8525 14.9166 16.7738 15.2281 16.6956 15.3913C16.6406 15.5058 16.5694 15.6074 16.4866 15.6934C16.3743 15.81 16.2909 15.8808 16.1559 15.9814C16.0737 16.0426 16.0311 16.0714 16.0311 16.0714C15.8922 16.159 15.8139 16.2028 15.6484 16.2909C15.391 16.428 15.1066 16.5068 14.8153 16.5218C14.6296 16.5313 14.4444 16.5447 14.2589 16.5347C14.2507 16.5342 13.6907 16.4482 13.6907 16.4482C12.2688 16.0742 10.9538 15.3736 9.85034 14.402C9.62473 14.2034 9.4155 13.9885 9.20194 13.7759C8.31288 12.8908 7.63982 11.9364 7.23169 11.0336C7.03043 10.5884 6.90299 10.1116 6.90098 9.62098C6.89729 9.01405 7.09599 8.4232 7.46569 7.94186C7.53857 7.84697 7.60774 7.74855 7.72709 7.63586C7.85348 7.51651 7.93392 7.45244 8.02057 7.40811C8.13607 7.34902 8.26293 7.31742 8.39232 7.30833Z"></path></svg> +971 56 520 3838</a> 411 </div> 412 413 414 <div class="call_hlp"> 415 <a aria-label="Email" href="mailto:[email protected]"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z"></path></svg> [email protected]</a> 416 </div> 417 418 </div> 419 420 <div class="copyright_area"> 421 <p>© 2026. All rights reserved.</p> 422 <p>Powered By : <a href="https://www.codebuzzers.com/" target="_blank">Codebuzzers Technologies</a></p> 423 </div> 424 </div> 425 </div> 426</footer> 427 428<div class="whatsapp_icon"> 429 <a aria-label="Floating Whatsapp" href="https://wa.me/+971565203838"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M7.25361 18.4944L7.97834 18.917C9.18909 19.623 10.5651 20 12.001 20C16.4193 20 20.001 16.4183 20.001 12C20.001 7.58172 16.4193 4 12.001 4C7.5827 4 4.00098 7.58172 4.00098 12C4.00098 13.4363 4.37821 14.8128 5.08466 16.0238L5.50704 16.7478L4.85355 19.1494L7.25361 18.4944ZM2.00516 22L3.35712 17.0315C2.49494 15.5536 2.00098 13.8345 2.00098 12C2.00098 6.47715 6.47813 2 12.001 2C17.5238 2 22.001 6.47715 22.001 12C22.001 17.5228 17.5238 22 12.001 22C10.1671 22 8.44851 21.5064 6.97086 20.6447L2.00516 22ZM8.39232 7.30833C8.5262 7.29892 8.66053 7.29748 8.79459 7.30402C8.84875 7.30758 8.90265 7.31384 8.95659 7.32007C9.11585 7.33846 9.29098 7.43545 9.34986 7.56894C9.64818 8.24536 9.93764 8.92565 10.2182 9.60963C10.2801 9.76062 10.2428 9.95633 10.125 10.1457C10.0652 10.2428 9.97128 10.379 9.86248 10.5183C9.74939 10.663 9.50599 10.9291 9.50599 10.9291C9.50599 10.9291 9.40738 11.0473 9.44455 11.1944C9.45903 11.25 9.50521 11.331 9.54708 11.3991C9.57027 11.4368 9.5918 11.4705 9.60577 11.4938C9.86169 11.9211 10.2057 12.3543 10.6259 12.7616C10.7463 12.8783 10.8631 12.9974 10.9887 13.108C11.457 13.5209 11.9868 13.8583 12.559 14.1082L12.5641 14.1105C12.6486 14.1469 12.692 14.1668 12.8157 14.2193C12.8781 14.2457 12.9419 14.2685 13.0074 14.2858C13.0311 14.292 13.0554 14.2955 13.0798 14.2972C13.2415 14.3069 13.335 14.2032 13.3749 14.1555C14.0984 13.279 14.1646 13.2218 14.1696 13.2222V13.2238C14.2647 13.1236 14.4142 13.0888 14.5476 13.097C14.6085 13.1007 14.6691 13.1124 14.7245 13.1377C15.2563 13.3803 16.1258 13.7587 16.1258 13.7587L16.7073 14.0201C16.8047 14.0671 16.8936 14.1778 16.8979 14.2854C16.9005 14.3523 16.9077 14.4603 16.8838 14.6579C16.8525 14.9166 16.7738 15.2281 16.6956 15.3913C16.6406 15.50
42958 16.5694 15.6074 16.4866 15.6934C16.3743 15.81 16.2909 15.8808 16.1559 15.9814C16.0737 16.0426 16.0311 16.0714 16.0311 16.0714C15.8922 16.159 15.8139 16.2028 15.6484 16.2909C15.391 16.428 15.1066 16.5068 14.8153 16.5218C14.6296 16.5313 14.4444 16.5447 14.2589 16.5347C14.2507 16.5342 13.6907 16.4482 13.6907 16.4482C12.2688 16.0742 10.9538 15.3736 9.85034 14.402C9.62473 14.2034 9.4155 13.9885 9.20194 13.7759C8.31288 12.8908 7.63982 11.9364 7.23169 11.0336C7.03043 10.5884 6.90299 10.1116 6.90098 9.62098C6.89729 9.01405 7.09599 8.4232 7.46569 7.94186C7.53857 7.84697 7.60774 7.74855 7.72709 7.63586C7.85348 7.51651 7.93392 7.45244 8.02057 7.40811C8.13607 7.34902 8.26293 7.31742 8.39232 7.30833Z"></path></svg></a> 430</div> 431 432<!-- Footer area main End --> 433 434 435 <!-- GSAP CDN --> 436
436<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
436 437
437<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
437 438
438<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
438 439 <!--
439<script src='https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/js/splide.min.js'></script>
439 --> 440
440<script src="https://npmcdn.com/flickity@2/dist/flickity.pkgd.js"></script>
440 441
441<script src="/assets/frontend/js/splide.min.js"></script>
441 442
442<script src="https://unpkg.com/[email protected]/dist/lenis.min.js"></script>
442 443
443<script src='https://unpkg.com/gsap@3/dist/Draggable.min.js'></script>
443 444
444<script src='https://assets.codepen.io/16327/InertiaPlugin.min.js'></script>
444 445
445<script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
445 446
446<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
446 447
447<script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>
447 448 449 <!-- MAIN JS --> 450 <!--
450<script src="/assets/frontend/js/custom.js"></script>
450 --> 451
451<script src="/assets/frontend/js/js_minify.js"></script>
451 452 453 454
455<script> 456 document.addEventListener("DOMContentLoaded", () => { 457 window.frontPrefix = '/'; 458 // Safety check 459 if (!window.gsap || !window.ScrollTrigger) { 460 console.error("GSAP or ScrollTrigger missing"); 461 return; 462 } 463 464 gsap.registerPlugin(ScrollTrigger); 465 // Avoid refresh storms from mobile URL-bar show/hide resizes, and coalesce callbacks. 466 ScrollTrigger.config({ ignoreMobileResize: true, limitCallbacks: true }); 467 468 /* =============================== 469 --- PROPERTIES PAGE SCRIPT --- START 470 =============================== */ 471 472 473 const propertyPageList = document.querySelector(".main_property_listing_right_box_single"); 474 475if(propertyPageList){ 476 477 gsap.utils.toArray(".main_property_listing_right_box_single").forEach((card, index) => { 478 479 const img = card.querySelector(".property_listing_right_img"); 480 const content = card.querySelector(".property_listing_right_content"); 481 482 const tl = gsap.timeline({ 483 scrollTrigger: { 484 trigger: card, 485 start: "top 85%", 486 toggleActions: "play none none none", 487 } 488 }); 489 490 // Card fade + slide up 491 tl.from(card, { 492 y: 80, 493 opacity: 0, 494 duration: 0.8, 495 ease: "power3.out" 496 }) 497 498 // Image reveal 499 .from(img, { 500 scale: 0.9, 501 opacity: 0, 502 duration: 0.7, 503 ease: "power2.out" 504 }, "-=0.4") 505 506 // Content slide 507 .from(content, { 508 x: 60, 509 opacity: 0, 510 duration: 0.7, 511 ease: "power2.out" 512 }, "-=0.5"); 513 514 }); 515 516} 517 518const propertyPageFaqAccordian = document.querySelector(".accordion-header"); 519 520if(propertyPageFaqAccordian){ 521 522 $(".accordion-header").click(function () { 523 524 let currentContent = $(this).next(".accordion-content"); 525 let icon = $(this).find(".icon"); 526 527 // Close other open content 528 $(".accordion-content").not(currentContent).slideUp("fast"); 529 530 // Toggle the visibility of the cliced content 531 currentContent.slideToggle("fast", function () { 532 533 // Toggle the plus and minus icons 534 icon.toggleClass("ri-add-line ri-subtract-line"); 535 536 }); 537 538 }); 539 540} 541 542const propertyPageImageSlider = document.querySelector(".property_listing_right_img"); 543 544if(propertyPageImageSlider){ 545 546 document.querySelectorAll(".property_listing_right_img").forEach((slider) => { 547 548 const images = slider.querySelectorAll(".listprop_slider img"); 549 const dotsContainer = slider.querySelector(".slider_dots"); 550 551 let current = 0; 552 let interval; 553 554 if (!images.length || !dotsContainer) return; 555 556 // Set initial state 557 images.forEach((img, index) => { 558 gsap.set(img, { 559 width: index === 0 ? "100%" : "0%" 560 }); 561 }); 562 563 if(images.length > 1){ 564 565 // Create dots 566 images.forEach((_, index) => { 567 568 const dot = document.createElement("span"); 569 570 if (index === 0) dot.classList.add("active"); 571 572 dot.addEventListener("click", () => { 573 574 stopSlider(); 575 goToSlide(index); 576 startSlider(); 577 578 }); 579 580 dotsContainer.appendChild(dot); 581 582 }); 583 584 } 585 586 const dots = dotsContainer.querySelectorAll("span"); 587 588 function goToSlide(index) { 589 590 if (index === current) return; 591 592 const currentImg = images[current]; 593 const nextImg = images[index]; 594 595 // Animate current out 596 gsap.to(currentImg, { 597 width: "0%", 598 duration: 0.6, 599 ease: "power2.inOut" 600 }); 601 602 // Animate next in 603 gsap.fromTo(nextImg, 604 { width: "0%" }, 605 { 606 width: "100%", 607 duration: 0.6, 608 ease: "power2.inOut" 609 } 610 ); 611 612 if(dots.length){ 613 dots[current].classList.remove("active"); 614 dots[index].classList.add("active"); 615 } 616 617 current = index; 618 619 } 620 621 function startSlider() { 622 623 stopSlider(); 624 625 interval = setInterval(() => { 626 627 let next = (current + 1) % images.length; 628 goToSlide(next); 629 630 }, 2500); 631 632 } 633 634 function stopSlider() { 635 636 clearInterval(interval); 637 638 } 639 640 // Auto start slider 641 if(images.length > 1){ 642 startSlider(); 643 } 644 645 // Stop on hover 646 slider.addEventListener("mouseenter", stopSlider); 647 648 // Restart on mouse leave 649 slider.addEventListener("mouseleave", startSlider); 650 651 }); 652 653} 654 655 656 657 658 /* =============================== 659 --- PROPERTIES DETAILS PAGE SCRIPT --- START 660 =============================== */ 661 const primary_slider = document.getElementById("primary_slider"); 662 if(primary_slider){ 663 // Primary slider. 664 var primarySlider = new Splide('#primary_slider', { 665 type: 'fade', 666 heightRatio: 0.5, 667 pagination: false,
668 arrows: false, 669 cover: true, 670 }); 671 672 // Thumbnails slider. 673 var thumbnailSlider = new Splide('#thumbnail_slider', { 674 rewind: true, 675 fixedWidth: 100, 676 fixedHeight: 64, 677 isNavigation: true, 678 gap: 10, 679 focus: 'center', 680 pagination: false, 681 cover: true, 682 breakpoints: { 683 '600': { 684 fixedWidth: 66, 685 fixedHeight: 40, 686 } 687 } 688 }).mount(); 689 690 // sync the thumbnails slider as a target of primary slider. 691 primarySlider.sync(thumbnailSlider).mount(); 692 } 693 // Mortgage Calculation Section - START 694 const mortgageCalculatorSection = document.getElementById("mortgageCalculatorSection"); 695 if(mortgageCalculatorSection){ 696 697 const property_value_input = document.getElementById("property_value"); 698 const down_payment_input = document.getElementById("down_payment"); 699 const term_years_input = document.getElementById("term_years"); 700 const interest_rates_input = document.getElementById("interest_rates"); 701 if(property_value_input && down_payment_input && term_years_input && interest_rates_input){ 702 let property_value = property_value_input.value; 703 let down_payment = down_payment_input.value; 704 let term_years = term_years_input.value; 705 let interest_rates = interest_rates_input.value; 706 707 calculationData = calculateMortgage(property_value, down_payment, term_years, interest_rates); 708 // console.log("calculationData",calculationData); 709 updateDisplay(calculationData); 710 document.getElementById("property_value").addEventListener('input', () => { 711 // console.log("property_value_input",event.target.value); 712 calculationData = calculateMortgage(event.target.value, down_payment_input.value, term_years_input.value, interest_rates_input.value); 713 updateDisplay(calculationData); 714 // console.log("calculationData_propertyValueInput",calculationData); 715 }); 716 717 document.getElementById("down_payment").addEventListener('input', () => { 718 // console.log("down_payment_input",event.target.value); 719 calculationData = calculateMortgage(property_value_input.value, event.target.value, term_years_input.value, interest_rates_input.value); 720 updateDisplay(calculationData); 721 // console.log("calculationData_propertyValueInput",calculationData); 722 }); 723 document.getElementById("term_years").addEventListener('input', () => { 724 // console.log("term_years_input",event.target.value); 725 calculationData = calculateMortgage(property_value_input.value, down_payment_input.value, event.target.value, interest_rates_input.value); 726 updateDisplay(calculationData); 727 // console.log("calculationData_propertyValueInput",calculationData); 728 }); 729 document.getElementById("interest_rates").addEventListener('input', () => { 730 // console.log("interest_rates_input",event.target.value); 731 calculationData = calculateMortgage(property_value_input.value, down_payment_input.value, term_years_input.value, event.target.value); 732 updateDisplay(calculationData); 733 // console.log("calculationData_propertyValueInput",calculationData); 734 }); 735 736 } 737 } 738 // Mortgage Calculation Section - END 739 // Property Share Section 740 $('.propertyShare').on('click',async function() { 741 var ele = $(this); 742 let extra = $(this).data('extra'); 743 const shareUrl = `${window.location.origin}/property-details/${extra.slug}`; 744 const shareText = `Check out this property: ${extra.name} - Starting from AED ${extra.starting_price}`; 745 // Share API (modern browsers) 746 if (navigator.share) { 747 try { 748 await navigator.share({ 749 title: extra.name, 750 text: shareText, 751 url: shareUrl 752 }); 753 // console.log("shareUrl",shareUrl); 754 } catch (err) {
755 console.log('Share cancelled'); 756 } 757 } else { 758 // Fallback: Copy to clipboard 759 // copyToClipboard(shareUrl); 760 navigator.clipboard.writeText(shareUrl).then(() => { 761 $(this).find(".share_copy").show(); 762 setTimeout(() => { 763 ele.find(".share_copy").hide(); 764 }, 1000); 765 }); 766 } 767 }); 768 function copyToClipboard(text) { 769 770 } 771 /* =============================== 772 --- PROPERTIES DETAILS PAGE SCRIPT --- END 773 =============================== */ 774 // Script Add 04.27.2026 - for Quote Popup 775 $('.freeQuoteEnquiry').click( 776 function () { 777 $('.nestwood_quote_popup_outer').addClass('nestwood_quote_popup_outer2'); 778 $("body").addClass('hidden_body'); 779 }, 780 781 ); 782 783 $('.cls_qut').click( 784 function () { 785 $('.nestwood_quote_popup_outer').removeClass('nestwood_quote_popup_outer2'); 786 $("body").removeClass('hidden_body'); 787 } 788 ); 789 $('.getfreequoteForm').submit(function(e) { 790 e.preventDefault(); 791 let form = this; 792 let formData = {}; 793 form.querySelectorAll("input, textarea").forEach(input => { 794 if (input.name) { 795 formData[input.name] = input.value; 796 } 797 }); 798 fetch(formData.formAction, { 799 method: "POST", 800 headers: { "Content-Type": "application/json" }, 801 body: JSON.stringify(formData) 802 }) 803 .then(res => res.json()) 804 .then(data => { 805 form.querySelectorAll("span.text-danger").forEach(span => { 806 span.textContent = ""; 807 }); 808 form.querySelectorAll("input, textarea, select").forEach(input => { 809 input.classList.remove("is-invalid", "is-valid"); 810 }); 811 if(data.status==1){ 812 $('.successFreQuoteMessage').html(data.message); 813 $('.successFreQuoteMessage').show(); 814 form.reset(); 815 setTimeout(function() { 816 $('.nestwood_quote_popup_outer').removeClass('nestwood_quote_popup_outer2'); 817 $("body").removeClass('hidden_body'); 818 }, 3000); 819 // console.log("success",data.message); 820 } else if (data.status == 2) { 821 // Validation errors 822 data.errors.forEach(error => { 823 const input = form.querySelector(`input[name="${error.path}"], textarea[name="${error.path}"]`); 824 if (input) { 825 input.classList.add("is-invalid"); 826 const errorSpan = input.nextElementSibling; 827 if (errorSpan && errorSpan.classList.contains("text-danger")) { 828 errorSpan.textContent = error.msg; 829 } 830 } 831 }); 832 }else{ 833 $('#successFreQuoteMessage').html(data.message); 834 console.log("error",data.message); 835 } 836 }) 837 .catch(err => { 838 $('#successFreQuoteMessage').html(err); 839 console.error("Error:", err); 840 }); 841 }); 842 // Script Add 04.27.2026 - for Quote Popup End 843 // ð§¼ Context keeps animations isolated & auto-cleans on refresh 844 const ctx = gsap.context(() => { 845 846 /* =============================== 847 SECTION 3 ANIMATION 848 =============================== */ 849 const section3 = document.querySelector(".prmt_constaltancy_area3"); 850 const inner3 = section3?.querySelector(".prmt_constaltancy_area_inner3"); 851 852 if (section3 && inner3) { 853 gsap.fromTo( 854 inner3, 855 { 856 scale: 1.5, 857 y: 120, 858 transformOrigin: "center center" 859 }, 860 { 861 scale: 1, 862 y: 0, 863 ease: "none", 864 scrollTrigger: { 865 trigger: section3, 866 start: "top 50%", 867 end: "bottom 80%", 868 scrub: 2, 869 invalidateOnRefresh: true, 870 // markers: true 871 } 872 } 873 ); 874 } 875 876 /* =============================== 877 SECTION 2 ANIMATION 878 =============================== */ 879 const section2 = document.querySelector(".prmt_constaltancy_area2"); 880 const inner2 = section2?.querySelector(".prmt_constaltancy_area_inner2"); 881 882 if (section2 && inner2) { 883 gsap.fromTo( 884 inner2, 885 { 886 scale: 1.5, 887 y: 120, 888 transformOrigin: "center center" 889 }, 890 { 891 scale: 1, 892 y: 0, 893 ease: "none", 894 scrollTrigger: { 895 trigger: section2, 896 start: "top 50%", 897 end: "bottom 80%", 898 scrub: 2, 899 invalidateOnRefresh: true, 900 //markers: true 901 } 902 } 903 ); 904 } 905 906 });
907 908 // ScrollTrigger already refreshes all triggers on resize; no manual re-refresh needed. 909 }); 910 document.addEventListener("DOMContentLoaded", () => { 911 912 window.addEventListener("load", () => { 913 const loopContainers = gsap.utils.toArray(".loop-container"); 914 if(loopContainers){ 915 loopContainers.forEach((el, i) => { 916 // Scope the selector to each loop container 917 const elements = gsap.utils.toArray(".element", el); 918 const loop = horizontalLoop(elements, { 919 repeat: -1, 920 paused: false, 921 paddingRight: 10, 922 reversed: i % 2 > 0 923 }); 924 }); 925 } 926 }); 927 928 function horizontalLoop(items, config) { 929 items = gsap.utils.toArray(items); 930 config = config || {}; 931 let tl = gsap.timeline({ 932 repeat: config.repeat, 933 paused: config.paused, 934 defaults: { ease: "none" }, 935 onReverseComplete: () => tl.totalTime(tl.rawTime() + tl.duration() * 100) 936 }), 937 length = items.length, 938 startX = items[0].offsetLeft, 939 times = [], 940 widths = [], 941 xPercents = [], 942 curIndex = 0, 943 pixelsPerSecond = (config.speed || 1) * 100, 944 snap = config.snap === false ? (v) => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural 945 totalWidth, 946 curX, 947 distanceToStart, 948 distanceToLoop, 949 item, 950 i; 951 gsap.set(items, { 952 // convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster. 953 xPercent: (i, el) => { 954 let w = (widths[i] = parseFloat(gsap.getProperty(el, "width", "px"))); 955 xPercents[i] = snap( 956 (parseFloat(gsap.getProperty(el, "x", "px")) / w) * 100 + 957 gsap.getProperty(el, "xPercent") 958 ); 959 return xPercents[i]; 960 } 961 }); 962 gsap.set(items, { x: 0 }); 963 totalWidth = 964 items[length - 1].offsetLeft + 965 (xPercents[length - 1] / 100) * widths[length - 1] - 966 startX + 967 items[length - 1].offsetWidth * 968 gsap.getProperty(items[length - 1], "scaleX") + 969 (parseFloat(config.paddingRight) || 0); 970 for (i = 0; i < length; i++) { 971 item = items[i]; 972 curX = (xPercents[i] / 100) * widths[i]; 973 distanceToStart = item.offsetLeft + curX - startX; 974 distanceToLoop = 975 distanceToStart + widths[i] * gsap.getProperty(item, "scaleX"); 976 tl.to( 977 item, 978 { 979 xPercent: snap(((curX - distanceToLoop) / widths[i]) * 100), 980 duration: distanceToLoop / pixelsPerSecond 981 }, 982 0 983 ) 984 .fromTo( 985 item, 986 { 987 xPercent: snap( 988 ((curX - distanceToLoop + totalWidth) / widths[i]) * 100 989 ) 990 }, 991 { 992 xPercent: xPercents[i], 993 duration: 994 (curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond, 995 immediateRender: false 996 }, 997 distanceToLoop / pixelsPerSecond 998 ) 999 .add("label" + i, distanceToStart / pixelsPerSecond); 1000 times[i] = distanceToStart / pixelsPerSecond; 1001 } 1002 function toIndex(index, vars) { 1003 vars = vars || {}; 1004 Math.abs(index - curIndex) > length / 2 && 1005 (index += index > curIndex ? -length : length); // always go in the shortest direction 1006 let newIndex = gsap.utils.wrap(0, length, index), 1007 time = times[newIndex]; 1008 if (time > tl.time() !== index > curIndex) { 1009 // if we're wrapping the timeline's playhead, make the proper adjustments 1010 vars.modifiers = { time: gsap.utils.wrap(0, tl.duration()) }; 1011 time += tl.duration() * (index > curIndex ? 1 : -1); 1012 } 1013 curIndex = newIndex;
1014 vars.overwrite = true; 1015 return tl.tweenTo(time, vars); 1016 } 1017 tl.next = (vars) => toIndex(curIndex + 1, vars); 1018 tl.previous = (vars) => toIndex(curIndex - 1, vars); 1019 tl.current = () => curIndex; 1020 tl.toIndex = (index, vars) => toIndex(index, vars); 1021 tl.times = times; 1022 tl.progress(1, true).progress(0, true); // pre-render for performance 1023 if (config.reversed) { 1024 tl.vars.onReverseComplete(); 1025 tl.reverse(); 1026 } 1027 return tl; 1028 } 1029 }); 1030 1031 1032 document.addEventListener("DOMContentLoaded", () => { 1033 const tabs = document.querySelectorAll(".tab-btn"); 1034 if(tabs){ 1035 const wrappers = document.querySelectorAll(".horiz-gallery-wrapper"); 1036 1037 let galleryST = null; 1038 1039 function initHorizontalScroll(wrapper) { 1040 const strip = wrapper.querySelector(".horiz-gallery-strip"); 1041 if (!strip) return; 1042 1043 // ð¹ Kill only this instance 1044 if (galleryST) { 1045 galleryST.kill(true); 1046 galleryST = null; 1047 } 1048 1049 // ð¹ Reset position 1050 gsap.set(strip, { x: 0 }); 1051 1052 // Distance is computed lazily (functional values) so ScrollTrigger 1053 // measures it during its own refresh â no forced reflow here, and 1054 // invalidateOnRefresh recalculates it on resize automatically. 1055 const getScrollLength = () => Math.max(0, strip.scrollWidth - window.innerWidth); 1056 if (getScrollLength() <= 0) return; 1057 1058 galleryST = gsap.to(strip, { 1059 x: () => -getScrollLength(), 1060 ease: "none", 1061 scrollTrigger: { 1062 trigger: "#portfolio", 1063 pin: true, 1064 scrub: 0.3, 1065 start: "top top", 1066 end: () =>
1066 `+=${getScrollLength()}`, 1067 invalidateOnRefresh: true, 1068 anticipatePin: 1, 1069 pinSpacing: true, 1070 1071 // ð¥ IMPORTANT: prevent blocking others 1072 refreshPriority: -1 1073 } 1074 }).scrollTrigger; 1075 } 1076 1077 /* INIT FIRST TAB */ 1078 function initFirstTab() { 1079 const firstActive = document.querySelector(".horiz-gallery-wrapper.active"); 1080 if (firstActive) { 1081 initHorizontalScroll(firstActive); 1082 } 1083 } 1084 1085 window.addEventListener("load", () => { 1086 setTimeout(() => { 1087 initFirstTab(); 1088 }, 100); 1089 }); 1090 1091 /* TAB CLICK */ 1092 tabs.forEach(tab => { 1093 tab.addEventListener("click", () => { 1094 1095 tabs.forEach(t => t.classList.remove("active")); 1096 tab.classList.add("active"); 1097 1098 const target = tab.dataset.tab; 1099 let activeWrap = null; 1100 1101 wrappers.forEach(wrap => { 1102 wrap.classList.remove("active"); 1103 wrap.style.display = "none"; 1104 1105 if (wrap.dataset.tab === target) { 1106 wrap.classList.add("active"); 1107 wrap.style.display = "block"; 1108 activeWrap = wrap; 1109 } 1110 }); 1111 1112 if (activeWrap) { 1113 requestAnimationFrame(() => { 1114 initHorizontalScroll(activeWrap); 1115 // One normal refresh after the layout (display toggle + new pin) settles. 1116 ScrollTrigger.refresh(); 1117 }); 1118 } 1119 }); 1120 }); 1121 } 1122 }); 1123</script>
1123 1124
1124<script> 1125 1126 1127 document.addEventListener("DOMContentLoaded", () => { 1128 const cellCheck = document.querySelector(".cell"); 1129 if(cellCheck){ 1130 if (!window.gsap || !window.Draggable) { 1131 console.error("GSAP or Draggable not loaded"); 1132 return; 1133 } 1134 1135 gsap.registerPlugin(Draggable); 1136 1137 // ð GSAP CONTEXT (prevents conflicts with other scripts) 1138 var picker = document.querySelector(".picker"); 1139 if (!picker) return; 1140 const ctx = gsap.context(() => { 1141 1142 gsap.defaults({ 1143 ease: "none" 1144 }); 1145 1146 // var picker = document.querySelector(".picker"); 1147 // if (!picker) return; 1148 1149 var cells = picker.querySelectorAll(".cell"); 1150 var proxy = document.createElement("div"); 1151 1152 var cellWidth = 250; 1153 var rotation = -90; 1154 1155 var numCells = cells.length; 1156 var cellStep = 1 / numCells; 1157 var wrapWidth = cellWidth * numCells; 1158 var wrapIndex = gsap.utils.wrap(0, cells.length); 1159 1160 var baseTl = gsap.timeline({ paused: true }); 1161 1162 gsap.set(picker, { 1163 perspective: 1100, 1164 width: wrapWidth - cellWidth 1165 }); 1166 1167 for (var i = 0; i < cells.length; i++) { 1168 initCell(cells[i], i); 1169 } 1170 1171 var animation = gsap.timeline({ repeat: -1, paused: true }) 1172 .add(baseTl.tweenFromTo(1, 2)) 1173 .progress(1); 1174 1175 // ð§¼ kill old draggable if script re-runs 1176 if (proxy._draggable) { 1177 proxy._draggable.kill(); 1178 } 1179 1180 var draggable = Draggable.create(proxy, { 1181 allowContextMenu: true, 1182 type: "x", 1183 trigger: picker, 1184 inertia: true, 1185 onDrag: updateProgress, 1186 onThrowUpdate: updateProgress, 1187 snap: { 1188 x: snapX 1189 }, 1190 onDragEnd: function() { 1191 wrapIndex(-this.endX / wrapWidth * cells.length - 5); 1192 } 1193 })[0]; 1194 1195 proxy._draggable = draggable; 1196 1197 function snapX(x) { 1198 return Math.round(x / cellWidth) * cellWidth; 1199 } 1200 1201 function updateProgress() { 1202 let newProg = this.x / wrapWidth; 1203 newProg = newProg - Math.floor(newProg); 1204 animation.progress(newProg); 1205 } 1206 1207 function initCell(element, index) { 1208 1209 gsap.set(element, { 1210 width: cellWidth, 1211 scale: 0.9, 1212 opacity: 0.5, 1213 rotation: rotation, 1214 x: -cellWidth 1215 }); 1216 1217 var tl = gsap.timeline({ repeat: 1 }) 1218 .to(element, 1, { x: "+=" + wrapWidth, rotation: -rotation }, 0) 1219 .to( 1220 element, 1221 cellStep, 1222 { scale: 1, opacity: 1, repeat: 1, yoyo: true }, 1223 0.5 - cellStep 1224 ); 1225 1226 baseTl.add(tl, index * -cellStep); 1227 } 1228 1229 }, picker); 1230 1231 // ð§¹ optional cleanup if needed later 1232 // ctx.revert(); 1233 } 1234 }); 1235 1236 1237 </script>
1237 1238 1239 1240 1241 1242 1243</body> 1244</html>
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.