1/* -------------------------------------------- 2 DOCUMENT.READY 3--------------------------------------------- */ 4 5window.addEventListener("load", () => { 6 const hiddenElements = document.querySelectorAll(".hidden"); 7 8 hiddenElements.forEach((element) => { 9 element.classList.remove("hidden"); 10 element.style.opacity = 0; 11 element.style.transition = `opacity 1s ease-in-out`; 12 setTimeout(() => { 13 element.style.opacity = 1; 14 }, 0); 15 }); 16}); 17 18gsap.registerPlugin(ScrollTrigger, EasePack, CSSRulePlugin, Flip); 19var mobile = Modernizr.mq("(max-width: 992px)"); 20 21var path = window.location.pathname.toString(); 22var url = window.location.href.toString(); 23var pathProto = path.split("/"); 24var pathUrl = url.split("//"); 25if (pathProto[2] === "proto") { 26 var proto = pathProto[3].toString(); 27 if (pathProto[4] === "home" || pathProto[1] === "home") { 28 window.location.replace("https://legacy-admin.spillover.com/spillover/proto/" + proto + "/"); 29 } 30} else if (pathProto[2] === "designs") { 31 var proto = pathProto[3].toString(); 32 if (pathProto[4] === "home" || pathProto[1] === "home") { 33 window.location.replace("https://legacy-admin.spillover.com/spillover/designs/" + proto + "/"); 34 } 35} else { 36 var protoBefore = pathUrl[1].split("."); 37 var proto = protoBefore[0].toString(); 38 39 if (pathProto[4] === "home" || pathProto[1] === "home") { 40 window.location.replace(location.protocol + "//" + location.host); 41 } 42} 43 44let $scrollElement = $(window); 45let $mainNavbar = $("#mainNavbar"); 46let scrollTopDistance; 47function toggleScrolledClass() { 48 if (scrollTopDistance > 10 || (mobile && scrollTopDistance > -1)) { 49 $mainNavbar.addClass("scrolled"); 50 } else { 51 $mainNavbar.removeClass("scrolled"); 52 } 53} 54 55$(window).on("load scroll resize", function (e) { 56 scrollTopDistance = window.pageYOffset; 57 mobile = window.outerWidth <= 992; 58 toggleScrolledClass(); 59}); 60 61// Hero 62 63const hero = document.querySelector("#hero .uk-overlay"); 64const cta = document.querySelectorAll(".cta"); 65const ctaWrap = document.querySelectorAll(".cta-content-wrap"); 66const homeItems = gsap.utils.toArray("#home p, #home h2, #home img"); 67const contactInfoElements = $("#contact .contact-info"); 68const contactIframeElements = $("#contact iframe"); 69const reviewsIframeElements = $("#reviews .uk-slider-container"); 70const headerLogo = $("#mainNavbar .navbar-brand"); 71const headerNav = $("#mainNavbar .navbar-nav"); 72const footerCopyright = $(".spillover img"); 73const footerSpillover = $("#footer .copyright p"); 74 75gsap.to(hero, { 76 autoAlpha: 0, 77 ease: "power1.out", 78 scrollTrigger: { 79 trigger: "#hero", 80 start: "top top", 81 end: "bottom top", 82 scrub: true, 83 onUpdate: function () { 84 if (scrollTopDistance <= 10) { 85 gsap.set(hero, { autoAlpha: 1 }); 86 }
87 ScrollTrigger.update(); 88 }, 89 }, 90}); 91 92// Call To Action/Promotiles 93 94cta.forEach((element) => { 95 const speed = parseFloat(element.dataset.speed) || 1; 96 const ticker = gsap.ticker; 97 98 let targetY = 0; 99 let currentY = 0; 100 101 ticker.add(() => { 102 currentY += (targetY - currentY) * 0.05; 103 gsap.set(element, { 104 y: -currentY * speed, 105 rotation: 0.01, 106 force3D: true, 107 transform: `translateZ(0)`, 108 backfaceVisibility: `hidden`, 109 }); 110 }); 111 112 $scrollElement.on("scroll", function () { 113 targetY = scrollTopDistance * 0.1; 114 }); 115}); 116 117// Optimize CTA wrap animation 118gsap.set(ctaWrap, { autoAlpha: 0, y: 250 }); 119ScrollTrigger.batch(ctaWrap, { 120 start: "top 120%", // Adjusted start value for earlier appearance on desktop 121 end: "0% 100%", 122 onEnter: (batch) => { 123 gsap.to(batch, { autoAlpha: 1, y: 0, duration: 1, ease: "power1.out" }); 124 }, 125}); 126 127// Home 128 129function animateHomeItem(element, speed, offsetY) { 130 const ticker = gsap.ticker; 131 132 let targetY = 0; 133 let currentY = 0; 134 135 ticker.add(() => { 136 currentY += (targetY - currentY) * 0.05; 137 gsap.set(element, { 138 y: (-currentY + offsetY) * speed, 139 rotation: 0.01, 140 force3D: true, 141 transform: `translateZ(0)`, 142 backfaceVisibility: `hidden`, 143 }); 144 }); 145 146 $scrollElement.on("scroll", function () { 147 targetY = scrollTopDistance * 0.1; 148 }); 149} 150 151if (mobile) { 152 homeItems.forEach((element) => { 153 const speed = parseFloat(element.dataset.speed) || 1; 154 animateHomeItem(element, speed, 125); 155 }); 156} else { 157 homeItems.forEach((element) => { 158 const speed = parseFloat(element.dataset.speed) || 1; 159 animateHomeItem(element, speed, 220); 160 }); 161} 162 163// Contact 164 165$(document).ready(() => { 166 // Check if jQuery and GSAP are loaded 167 if (typeof $ === "undefined" || typeof gsap === "undefined") { 168 console.error("jQuery and/or GSAP not loaded"); 169 return; 170 } 171 172 function animateElements(elements, xOffset, yOffset) { 173 elements.each(function () { 174 const element = this; 175 const isAboveViewport = element.getBoundingClientRect().bottom < 0; 176 177 gsap.set(element, { 178 autoAlpha: isAboveViewport ? 1 : 0, 179 x: isAboveViewport ? 0 : xOffset, 180 y: isAboveViewport ? 0 : yOffset 181 }); 182 }); 183 184 ScrollTrigger.batch(elements, { 185 start: "top bottom", 186 once: true, 187 onEnter: (batch) => { 188 gsap.to(batch, { 189 autoAlpha: 1, 190 x: 0, 191 y: 0, 192 ease: "power1.out", 193 duration: 1.5 194 }); 195 } 196 }); 197 } 198 199 function animateElementsOnce(elements, xOffset, yOffset) { 200 gsap.set(elements, { autoAlpha: 0, x: xOffset, y: yOffset, ease: "power1.out" }); 201 gsap.to(elements, { 202 delay: 1, 203 duration: 1, 204 autoAlpha: 1, 205 x: 0, 206 y: 0, 207 ease: "power1.out", 208 }); 209 } 210 211 animateElements(contactInfoElements, -500, 0); 212 animateElements(contactIframeElements, 500, 0); 213 animateElements(reviewsIframeElements, 0, 500); 214 if (!$("body").hasClass("internal")) { 215 animateElementsOnce(headerLogo, -500, 0); 216 animateElementsOnce(headerNav, 500, 0); 217 } 218 animateElements(footerCopyright, 500, 0); 219 animateElements(footerSpillover, -500, 0); 220}); 221 222 223window.addEventListener("load", () => { 224 // Forms 225 226 const modalControlLabels = $(".modal .control-label"); 227 modalControlLabels.each(function () { 228 $(this).removeAttr("style").removeClass("col-sm-3 col-form-label"); 229 const label = $(this).attr("for"); 230 $(this).insertAfter(`.modal #${label}`); 231 }); 232 modalControlLabels.promise().done(function () { 233 modalControlLabels.each(function () { 234 const label = $(this).attr("for"); 235 const elementsWithSameLabel = $(`.modal [for=${label}]`); 236 if (elementsWithSameLabel.length > 1) { 237 elementsWithSameLabel.first().remove(); 238 } 239 }); 240 }); 241 242 const toastContainer = $(".toast-container"); 243 244 toastContainer 245 .find(".control-label") 246 .each(function () { 247 $(this).removeAttr("style").removeClass("col-sm-3 col-form-label"); 248 const label = $(this).attr("for"); 249 $(this).insertAfter(toastContainer.find(`#${label}`)); 250 }) 251 .promise() 252 .done(function () { 253 toastContainer.find(".control-label").each(function () { 254 const label = $(this).attr("for"); 255 if (toastContainer.find(`[for=${label}
255]`).length > 1) { 256 toastContainer.find(`[for=${label}]`).first().remove(); 257 } 258 }); 259 }); 260 261 const $mainControlLabels = $("main .control-label"); 262 $mainControlLabels.each(function () { 263 $(this).removeAttr("style").removeClass("col-sm-3 col-form-label"); 264 const label = $(this).attr("for"); 265 $(this).insertAfter(`main #${label}`); 266 }); 267 $mainControlLabels.promise().done(function () { 268 $mainControlLabels.each(function () { 269 const label = $(this).attr("for"); 270 const $duplicateLabels = $(`main [for=${label}]`).not(this); 271 if ($duplicateLabels.length > 0) { 272 $duplicateLabels.remove(); 273 } 274 }); 275 }); 276 277 setTimeout(function () { 278 $(".cmsform .form-group").each(function () { 279 $(this).addClass("mb-3"); 280 var checkRadio = $(this).find(".cmsform .form-check").length; 281 var hasButton = $(this).find("button").length; 282 var spanChild = $(this).children('span[data-forfield="resume"]').length; 283 var checkChild = $(this).children("div.form-check").length; 284 if (checkRadio === 0 && spanChild === 0 && hasButton === 0 && checkChild === 0) { 285 $(this).addClass("form-floating"); 286 $(this).children(".cmsform label").wrapInner('<span class="formTextColor"></span>'); 287 } 288 if (hasButton !== 0) { 289 $(this).removeClass("mb-3"); 290 } 291 }); 292 $(".hidden-form").fadeIn(1000).removeClass("hidden-form"); 293 294 $(".cmsform .form-control:not([placeholder])").each(function () { 295 $(this).attr("placeholder", " "); 296 }); 297 298 $(".cmsform .form-check-input").each(function () { 299 $(this).attr("style", ""); 300 }); 301 302 $(".cmsform textarea.form-control").each(function () { 303 $(this).attr("rows", "3"); 304 }); 305 }, 500); 306 307 $.datepicker.setDefaults({ 308 minDate: 0, 309 }); 310 311 //replace these with the id's of your datepickers 312 $('input[name="event-date"]').datepicker({ 313 beforeShowDay: function (date) { 314 let day = date.getDay(); 315 let string = jQuery.datepicker.formatDate("d-m-yy", date); 316 let isDisabled = $.inArray(string, disabledDays) != -1; 317 318 //day != 0 disables all Sundays 319 return [day != 0 && !isDisabled]; 320 }, 321 }); 322 323 const socialIcons = gsap.utils.toArray(".social li"); 324 gsap.set(socialIcons, { autoAlpha: 0, x: gsap.utils.random(-100, 100) }); 325 326 const scrollTriggerOptions = { 327 start: "top 100%", 328 end: "bottom 0%", 329 onEnter: (batch) => { 330 gsap.to(batch, { autoAlpha: 1, stagger: 0.05, x: 0 }); 331 }, 332 }; 333 334 ScrollTrigger.batch(socialIcons, scrollTriggerOptions); 335 336 const bottomNavs = gsap.utils.toArray("#footer .nav-item"); 337 gsap.set(bottomNavs, { autoAlpha: 0, y: gsap.utils.random(-100, 100) }); 338 const bottomNavsTriggerOptions = { 339 start: "top bottom", 340 end: "bottom top", 341 onEnter: (batch) => { 342 gsap.to(batch, { autoAlpha: 1, stagger: 0.05, y: 0 }); 343 }, 344 }; 345 346 ScrollTrigger.batch(bottomNavs, bottomNavsTriggerOptions); 347 348 // Internal Pages 349 const excludedPaths = ["calendar", "menu", "food-menu", "beer-and-wine", "gallery", "", "index.htm", "/"]; 350 if (!excludedPaths.includes(pathProto[1]) && !excludedPaths.includes(pathProto[4])) { 351 const internalTitles = gsap.utils.toArray( 352 ".internal #main .container > div, .internal #main .container > div > div" 353 ); 354 gsap.set(internalTitles, { autoAlpha: 0, x: gsap.utils.random(-100, 100), y: gsap.utils.random(-100, 100) }); 355 356 const triggerStart = mobile ? "top 100%" : "top 98%"; 357 const triggerEnd = mobile ? "bottom 0%" : "bottom 2%"; 358 359 ScrollTrigger.batch(internalTitles, { 360 start: triggerStart, 361 end: triggerEnd, 362 onEnter: (batch) => { 363 gsap.to(batch, { autoAlpha: 1, stagger: 0.1, x: 0, y: 0 }); 364 }, 365 }); 366 } 367 368 gsap.delayedCall(mobile ? 1.5 : 1, () => { 369 ScrollTrigger.refresh(true); 370 }); 371}); 372 373// Gallery 374 375window.addEventListener("load", () => { 376 let galleryIsotope = $(".gallery-items").isotope({ 377 itemSelector: ".gallery-item", 378 layoutMode: "masonry", 379 containerStyle: { 380 overflow: "hidden", 381 position: "relative", 382 }, 383 filter: $(".gallery-filters li:first-child").attr("data-filter"), 384 }); 385 386 $(".gallery-filters li").on("click", function () { 387 let galleryFilters = $(".gallery-filters li"); 388 galleryFilters.each(function () { 389 $(this).removeClass("filter-active"); 390 }); 391 $(this).addClass("filter-active"); 392 let filter = $(this).attr("data-filter"); 393 galleryIsotope.isotope({ 394 filter: filter, 395 }); 396 }); 397 398 galleryIsotope.on("arrangeComplete", function () { 399 $(".gallery-item:hidden").removeClass("mag"); 400 $(".gallery-item:visible").addClass("mag"); 401 }); 402 403 galleryIsotope.magnificPopup({ 404 type: "image", 405 delegate: "a.mag", 406 gallery: { 407 enabled: true, 408 }, 409 zoom: { 410 enabled: true, 411 duration: 300, 412 opener: function (e) { 413 return e.find("img"); 414 }, 415 }, 416 }); 417 418 let $galleryContainer = $(".gallery-items"); 419 let $galleryImgs = $("img"); 420 421 $galleryContainer.imagesLoaded(function () { 422 galleryIsotope.isotope({ 423 itemSelector: ".gallery-item", 424 }); 425 $galleryImgs.on("load", function () { 426 galleryIsotope.isotope("layout"); 427 }); 428 }); 429}); 430 431// Refreshes Menu Tabs When Tabbing Through Them 432 433$(".nav-link").on("click", function () { 434 ScrollTrigger.refresh(true); 435}); 436 437// ============================================= 438// Mailing List Cookie 439// ============================================= 440 441let alreadyShowing = false;
442const mailingToast = $("#mailingListToast"); 443let mailingListCookieName = proto + "-mailingList"; 444const toast = new bootstrap.Toast(mailingToast); 445 446if (Cookies.get(mailingListCookieName) == null || Cookies.get(mailingListCookieName) != "false") { 447 Cookies.set(mailingListCookieName, "true", { 448 expires: 7, 449 }); 450} 451$(document).on("scroll", function () { 452 if ($(this).scrollTop() > 500 && Cookies.get(mailingListCookieName) == "true" && alreadyShowing == false) { 453 toast.show(); 454 alreadyShowing = true; 455 } 456}); 457$("#mailingListModal button").on("click", function () { 458 Cookies.set(mailingListCookieName, "false", { 459 expires: 1, 460 }); 461}); 462$("#mailingListToast button").on("click", function () { 463 Cookies.set(mailingListCookieName, "false", { 464 expires: 1, 465 }); 466}); 467$("#mailingListToast .btn.btn-template").on("click", function () { 468 toast.hide(); 469}); 470$('#mailingListModal button[type="submit"]').on("click", function () { 471 Cookies.set(mailingListCookieName, "false", { 472 expires: 180, 473 }); 474}); 475$('#mailingListToast button[type="submit"]').on("click", function () { 476 Cookies.set(mailingListCookieName, "false", { 477 expires: 180, 478 }); 479});
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.