1(function ($) { 2 "use strict"; 3 4 gsap.registerPlugin(Draggable, ScrollTrigger, ScrollToPlugin, InertiaPlugin, ScrollSmoother, Flip); 5 6 gsap.config({ 7 nullTargetWarn: false 8 }); 9 10 function parents(element, selector) { 11 const parentsArray = []; 12 let currentElement = element.parentElement; 13 14 while (currentElement !== null) { 15 if (currentElement.matches(selector)) { 16 parentsArray.push(currentElement); 17 } 18 currentElement = currentElement.parentElement; 19 } 20 21 return parentsArray; 22 } 23 24 var mobileQuery = window.matchMedia('(max-width: 450px)'), 25 siteHeader = $('.site-header'), 26 matchMedia = gsap.matchMedia(), 27 isPhone = '(max-width: 450px)', 28 isTablet = '(min-width: 450px) and (max-width: 900px)', 29 isDesktop = '(min-width: 900px)'; 30 31 32 33 var cursor = document.getElementById('mouseCursor') ? document.getElementById('mouseCursor') : false, 34 cursorText = cursor ? cursor.querySelector('.cursor-text') : false, 35 cursorIcon = cursor ? cursor.querySelector('.cursor-icon') : false; 36 37 38 var keys = { 39 37: 1, 40 38: 1, 41 39: 1, 42 40: 1 43 }; 44 45 function preventDefault(e) { 46 e.preventDefault(); 47 } 48 49 function preventDefaultForScrollKeys(e) { 50 if (keys[e.keyCode]) { 51 preventDefault(e); 52 return false; 53 } 54 } 55 56 57 var supportsPassive = false; 58 try { 59 window.addEventListener("test", null, Object.defineProperty({}, 'passive', { 60 get: function () { 61 supportsPassive = true; 62 } 63 })); 64 } catch (e) { } 65 66 var wheelOpt = supportsPassive ? { 67 passive: false 68 } : false; 69 var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel'; 70 71 // call this to Disable 72 function disableScroll() { 73 74 if (ScrollSmoother.get()) { 75 let farahSmoother = ScrollSmoother.get(); 76 farahSmoother.paused(true); 77 } else { 78 79 window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF 80 window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop 81 window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile 82 window.addEventListener('keydown', preventDefaultForScrollKeys, false); 83 } 84 85 } 86 87 // call this to Enable 88 function enableScroll() { 89 90 if (ScrollSmoother.get()) { 91 let farahSmoother = ScrollSmoother.get(); 92 farahSmoother.paused(false); 93 } else { 94 window.removeEventListener('DOMMouseScroll', preventDefault, false); 95 window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 96 window.removeEventListener('touchmove', preventDefault, wheelOpt); 97 window.removeEventListener('keydown', preventDefaultForScrollKeys, false); 98 } 99 100 } 101 102 103 ///////////////////////// 104 // Global Scripts // 105 ///////////////////////// 106 107 108 function peScrollButton(button) { 109 110 var target = button.dataset.scrollTo, 111 duration = button.dataset.scrollDuration; 112 113 button.addEventListener('click', () => { 114 115 gsap.to(window, { 116 duration: duration, 117 scrollTo: isNaN(target) ? $(target).offset().top : target, 118 ease: 'expo.inOut', 119 }); 120 121 }) 122 123 } 124 125 function resetCursor() { 126 127 cursor.classList.remove('cursor--default') 128 cursor.classList.remove('cursor--text'); 129 cursor.classList.remove('cursor--icon'); 130 cursor.classList.remove('dragging--right'); 131 cursor.classList.remove('dragging--left'); 132 cursorText.innerHTML = ''; 133 cursorIcon.innerHTML = ''; 134 135 } 136 137 barba.hooks.before(() => { 138 139 resetCursor(); 140 }); 141
142 barba.hooks.afterEnter(() => { 143 144 resetCursor(); 145 }); 146 147 148 function peCursorInteraction(target) { 149 150 // Types: default/text/icon 151 152 var type = target.dataset.cursorType, 153 text = target.dataset.cursorText, 154 icon = target.dataset.cursorIcon; 155 156 target.addEventListener('mouseenter', () => { 157 158 if (!target.classList.contains('cursor--disabled')) { 159 160 161 if (type === 'default') { 162 163 cursor.classList.add('cursor--default') 164 } 165 166 if (type === 'text') { 167 168 cursor.classList.add('cursor--text'); 169 cursorText.innerHTML = text; 170 171 } 172 173 if (type === 'icon') { 174 175 cursor.classList.add('cursor--icon'); 176 cursorIcon.innerHTML = icon; 177 178 } 179 } 180 }); 181 182 target.addEventListener('mouseleave', () => resetCursor()); 183 184 } 185 186 187 function peCursorDrag(target, init = true) { 188 resetCursor() 189 190 let width = target.clientWidth; 191 192 function init() { 193 194 cursor.classList.add('cursor--icon'); 195 cursor.classList.add('cursor--drag'); 196 197 cursorIcon.innerHTML = '<i aria-hidden="true" class="material-icons-sharp md-arrow_forward" data-md-icon="arrow_backward"></i>'; 198 199 } 200 201 202 target.addEventListener('mousemove', e => { 203 204 if (e.clientX < width / 2) { 205 206 cursor.classList.remove('dragging--right'); 207 cursor.classList.add('dragging--left'); 208 209 210 } else if (e.clientX > e.clientX < width / 2) { 211 212 cursor.classList.remove('dragging--left'); 213 cursor.classList.add('dragging--right'); 214 } 215 216 217 }) 218 219 target.addEventListener('mouseleave', () => resetCursor()); 220 target.addEventListener('mouseenter', () => init()); 221 222 223 } 224 225 function peCustomSelect(target) { 226 227 var x, i, j, l, ll, selElmnt, a, b, c; 228 /*look for any elements with the class "custom-select":*/ 229 x = target; 230 l = x.length; 231 for (i = 0; i < l; i++) { 232 selElmnt = x[i].getElementsByTagName("select")[0]; 233 ll = selElmnt.length; 234 /*for each element, create a new DIV that will act as the selected item:*/ 235 a = document.createElement("DIV"); 236 a.setAttribute("class", "select-selected"); 237 a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML; 238 a.setAttribute('data-select', selElmnt.options[selElmnt.selectedIndex].innerHTML); 239 x[i].appendChild(a); 240 /*for each element, create a new DIV that will contain the option list:*/ 241 b = document.createElement("DIV"); 242 b.setAttribute("class", "select-items select-hide"); 243 for (j = 1; j < ll; j++) { 244 /*for each option in the original select element, 245 create a new DIV that will act as an option item:*/ 246 c = document.createElement("DIV"); 247 c.innerHTML = selElmnt.options[j].innerHTML; 248 c.addEventListener("click", function (e) { 249 /*when an item is clicked, update the original select box, 250 and the selected item:*/ 251 var y, i, k, s, h, sl, yl; 252 s = this.parentNode.parentNode.getElementsByTagName("select")[0]; 253 sl = s.length; 254 h = this.parentNode.previousSibling; 255 for (i = 0; i < sl; i++) { 256 if (s.options[i].innerHTML == this.innerHTML) { 257 s.selectedIndex = i; 258 h.setAttribute('data-select', this.innerHTML); 259 y = this.parentNode.getElementsByClassName("same-as-selected"); 260 yl = y.length; 261 for (k = 0; k < yl; k++) { 262 y[k].removeAttribute("class"); 263 } 264 this.setAttribute("class", "same-as-selected"); 265 break; 266 } 267 } 268 h.click(); 269 }); 270 b.appendChild(c); 271 } 272 x[i].appendChild(b); 273 a.addEventListener("click", function (e) { 274 /*when the select box is clicked, close any other select boxes, 275 and open/close the current select box:*/ 276 e.stopPropagation(); 277 closeAllSelect(this); 278 this.nextSibling.classList.toggle("select-hide"); 279 this.classList.toggle("select-arrow-active"); 280 }); 281 } 282 283 function closeAllSelect(elmnt) { 284 /*a function that will close all select boxes in the document, 285 except the current select box:*/ 286 var x, y, i, xl, yl, arrNo = []; 287 x = document.getElementsByClassName("select-items"); 288 y = document.getElementsByClassName("select-selected"); 289 xl = x.length; 290 yl = y.length; 291 for (i = 0; i < yl; i++) { 292 if (elmnt == y[i]) { 293 arrNo.push(i) 294 } else { 295 y[i].classList.remove("select-arrow-active"); 296 } 297 } 298 for (i = 0; i < xl; i++) { 299 if (arrNo.indexOf(i)) { 300 x[i].classList.add("select-hide"); 301 } 302 } 303 } 304 /*if the user clicks anywhere outside the select box, 305 then close all select boxes:*/ 306 document.addEventListener("click", closeAllSelect); 307 308 } 309 310 function isPinnng(trigger, add) { 311 312 if (!mobileQuery.matches) { 313 if (add) { 314 if (document.querySelector(trigger)) { 315 document.querySelector(trigger).classList.add('is-pinning') 316 } 317 318 } else { 319 if (document.querySelector(trigger)) { 320 document.querySelector(trigger).classList.remove('is-pinning') 321 } 322 } 323 324 } 325 326 } 327 328 window.addEventListener('elementor/frontend/init', function () { 329 330 if (document.body.classList.contains('e-preview--show-hidden-elements')) { 331 332 document.body.setAttribute('data-barba-prevent', 'all'); 333 334 } 335 336 elementorFrontend.hooks.addAction('frontend/element_ready/global', function ($scope, $) { 337 338 var jsScopeArray = $scope.toArray(); 339 for (var i = 0; i < jsScopeArray.length; i++) { 340 var scope = jsScopeArray[i], 341 id = scope.dataset.id; 342
343 // Reset on Editor 344 if (document.body.classList.contains('e-preview--show-hidden-elements')) { 345 if (ScrollTrigger.getById(id)) { 346 ScrollTrigger.getById(id).kill(); 347 } 348 349 } 350 // Reset on Editor 351 352 var containerBg = document.querySelector('.bg--for--' + id); 353 containerBg ? scope.prepend(containerBg) : ''; 354 355 if (scope.querySelector('.container--bg')) { 356 357 // let video = scope.querySelector('.container--bg').querySelector('.pe-video'); 358 // video ? pe_coreVideo(video) : ''; 359 } 360 361 if (scope.classList.contains('animate--radius')) { 362 363 setTimeout(() => { 364 365 let radius = window.getComputedStyle(scope).borderRadius.split(' '), 366 width = scope.getBoundingClientRect().width, 367 padding = getComputedStyle(scope).getPropertyValue('--container-default-padding-left'); 368 369 gsap.to(scope, { 370 borderRadius: '0px', 371 width: scope.classList.contains('integared--width') ? '100%' : '--width', 372 padding: padding, 373 ease: 'none', 374 scrollTrigger: { 375 trigger: scope, 376 start: 'top bottom', 377 end: 'top top', 378 scrub: true 379 } 380 }) 381 382 gsap.fromTo(scope, { 383 borderRadius: '0px 0px 0px 0px', 384 padding: padding, 385 }, { 386 borderRadius: radius, 387 width: width, 388 padding: 0, 389 ease: 'none', 390 immediateRender: false, 391 scrollTrigger: { 392 trigger: scope, 393 start: 'bottom bottom', 394 end: 'bottom center', 395 scrub: true 396 } 397 }) 398 399 }, 1); 400 401 } 402 403 if (scope.classList.contains('backward__container')) { 404 setTimeout(function(){ 405 ScrollTrigger.create({ 406 trigger: scope, 407 start: 'bottom bottom', 408 end: 'bottom top', 409 scrub: 2, 410 pin: true, 411 pinSpacing: false, 412 id: id 413 }) 414 }, 1000) 415 416 417 } 418 419 if (scope.classList.contains('parallax__active')) { 420 421 gsap.fromTo(scope.querySelector('.parallax--wrap'), { 422 yPercent: -20 423 }, { 424 yPercent: 0, 425 scrollTrigger: { 426 trigger: scope, 427 start: 'top bottom', 428 end: 'bottom top', 429 scrub: true 430 } 431 }) 432 } 433 434 435 //Animations 436 setTimeout(() => { 437 438 if (scope.hasAttribute('data-anim-general')) { 439 440 new peGeneralAnimation(scope, id); 441 442 } 443 444 if (scope.classList.contains('will__animated') && scope.querySelector('.container--anim--hold')) { 445 446 let hold = scope.querySelector('.container--anim--hold'), 447 anim = hold.dataset.animation, 448 sett = hold.dataset.settings; 449 450 scope.setAttribute('data-animation', anim); 451 scope.setAttribute('data-settings', sett); 452 453 new peGeneralAnimation(scope, id); 454 455 456 } 457 458 }, 10); 459 460 if (scope.classList.contains('convert--carousel')) { 461 462 let width = scope.offsetWidth, 463 classList = scope.className, 464 classes = classList.split(' '), 465 carouselIdClass = classes.find(cls => cls.startsWith('carousel_id')), 466 carouselTriggerClass = classes.find(cls => cls.startsWith('carousel_trigger')), 467 trigger = carouselTriggerClass ? carouselTriggerClass.substring("carousel_trigger_".length) : '.' + scope.classList[0], 468 id = carouselIdClass ? carouselIdClass.substring("carousel_id_".length) : scope.dataset.id, 469 items = scope.children; 470 471 for (var i = 0; i < items.length; i++) { 472 473 items[i].classList.contains('e-con') ? items[i].classList.add('cr--item') : ''; 474 items[i].setAttribute('data-cr', i + 1); 475 476 } 477 478 scope.setAttribute('data-total', scope.querySelectorAll('.cr--item').length); 479 480 if (scope.classList.contains('cr--drag')) { 481 482 Draggable.create(scope, { 483 id: id, 484 type: 'x', 485 bounds: { 486 minX: 0, 487 maxX: -width + document.body.clientWidth 488 }, 489 lockAxis: true, 490 dragResistance: 0.5, 491 inertia: true, 492 }); 493 494 scope.classList.contains('cursor_drag') ? peCursorDrag(scope) : ''; 495 496 497 } else if (scope.classList.contains('cr--scroll')) { 498 499 gsap.to(scope, { 500 x: (-1 * width) + document.body.clientWidth, 501 scrollTrigger: { 502 id: id, 503 trigger: trigger, 504 scrub: true, 505 pin: trigger, 506 ease: "elastic.out(1, 0.3)", 507 start: 'center center', 508 end: 'bottom+=6000 bottom' 509 } 510 }) 511 512 } 513 514 } 515 516 if (scope.classList.contains('convert--layered')) { 517 setTimeout(function(){ 518 519 let items = scope.children, 520 classList = scope.className, 521 classes = classList.split(' '), 522 speedClass = classes.find(cls => cls.startsWith('layered_speed')), 523 speed = speedClass ? speedClass.substring("layered_speed_".length) : '.' + scope.classList[0], 524 triggerClass = classes.find(cls => cls.startsWith('layered_target')), 525 trigger = triggerClass ? triggerClass.substring("layered_target_".length) : scope; 526 527 let tl = gsap.timeline({ 528 scrollTrigger: { 529 trigger: trigger, 530 start: 'top top', 531 end: 'bottom+=' + speed + ' top', 532 pin: trigger, 533 scrub: true, 534 markers: false 535 } 536 }); 537 538 539 540 for (var i = 0; i < items.length; i++) { 541 542 if (items[i].classList.contains('e-con')) { 543 544 if (i != 0) { 545 tl.to(items[i], { 546 yPercent: 0, 547 y: 0, 548 ease: 'none' 549 }, 'label_' + i) 550 551 if (window.screen.height < items[i].getBoundingClientRect().height) { 552 553 tl.to(items[i], { 554 y: window.screen.height - items[i].getBoundingClientRect().height, 555 ease: 'none' 556 }, 'label_' + i) 557 558 } 559 560 tl.to(items[i - 1], { 561 // opacity: 0, 562 // scale: 0.9, 563 // '--op': 1, 564 ease: 'none' 565 }, 'label_' + i) 566 567 } 568 } 569 570 571 572 } 573 }, 500) 574 } 575 576 if (scope.classList.contains('convert--tabs')) { 577 let id = scope.dataset.id, 578 innerContent = scope.innerHTML, 579 titles, 580 wrap = document.createElement("div"); 581 582 wrap.classList.add('tabs--wrapper'); 583 scope.insertBefore(wrap, scope.childNodes[0]) 584 585 let wrapper = scope.querySelector('.tabs--wrapper'), 586 econs = Array.from(scope.children).filter(child => child.classList.contains('e-con')); 587 588 if (scope.querySelector('.container--tab--titles--wrap')) { 589 titles = scope.querySelector('.container--tab--titles--wrap'); 590 scope.insertBefore(titles, scope.firstChild); 591 592 } else { 593 titles = document.querySelector('.container--tab--titles__' + id); 594 scope.insertBefore(titles, scope.firstChild); 595 } 596 597 let titlesWrap = scope.querySelector('.container--tab--titles--wrap'); 598 599 600 601 602 for (let i = 0; i <= econs.length; i++) { 603 let tab = econs[i]; 604 605 if (tab && tab.nodeName === 'DIV' && tab.classList.contains('e-con')) { 606 tab.classList.add('container--tab--item'); 607 } 608 } 609 610 let tabItems = scope.querySelectorAll('.container--tab--item'); 611
612 tabItems.forEach((tabItem, i) => { 613 i++ 614 tabItem.classList.add('tab--item__' + i); 615 if (i == 1) { 616 tabItem.classList.add('active'); 617 } 618 }); 619 620 gsap.set(wrapper, { 621 height: scope.querySelector('.container--tab--item.active').offsetHeight 622 }) 623 624 let arr = []; 625 626 titles.querySelectorAll('.container--tab--title').forEach(title => { 627 628 629 arr.push(title.getBoundingClientRect().left); 630 631 title.addEventListener('click', (self) => { 632 633 if (titlesWrap.getBoundingClientRect().width > document.body.clientWidth) { 634 635 gsap.to(titlesWrap, { 636 x: arr[title.dataset.index - 1] * -1 637 }) 638 } 639 640 scope.querySelector('.container--tab--title.active').classList.remove('active'); 641 title.classList.add('active'); 642 643 let findCont = scope.querySelector('.tab--item__' + title.dataset.index), 644 state = Flip.getState(tabItems); 645 646 gsap.set(tabItems, { 647 display: 'none', 648 }) 649 650 gsap.set(findCont, { 651 display: 'flex', 652 }); 653 654 Flip.from(state, { 655 duration: .75, 656 ease: "power3.inOut", 657 absolute: true, 658 fade: true, 659 onStart: () => { 660 661 gsap.to(wrapper, { 662 height: findCont.offsetHeight, 663 duration: .75, 664 ease: "power3.inOut", 665 }) 666 667 }, 668 onComplete: () => { 669 ScrollTrigger.refresh(); 670 }, 671 onEnter: (elements) => 672 gsap.fromTo( 673 elements, 674 { 675 opacity: 0, 676 // y: 300, 677 scale: 0.9 678 }, 679 { 680 opacity: 1, 681 scale: 1, 682 duration: .75, 683 // y: 0, 684 delay: 0, 685 ease: "power3.inOut", 686 } 687 ), 688 onLeave: (elements) => 689 gsap.to(elements, { 690 opacity: 0, 691 scale: .9, 692 duration: .75, 693 ease: "power3.inOut", 694 }) 695 }); 696 697 }) 698 699 }) 700 701 702 703 } 704 if (scope.dataset.title && parents(scope, '.convert--accordion').length) { 705 706 scope.classList.add('container--accordion--item'); 707 scope.classList.add('acc--item__' + scope.dataset.id); 708 } 709 710 if (scope.querySelector('.container--accordion--title') && (!scope.classList.contains('convert--accordion')) && (!scope.classList.contains('convert--tabs'))) { 711 712 let title = scope.querySelector('.container--accordion--title'); 713 714 title.setAttribute('data-id', scope.dataset.id) 715 716 scope.classList.add('container--accordion--item'); 717 scope.classList.add('acc--item__' + scope.dataset.id); 718 719 scope.parentNode.insertBefore(title, scope); 720 721 722 } 723 724 725 setTimeout(() => { 726 if (scope.classList.contains('convert--accordion')) { 727 728 let titles = scope.querySelectorAll('.container--accordion--title'), 729 contents = scope.querySelectorAll('.container--accordion--item'); 730 731 732 if (scope.classList.contains('active--first')) { 733 contents[0].classList.add('cont--acc--active') 734 } 735
736 titles.forEach((title, i) => { 737 i++ 738 title.querySelector('.ac-order').innerHTML = '(0' + i + ')'; 739 740 title.addEventListener('click', () => { 741 742 let id = title.dataset.id, 743 content = scope.querySelector('.acc--item__' + id); 744 745 if (content.classList.contains('cont--acc--active')) { 746 747 title.classList.remove('active') 748 749 var contentState = Flip.getState(content); 750 content.classList.remove('cont--acc--active'); 751 752 Flip.from(contentState, { 753 duration: .75, 754 ease: 'expo.inOut', 755 absolute: false, 756 absoluteOnLeave: false, 757 onComplete: () => { 758 ScrollTrigger.refresh(); 759 }, 760 }) 761 762 } else { 763 764 var currentActive = scope.querySelector('.cont--acc--active'); 765 766 if (currentActive) { 767 let currentTitle = scope.querySelector('.container--accordion--title.active'); 768 769 currentTitle.classList.remove('active'); 770 771 let currentContentState = Flip.getState(currentActive); 772 773 currentActive.classList.remove('cont--acc--active'); 774 775 Flip.from(currentContentState, { 776 duration: .75, 777 ease: 'expo.inOut', 778 absolute: false, 779 absoluteOnLeave: false, 780 onComplete: () => { 781 ScrollTrigger.refresh(); 782 }, 783 }) 784 785 } 786 787 //Open 788 var contentState = Flip.getState(content); 789 content.classList.add('cont--acc--active'); 790 title.classList.add('active') 791 Flip.from(contentState, { 792 duration: .75, 793 ease: 'expo.inOut', 794 absolute: false, 795 absoluteOnLeave: false, 796 onComplete: () => { 797 ScrollTrigger.refresh(); 798 }, 799 }) 800 } 801 }) 802 }) 803 } 804 }, 10); 805 806 if (scope.classList.contains('switch_on_enter')) { 807 808 function switcherClick() { 809 810 if (!document.documentElement.classList.contains('barba--running')) { 811 812 let switcher = document.querySelector('.pe-layout-switcher'); 813 814 if (switcher) { 815 switcher.click(); 816 } 1 817 } 818 819 820 } 821 ScrollTrigger.create({ 822 trigger: scope, 823 start: 'top center', 824 end: 'bottom center', 825 onEnter: () => switcherClick(), 826 onLeave: () => switcherClick(), 827 onEnterBack: () => switcherClick(), 828 onLeaveBack: () => switcherClick(), 829 }) 830 831 } 832 833 834 if (scope.classList.contains('pinned_true')) { 835 836 let items = scope.children, 837 classList = scope.className, 838 classes = classList.split(' '), 839 targetClass = classes.find(cls => cls.startsWith('pin_container')), 840 target = targetClass ? targetClass.substring("pin_container_".length) : '.' + scope.classList[0]; 841 842 let pinnedScroll = ScrollTrigger.create({ 843 trigger: document.querySelector(target), 844 pin: scope, 845 pinSpacing: true, 846 start: 'top top', 847 end: 'bottom bottom', 848 }) 849 850 matchMedia.add({ 851 isMobile: "(max-width: 550px)" 852 853 }, (context) => { 854 855 let { 856 isMobile 857 } = context.conditions; 858 859 pinnedScroll.kill(); 860 861 }); 862 863 } 864 865 866 867 setTimeout(() => { 868 if (scope.classList.contains('curved_true')) { 869 870 let rhTop = document.querySelector('.rh--top.reverse__' + scope.dataset.id); 871 let rhBottom = document.querySelector('.rh--bottom.reverse__' + scope.dataset.id); 872 873 if (rhTop) { 874 gsap.set(rhTop, {
875 '--mainBackground': window.getComputedStyle(scope).backgroundColor 876 }) 877 } 878 if (rhBottom) { 879 gsap.set(rhBottom, { 880 '--mainBackground': window.getComputedStyle(scope).backgroundColor 881 }) 882 883 } 884 } 885 886 }, 50); 887 888 889 890 if (scope.classList.contains('e-parent')) { 891 892 var scopeBg = getComputedStyle(scope).getPropertyValue('background-color'); 893 894 if (scopeBg !== 'rgba(0, 0, 0, 0)') { 895 896 function integrateColors() { 897 898 if (!parents(scope, '.site-header').length) { 899 900 901 let headerColor = getComputedStyle(document.querySelector('.site-header')).getPropertyValue('--intColor'), 902 headerBrightness = gsap.utils.splitColor(headerColor, true)[2], 903 scopeBg = getComputedStyle(scope).getPropertyValue('background-color'), 904 scopeBrightness = gsap.utils.splitColor(scopeBg, true)[2]; 905 906 if (headerBrightness > scopeBrightness) { 907 document.querySelector('.site-header').classList.add('header--switched') 908 909 } 910 } 911 912 } 913 914 setTimeout(() => { 915 916 ScrollTrigger.create({ 917 trigger: scope, 918 start: 'top top+=50', 919 end: 'bottom top+=50', 920 onEnter: () => { 921 integrateColors() 922 }, 923 onEnterBack: () => { 924 integrateColors() 925 }, 926 onLeave: () => { 927 document.querySelector('.site-header').classList.remove('header--switched') 928 }, 929 onLeaveBack: () => { 930 document.querySelector('.site-header').classList.remove('header--switched') 931 }, 932 }) 933 934 935 }, 50); 936 937 } 938 939 } 940 if (scope.dataset.cursor) { 941 942 peCursorInteraction(scope); 943 944 945 946 } 947 948 } 949 950 951 952 }) 953 954 elementorFrontend.hooks.addAction('frontend/element_ready/widget', function ($scope, $) { 955 956 var jsScopeArray = $scope.toArray(); 957 for (var i = 0; i < jsScopeArray.length; i++) { 958 var scope = jsScopeArray[i], 959 id = scope.dataset.id; 960 961 // Scroll Buttons 962 scope.querySelector('.pe--scroll--button') ? peScrollButton(scope.querySelector('.pe--scroll--button')) : ''; 963 // Scroll Buttons 964 965 if (scope.querySelector('.pe--browser--back')) { 966 967 scope.querySelector('.pe--browser--back').addEventListener('click', () => { 968 969 window.history.back(); 970 }) 971 } 972 973 //Animations 974 setTimeout(() => { 975 976 if (scope.querySelector('[data-anim-general="true"]')) { 977 978 var hasAnim = scope.querySelectorAll('[data-anim-general="true"]'); 979 980 hasAnim.forEach(element => { 981 982 if (!scope.querySelector('div[data-elementor-type="pe-menu"]')) { 983 984 new peGeneralAnimation(element) 985 986 } 987 }) 988 989 } 990 991 }, 10); 992 993 994 if (scope.querySelector('[data-anim-image="true"]')) { 995
996 var hasAnim = scope.querySelectorAll('[data-anim-image="true"]'); 997 998 hasAnim.forEach(element => { 999 1000 if (!scope.querySelector('div[data-elementor-type="pe-menu"]')) { 1001 1002 new peImageAnimation(element) 1003 } 1004 1005 }) 1006 1007 } 1008 1009 setTimeout(() => { 1010 1011 if (scope.querySelector('[data-cursor="true"]')) { 1012 1013 var targets = scope.querySelectorAll('[data-cursor="true"]'); 1014 1015 targets.forEach(target => { 1016 1017 peCursorInteraction(target); 1018 1019 }) 1020 1021 } 1022 1023 }, 10); 1024 1025 1026 1027 if (scope.querySelector('[data-animate="true"]')) { 1028 1029 scope.querySelectorAll('[data-animate="true"]').forEach(text => { 1030 if (!scope.querySelector('div[data-elementor-type="pe-menu"]')) { 1031 1032 document.fonts.ready.then((fontFaceSet) => { 1033 1034 if (!text.classList.contains('anim--hold')) { 1035 new peTextAnimation(text, false, false, id); 1036 1037 } else { 1038 1039 let mainNav = scope.querySelector('.main-navigation > .menu'), 1040 items = mainNav.childNodes; 1041 1042 for (let i = 0; i < items.length; i++) { 1043 1044 if (items[i].tagName && items[i].tagName === 'LI') { 1045 items[i].querySelector('a').classList.add('menu--item--anim') 1046 } 1047 1048 } 1049 1050 mainNav.querySelectorAll('.menu--item--anim').forEach(link => { 1051 if (!link.classList.contains('anim--once')) { 1052 new peTextAnimation(link, text.dataset.settings, text.dataset.animation); 1053 } 1054 1055 }) 1056 1057 1058 } 1059 1060 1061 1062 }); 1063 1064 } 1065 }); 1066 1067 } 1068 1069 setTimeout(() => { 1070 1071 if (scope.querySelector('.pe-video')) { 1072 1073 let videos = scope.querySelectorAll('.pe-video') 1074 1075 for (var i = 0; i < videos.length; i++) { 1076 new peVideoPlayer(videos[i]); 1077 } 1078 1079 } 1080 1081 }, 10); 1082 1083 1084 1085 1086 1087 } 1088 1089 }) 1090 1091 elementorFrontend.hooks.addAction('frontend/element_ready/pe-slider.default', function ($scope, $) { 1092 1093 peSlider(); 1094 1095 function peSlider() { 1096 1097 var main = $scope.find('.pe-slider'); 1098 1099 main.each(function () { 1100 let $this = $(this), 1101 wrapper = $this.find('.slider-wrapper'), 1102 slide = $this.find('.pe-slide'), 1103 itemWidth = slide.outerWidth(true), 1104 itemHeight = slide.outerHeight(true), 1105 navButton = $this.find('.navigate-button'), 1106 pinTarget = $this.data('pin-target'), 1107 speed = $this.data('speed'), 1108 next = $this.find('.next'), 1109 prev = $this.find('.prev'), 1110 fraction = $this.find('.pe-fraction'), 1111 activeEl = fraction.find('.active'), 1112 total = fraction.find('.total'), 1113 trigger = pinTarget ? pinTarget : $this; 1114 1115 total.html(slide.length) 1116 1117 if (!pinTarget) { 1118 pinTarget = true 1119 } 1120 1121 slide.each(function (i) { 1122 i++; 1123 1124 let item = $(this) 1125 1126 item.attr('data-index', i); 1127 item.addClass('data-index_' + i) 1128 1129 item.find('.item-wrap').css('width', parseInt(itemWidth)) 1130 item.find('.item-wrap').css('height', parseInt(itemHeight)) 1131 1132 item.find('.slide-image').css('width', parseInt(itemWidth)) 1133 item.find('.slide-image').css('height', parseInt(itemHeight)) 1134 1135 }) 1136 1137 1138 if ($this.hasClass('nav_scroll')) { 1139 1140 1141 let tl = gsap.timeline({ 1142 scrollTrigger: { 1143 trigger: trigger, 1144 start: 'top top', 1145 end: 'bottom bottom', 1146 pin: $this, 1147 scrub: true, 1148 onUpdate: (self) => { 1149 let prog = self.progress * slide.length; 1150 1151 if (prog > 1) { 1152 activeEl.html(Math.floor(prog)) 1153 } 1154 } 1155 } 1156 }) 1157 1158 slide.each(function (i) { 1159 let item = $(this); 1160 1161 if ($this.hasClass('vertical')) { 1162 1163 tl.to($(this), { 1164 ease: 'none', 1165 height: '100%' 1166 }) 1167 1168 slide.first().nextAll().css('height', 0) 1169 1170 } else { 1171 1172 tl.to($(this), { 1173 ease: 'none', 1174 width: '100%' 1175 }) 1176 1177 slide.first().nextAll().css('width', 0) 1178 1179 } 1180 1181 }) 1182 1183 } else if ($this.hasClass('nav_button')) { 1184 1185 var x; 1186 x = 1 1187 1188 navButton.on('click', function (e) { 1189 1190 if ($(this).hasClass('prev')) { 1191 x--; 1192 1193 } else if ($(this).hasClass('next')) { 1194 x++; 1195 } 1196 1197 if (x <= 1) { 1198 x = 1 1199 1200 gsap.to(prev, { 1201 opacity: 0.2 1202 }) 1203 1204 gsap.to(next, { 1205 opacity: 1 1206 }) 1207 1208 } else if (x >= slide.length) { 1209 x = slide.length 1210 1211 gsap.to(next, { 1212 opacity: 0.2 1213 }) 1214 1215 gsap.to(prev, { 1216 opacity: 1 1217 }) 1218 1219 1220 } else if (1 < x < slide.length) { 1221 1222 gsap.to(next, { 1223 opacity: 1 1224 }) 1225 1226 gsap.to(prev, { 1227 opacity: 1 1228 }) 1229 1230 } 1231 1232 if ($(this).hasClass('prev')) { 1233 1234 if ($this.hasClass('vertical')) { 1235 1236 gsap.to($this.find('.data-index_' + (x + 1)), { 1237 height: '0%', 1238 duration: 0.1 1239 }) 1240 1241 } else { 1242 1243 gsap.to($this.find('.data-index_' + (x + 1)), { 1244 width: '0%', 1245 duration: 0.1 1246 }) 1247 1248 } 1249 1250 activeEl.html(x) 1251 1252 } else if ($(this).hasClass('next')) { 1253 1254 gsap.to($this.find('.data-index_' + x), { 1255 width: '100%', 1256 height: '100%', 1257 duration: 0.1 1258 }) 1259 1260 activeEl.html(x) 1261 1262 } 1263 1264 1265 1266 }) 1267 1268 } 1269 1270 1271 1272 }) 1273 1274 } 1275 1276 1277 1278 }); 1279 1280 elementorFrontend.hooks.addAction('frontend/element_ready/petable.default', function ($scope, $) { 1281 1282 var jsScopeArray = $scope.toArray(); 1283 1284 for (var i = 0; i < jsScopeArray.length; i++) { 1285 var scope = jsScopeArray[i], 1286 rows = scope.querySelectorAll('.pe--table--row'); 1287 1288 rows.forEach(row => { 1289 1290 let image = row.querySelector('.pe--table--row--image'); 1291 1292 row.addEventListener("mouseenter", (e) => { 1293 if (image) { 1294 gsap.set(image, { 1295 x: e.layerX, 1296 y: e.layerY 1297 }) 1298 } 1299 1300 1301 }); 1302 row.addEventListener("mousemove", (e) => { 1303 if (image) { 1304 gsap.to(image, { 1305 x: e.layerX + 10,
1306 y: e.layerY + 10, 1307 rotate: e.movementX / 2 1308 }) 1309 } 1310 1311 }); 1312 1313 }) 1314 1315 1316 } 1317 1318 }); 1319 1320 elementorFrontend.hooks.addAction('frontend/element_ready/pegooglemaps.default', function ($scope, $) { 1321 1322 var jsScopeArray = $scope.toArray(); 1323 1324 for (var i = 0; i < jsScopeArray.length; i++) { 1325 var scope = jsScopeArray[i]; 1326 1327 function initMap(latitude, longitude, zoomLevel, mapStyles, markerIcon) { 1328 1329 var mapOptions = { 1330 zoom: zoomLevel, 1331 center: { lat: parseFloat(latitude), lng: parseFloat(longitude) }, 1332 styles: mapStyles, 1333 disableDefaultUI: true, 1334 mapTypeControl: false, 1335 fullscreenControl: false, 1336 zoomControl: false, 1337 streetViewControl: false, 1338 rotateControl: false, 1339 scaleControl: false 1340 }; 1341 1342 var map = new google.maps.Map(document.getElementById('pe--google--map'), mapOptions); 1343 1344 var markerOptions = { 1345 position: mapOptions.center, 1346 map: map, 1347 icon: { 1348 url: markerIcon, 1349 scaledSize: new google.maps.Size(60, 60) 1350 } 1351 }; 1352 1353 var marker = new google.maps.Marker(markerOptions); 1354 } 1355 1356 var mapElement = document.getElementById('pe--google--map'); 1357 1358 if (mapElement) { 1359 1360 var latitude = mapElement.getAttribute('data-latitude'); 1361 var longitude = mapElement.getAttribute('data-longitude'); 1362 var zoomLevel = parseInt(mapElement.getAttribute('data-zoom-level')); 1363 var mapStyles = JSON.parse(mapElement.getAttribute('data-map-styles')); 1364 var markerIcon = mapElement.getAttribute('data-marker-icon'); 1365 1366 initMap(latitude, longitude, zoomLevel, mapStyles, markerIcon); 1367 1368 } 1369 1370 } 1371 1372 }); 1373 1374 elementorFrontend.hooks.addAction('frontend/element_ready/petestimonials.default', function ($scope, $) { 1375 1376 var jsScopeArray = $scope.toArray(); 1377 1378 for (var i = 0; i < jsScopeArray.length; i++) { 1379 var scope = jsScopeArray[i], 1380 testimonials = scope.querySelector('.pe--testimonials'), 1381 wrapper = testimonials.querySelector('.pe--testimonials--wrapper'), 1382 gap = window.getComputedStyle(wrapper).getPropertyValue('gap'), 1383 wrapperHeight = wrapper.clientHeight, 1384 wrapperWidth = wrapper.clientWidth, 1385 items = wrapper.querySelectorAll('.pe-testimonial'); 1386 1387 let maxX = document.body.clientWidth * 0.75, 1388 yVals = []; 1389 1390 items.forEach((item, i) => { 1391 1392 if (testimonials.classList.contains('test--dynamic')) { 1393 let itemX = item.getBoundingClientRect().x - testimonials.getBoundingClientRect().x, 1394 itemWidth = item.getBoundingClientRect().width, 1395 randX = gsap.utils.random((-maxX / 2), (maxX / 2)), 1396 randY = gsap.utils.random(0, 400), 1397 randR = gsap.utils.random(-15, 15); 1398 1399 1400 if (itemX > maxX) { 1401 1402 gsap.set(item, { 1403 x: (-itemX + (maxX / 2) - (itemWidth / 2) + (parseFloat(gap) * 3)) + randX, 1404 y: randY, 1405 rotate: randR 1406 }) 1407 1408 } else if (itemX < (maxX / 2)) { 1409 1410 gsap.set(item, { 1411 x: gsap.utils.random(-250, -100), 1412 y: gsap.utils.random(100, 300), 1413 rotate: randR 1414 }) 1415 1416 } else if (itemX > (maxX / 2)) { 1417 1418 gsap.set(item, { 1419 x: gsap.utils.random(100, (maxX / 3)), 1420 y: gsap.utils.random(100, 300), 1421 rotate: randR 1422 }) 1423 1424 } 1425 1426 yVals.push(randY) 1427 1428 } 1429 1430 1431 }) 1432 1433 wrapper.style.height = (100 + wrapperHeight + Math.max(...yVals)) + 'px'; 1434 1435 if (testimonials.classList.contains('carousel--centered')) { 1436 1437 gsap.set(wrapper, {
1438 x: wrapperWidth / -6 1439 }) 1440 1441 } 1442 1443 Draggable.create(wrapper, { 1444 type: 'x', 1445 bounds: { 1446 minX: 0, 1447 maxX: -wrapperWidth + document.body.clientWidth - 50 1448 }, 1449 lockAxis: true, 1450 dragResistance: 0.5, 1451 inertia: true, 1452 }); 1453 1454 var drag = Draggable.get(wrapper); 1455 1456 if (testimonials.classList.contains('test--dynamic')) { 1457 1458 drag.disable(); 1459 1460 wrapper.addEventListener('click', () => { 1461 1462 var state = Flip.getState(items); 1463 1464 testimonials.classList.add('pt--carousel') 1465 1466 gsap.set(items, { 1467 clearProps: 'all' 1468 }) 1469 1470 Flip.from(state, { 1471 duration: 1, 1472 ease: "power3.inOut", 1473 absolute: true, 1474 absoluteOnLeave: true, 1475 stagger: -0.05 1476 }); 1477 1478 drag.enable(); 1479 peCursorDrag(scope); 1480 wrapper.classList.add('cursor--disabled'); 1481 1482 }) 1483 1484 } 1485 1486 1487 1488 matchMedia.add({ 1489 isMobile: "(max-width: 570px)" 1490 }, (context) => { 1491 1492 let { 1493 isMobile 1494 } = context.conditions; 1495 1496 wrapper.click(); 1497 gsap.set(wrapper, { 1498 height: 'auto' 1499 }) 1500 1501 }); 1502 1503 } 1504 }); 1505 1506 elementorFrontend.hooks.addAction('frontend/element_ready/pesitenavigation.default', function ($scope, $) { 1507 1508 var jsScopeArray = $scope.toArray(); 1509 1510 for (var i = 0; i < jsScopeArray.length; i++) { 1511 var scope = jsScopeArray[i], 1512 nav = scope.querySelector('.site--nav'), 1513 toggle = scope.querySelector('.menu--toggle'), 1514 menu = scope.querySelector('.site--menu'), 1515 hideElements = nav.dataset.hideElements, 1516 clicks = 0; 1517 1518 function hideOnMenu(hide) { 1519 1520 if (hideElements) { 1521 1522 if (hide) { 1523 1524 gsap.to(hideElements, { 1525 opacity: 0 1526 }) 1527 1528 } else { 1529 gsap.to(hideElements, { 1530 opacity: 1 1531 }) 1532 } 1533 1534 } 1535 1536 } 1537 1538 1539 toggle.addEventListener('click', () => { 1540 clicks++ 1541 1542 if (clicks % 2 == 0) { 1543 1544 if (nav.querySelectorAll('.st--active').length) { 1545 1546 nav.querySelectorAll('.st--active').forEach(st => { 1547 st.click(); 1548 }) 1549 } 1550 1551 // Close 1552 toggle.classList.remove('active'); 1553 enableScroll(); 1554 1555 if (nav.classList.contains('nav--popup')) { 1556 popUpNav(false); 1557 1558 } else if (nav.classList.contains('nav--fullscreen')) { 1559 fullscreenNav(false); 1560 } 1561 hideOnMenu(false) 1562 1563 } else { 1564 // Open 1565 toggle.classList.add('active'); 1566 // disableScroll(); 1567 1568 hideOnMenu(true) 1569 1570 if (nav.classList.contains('nav--popup')) { 1571 1572 popUpNav(true) 1573 1574 } else if (nav.classList.contains('nav--fullscreen')) { 1575 1576 fullscreenNav(true); 1577 1578 } 1579 1580 } 1581 1582 }) 1583 1584 // Popup Navigation 1585 1586 function popUpNav(open) { 1587 1588 if (open) { 1589 1590 gsap.to(menu, { 1591 xPercent: 0, 1592 x: 0, 1593 duration: 1.4, 1594 ease: 'expo.inOut', 1595 onStart: () => { 1596 menu.classList.add('active') 1597 } 1598 }) 1599 1600 1601 } else { 1602 1603 gsap.to(menu, { 1604 xPercent: 100, 1605 duration: 1.4, 1606 ease: 'expo.inOut', 1607 onComplete: () => { 1608 menu.classList.remove('active') 1609 } 1610 }) 1611 } 1612 1613 } 1614 1615 // Popup Navigation 1616 1617 // Fullscreen Navigation 1618 function fullscreenNav(open) { 1619 1620 if (nav.classList.contains('overlay--slide')) { 1621 1622 if (open) { 1623 1624 gsap.to(menu, { 1625 height: '100vh', 1626 duration: .8, 1627 ease: 'power4.out' 1628 }) 1629 1630 gsap.to('#primary', { 1631 y: '50vh', 1632 duration: .8, 1633 ease: 'power4.out' 1634 }) 1635 1636 1637 } else { 1638 1639 gsap.to(menu, { 1640 height: '0vh', 1641 duration: .8, 1642 ease: 'power4.out' 1643 }) 1644 gsap.to('#primary', { 1645 y: '0vh', 1646 duration: .8, 1647 ease: 'power4.out' 1648 }) 1649 1650 } 1651 1652 } else if (nav.classList.contains('overlay--blocks')) { 1653 1654 let blocksWrapper = scope.querySelector('.nav--blocks'); 1655 1656 if (open) { 1657 1658 gsap.to(scope.querySelectorAll('.fullscreen--menu--block'), { 1659 height: '100vh', 1660 duration: 1, 1661 ease: 'power4.out', 1662 overwrite: true, 1663 stagger: { 1664 grid: [1, 20], 1665 from: "random", 1666 amount: .3, 1667 }, 1668 onStart: () => { 1669 gsap.set([blocksWrapper, menu], { 1670 visibility: 'visible' 1671 }) 1672 1673 } 1674 }) 1675 1676 1677 } else { 1678 1679 gsap.to(scope.querySelectorAll('.fullscreen--menu--block'), { 1680 height: '0vh', 1681 duration: 1, 1682 ease: 'power4.inOut', 1683 overwrite: true, 1684 id: 'fs--menu--blocks', 1685 stagger: { 1686 grid: [1, 20], 1687 from: "random", 1688 amount: .3, 1689 }, 1690 onComplete: () => { 1691 gsap.set([blocksWrapper, menu], { 1692 visibility: 'hidden' 1693 }) 1694 1695 } 1696 }) 1697 1698 1699 } 1700 1701 1702 } 1703 1704 } 1705 1706 1707 // Fullscreen Navigation 1708 1709 1710 1711 1712 } 1713 }); 1714 1715 elementorFrontend.hooks.addAction('frontend/element_ready/penavmenu.default', function ($scope, $) { 1716 var jsScopeArray = $scope.toArray(); 1717 1718 for (var i = 0; i < jsScopeArray.length; i++) { 1719 var scope = jsScopeArray[i]; 1720 1721 var nav = scope.querySelector('#site-navigation'), 1722 menus = scope.querySelectorAll('ul'), 1723 parentMenu = scope.querySelector('ul.main-menu'), 1724 items = nav.querySelectorAll('.menu-item'), 1725 toggleHTML = nav.dataset.subToggle, 1726 toggle = document.createElement('div'); 1727 1728
1729 items.forEach(item => { 1730 item.querySelector('a').classList.add('menu--link') 1731 }) 1732 1733 if (!scope.classList.contains('nav--init')) { 1734 1735 scope.classList.add('nav--init'); 1736 1737 toggle.classList.add('st--wrap'); 1738 toggle.innerHTML = toggleHTML; 1739 1740 var childrens = []; 1741 var childNodes = parentMenu.childNodes; 1742 1743 for (var i = 0; i < childNodes.length; i++) { 1744 1745 if (childNodes[i].nodeType === 1 && childNodes[i].tagName.toLowerCase() === "li") { 1746 1747 childrens.push(childNodes[i]); 1748 } 1749 } 1750 1751 if (!parentMenu.classList.contains('menu--horizontal')) { 1752 1753 parentMenu.querySelectorAll('.farah-sub-menu-wrap').forEach((sub) => { 1754 sub.remove(); 1755 }); 1756 1757 } 1758 1759 childrens.forEach((item, i) => { 1760 1761 i++ 1762 item.setAttribute('data-index', i); 1763 1764 if (item.classList.contains('menu-item-has-children') || item.classList.contains('farah-has-children')) { 1765 1766 let sub = item.querySelector('.sub-menu'), 1767 a = item.childNodes[0]; 1768 1769 item.insertBefore(toggle.cloneNode(true), sub); 1770 1771 item.querySelector('.st--wrap').addEventListener('click', (self) => { 1772 1773 self.target.classList.toggle('st--active'); 1774 1775 if (item.classList.contains('sub--active')) { 1776 1777 let subState = Flip.getState(sub, { 1778 props: ['padding'] 1779 }); 1780 item.classList.remove('sub--active'); 1781 1782 Flip.from(subState, { 1783 duration: .75, 1784 ease: 'expo.inOut', 1785 absolute: false, 1786 absoluteOnLeave: false, 1787 }) 1788 1789 } else { 1790 1791 nav.querySelector('.sub--active') ? nav.querySelector('.sub--active > .st--wrap').click() : ''; 1792 1793 let subState = Flip.getState(sub, { 1794 props: ['padding'] 1795 }); 1796 1797 item.classList.add('sub--active'); 1798 1799 Flip.from(subState, { 1800 duration: .75, 1801 ease: 'expo.inOut', 1802 absolute: false, 1803 absoluteOnLeave: false, 1804 }) 1805 } 1806 1807 }); 1808 1809 if (!nav.classList.contains('st--only')) { 1810 1811 a.addEventListener('click', (e) => { 1812 1813 e.preventDefault(); 1814 item.querySelector('.st--wrap').click(); 1815 1816 }) 1817 1818 } 1819 1820 } 1821 // Has Children 1822 1823 }) 1824 1825 } 1826 1827 } 1828 }); 1829 1830 1831 1832 elementorFrontend.hooks.addAction('frontend/element_ready/petextwrapper.default', function ($scope, $) { 1833 1834 var jsScopeArray = $scope.toArray(); 1835 1836 for (var i = 0; i < jsScopeArray.length; i++) { 1837 var scope = jsScopeArray[i], 1838 wrapper = scope.querySelector('.text-wrapper'); 1839 1840 document.fonts.ready.then((fontFaceSet) => { 1841 //Inner Elements 1842 var innerElements = wrapper.querySelectorAll('[class^="inner--"]'); 1843
1844 innerElements.forEach((element) => { 1845 1846 let classes = element.classList, 1847 hasMotion = Array.from(classes).some(className => className.startsWith('me--')); 1848 1849 1850 // Motion Effects 1851 if (hasMotion) { 1852 1853 let motion = hasMotion ? Array.from(classes).find(className => className.startsWith('me--')) : null, 1854 duration = element.dataset.duration, 1855 delay = element.dataset.delay, 1856 ease = motion === 'me--flip-x' ? 'none' : motion === 'me--flip-y' ? 'none' : motion === 'me--hearthbeat-x' ? 'power4.inOut' : motion === 'me--slide-left' ? 'power3.in' : motion === 'me--slide-right' ? 'power3.in' : 'expo.out', 1857 tl = gsap.timeline({ 1858 repeat: -1, 1859 repeatDelay: parseInt(delay, 10) 1860 }), 1861 target = element; 1862 1863 1864 if (motion === 'me--slide-left' || motion === 'me--slide-right') { 1865 1866 target = element.firstElementChild; 1867 } 1868 1869 tl.fromTo(target, { 1870 xPercent: 0, 1871 scale: motion === 'me--hearth-beat' ? 0.6 : 1 1872 }, { 1873 1874 scale: 1, 1875 rotate: motion === 'me--rotate' ? -360 : 0, 1876 rotateX: motion === 'me--flip-x' ? -360 : 0, 1877 rotateY: motion === 'me--flip-y' ? -360 : 0, 1878 xPercent: motion === 'me--slide-left' ? -100 : motion === 'me--slide-right' ? 100 : 0, 1879 duration: duration, 1880 ease: ease, 1881 1882 }) 1883 1884 if (motion === 'me--slide-left' || motion === 'me--slide-right') { 1885 1886 tl.fromTo(target, { 1887 xPercent: motion === 'me--slide-left' ? 100 : motion === 'me--slide-right' ? -100 : 0 1888 }, { 1889 xPercent: 0, 1890 duration: duration, 1891 ease: 'power3.out', 1892 }) 1893 } 1894 1895 if (motion === 'me--hearth-beat') { 1896 1897 tl.to(target, { 1898 scale: 0.6, 1899 duration: duration 1900 }) 1901 } 1902 1903 } 1904 1905 if (element.classList.contains('inserted--pin')) { 1906 1907 let state = Flip.getState(element), 1908 target = element.dataset.zoomPin ? element.dataset.zoomPin : scope, 1909 tl = gsap.timeline({ 1910 scrollTrigger: { 1911 trigger: target, 1912 scrub: true, 1913 pin: true, 1914 start: 'center center', 1915 end: 'bottom+=500 top', 1916 } 1917 }); 1918 1919 gsap.set(element, { 1920 position: 'fixed', 1921 width: '100vw', 1922 height: '100vh', 1923 top: 0, 1924 left: 0, 1925 1926 }) 1927 1928 let fl = Flip.from(state, { 1929 absolute: false, 1930 absoluteOnLeave: false, 1931 }) 1932 1933 tl.add(fl, 0) 1934 1935 } 1936 1937 }) 1938 //Inner Elements 1939 1940 //Dyanmic words 1941 function dynamicWordAnimation() { 1942 1943 let dynamicWords = wrapper.querySelectorAll('.pe-dynamic-words'); 1944 1945 dynamicWords.forEach((dynamic) => { 1946 1947 if (!dynamic.classList.contains('dyno--init')) { 1948 dynamic.classList.add('dyno--init'); 1949 1950 let innerWrap = dynamic.firstElementChild, 1951 words = innerWrap.querySelectorAll('span'), 1952 duration = parseFloat(dynamic.dataset.duration),
1953 delay = parseFloat(dynamic.dataset.delay), 1954 pin = dynamic.dataset.pin, 1955 scrub = dynamic.dataset.scrub, 1956 scroll = false; 1957 1958 if (pin === 'true' || scrub === 'true') { 1959 1960 scroll = { 1961 trigger: scope, 1962 pin: pin === 'true' ? scope : false, 1963 scrub: 1, 1964 start: pin === 'true' ? 'center center' : 'top bottom', 1965 end: pin === 'true' ? 'bottom+=500 top' : 'bottom top', 1966 }; 1967 1968 } 1969 1970 let tl = gsap.timeline({ 1971 repeat: pin === 'true' ? 0 : scrub === 'true' ? 0 : -1, 1972 scrollTrigger: scroll 1973 }); 1974 1975 dynamic.style.width = Math.ceil(words[0].getBoundingClientRect().width) + 'px'; 1976 1977 words.forEach((word, i) => { 1978 1979 tl.to(innerWrap, { 1980 yPercent: -100 / words.length * i, 1981 duration: duration, 1982 delay: i == 0 ? 0 : delay, 1983 ease: scroll ? 'none' : 'expo.inOut' 1984 }, 'label_' + i) 1985 1986 tl.to(dynamic, { 1987 width: Math.ceil(word.getBoundingClientRect().width), 1988 duration: duration, 1989 delay: delay, 1990 ease: scroll ? 'none' : 'expo.inOut' 1991 }, 'label_' + i) 1992 1993 1994 }) 1995 1996 } 1997 1998 1999 2000 }) 2001 2002 } 2003 2004 dynamicWordAnimation(); 2005 //Dyanmic words 2006 2007 setTimeout(() => { 2008 2009 if (scope.querySelector('.custom-lines-hold')) { 2010 2011 for (let i = 0; i < wrapper.childNodes.length; i++) { 2012 2013 if (wrapper.childNodes[i].tagName) { 2014 new SplitText(wrapper.childNodes[i], { 2015 type: "lines", 2016 linesClass: "customized--line", 2017 }); 2018 } 2019 2020 } 2021 2022 wrapper.querySelectorAll('.customized--line').forEach((line, i) => { 2023 i++ 2024 line.classList.add('cs--line--' + i) 2025 }) 2026 2027 let holds = scope.querySelectorAll('.csl--hold'); 2028 2029 if (holds) { 2030 2031 holds.forEach(hold => { 2032 2033 let line = hold.dataset.line, 2034 id = hold.dataset.id, 2035 findLine = '.cs--line--' + line; 2036 2037 if (scope.querySelector(findLine)) { 2038 2039 scope.querySelector(findLine).classList.add('elementor-repeater-item-' + id); 2040 2041 } 2042 2043 2044 2045 2046 2047 }) 2048 } 2049 2050 } 2051 2052 }, 50); 2053 2054 2055 2056 }); 2057 2058 } 2059 2060 }); 2061 2062 elementorFrontend.hooks.addAction('frontend/element_ready/pevideo.default', function ($scope, $) { 2063 2064 var jsScopeArray = $scope.toArray(); 2065 for (var i = 0; i < jsScopeArray.length; i++) { 2066 var scope = jsScopeArray[i]; 2067 2068 // new peVideoPlayer(scope.querySelector('.pe-video')); 2069 2070 2071 } 2072 2073 }); 2074 2075 elementorFrontend.hooks.addAction('frontend/element_ready/pecircletext.default', function ($scope, $) { 2076 2077 var jsScopeArray = $scope.toArray(); 2078 2079 for (var i = 0; i < jsScopeArray.length; i++) { 2080 var scope = jsScopeArray[i]; 2081 2082 if (scope) { 2083 var circularText = scope.querySelectorAll('.pe-circular-text'); 2084 2085 2086 circularText.forEach(function ($this) { 2087 var textWrap = $this.querySelector('.circular-text-wrap'), 2088 circularContent = $this.querySelector(".circular-text-content"), 2089 dataHeight = $this.dataset.height, 2090 dataDuration = $this.dataset.duration, 2091 dataTarget = $this.dataset.target, 2092 circleSplit = new SplitText($this.querySelector('.circle-text'), {
2093 type: "words, chars", 2094 charsClass: "circle-char", 2095 wordsClass: "circle-word", 2096 position: "absolute" 2097 }), 2098 fontSize = parseInt(window.getComputedStyle($this.querySelector('.circle-char')).fontSize), 2099 charLength = $this.querySelectorAll('.circle-char').length, 2100 textLength = (dataHeight / charLength) / (fontSize / 1.75), 2101 circleChar = $this.querySelectorAll('.circle-char'), 2102 circleWord = $this.querySelectorAll('.circle-word'), 2103 snap = gsap.utils.snap(1), 2104 dataIcon = $this.dataset.icon; 2105 2106 for (var i = 2; i <= snap(textLength); i++) { 2107 var clonedContent = circularContent.cloneNode(true); 2108 textWrap.appendChild(clonedContent); 2109 } 2110 circularContent = $this.querySelectorAll(".circular-text-content"); 2111 2112 gsap.set(circularContent, { 2113 width: dataHeight, 2114 height: dataHeight 2115 }) 2116 2117 var circleWordElements = $this.querySelectorAll('.circle-word'); 2118 2119 circleWordElements.forEach(function (circleWordElement) { 2120 var circleCharElement = document.createElement('span'); 2121 circleCharElement.className = 'circle-char'; 2122 circleWordElement.appendChild(circleCharElement); 2123 }); 2124 2125 $this.querySelectorAll('.circle-word').forEach(function (circleWordElement) { 2126 gsap.set(circleWordElement, { 2127 left: '50%', 2128 top: 0, 2129 height: "100%", 2130 xPercent: -50 2131 }) 2132 }); 2133 2134 var charElements = $this.querySelectorAll('.circle-char'), 2135 rotateMultiplier = 360 / charElements.length; 2136 2137 charElements.forEach(function (charElement, index) { 2138 2139 gsap.set(charElement, { 2140 rotate: rotateMultiplier * index, 2141 left: '50%', 2142 xPercent: -50, 2143 top: 0, 2144 height: "50%" 2145 }); 2146 2147 }); 2148 2149 var tl = gsap.timeline(); 2150 2151 gsap.set(textWrap, { 2152 width: dataHeight, 2153 height: dataHeight 2154 }); 2155 2156 if ($this.classList.contains('counter-clockwise')) { 2157 tl.to(textWrap, { 2158 rotation: -360, 2159 duration: dataDuration, 2160 ease: "none", 2161 repeat: -1 2162 }); 2163 } else { 2164 tl.to(textWrap, { 2165 rotation: 360, 2166 duration: dataDuration, 2167 ease: "none", 2168 repeat: -1 2169 }); 2170 } 2171 2172 let whaler = Hamster(document.querySelector('body')), 2173 wheelDeltaY, currentDeltaY; 2174 2175 function createWheelStopListener(element, callback, timeout) { 2176 var handle = null; 2177 var onScroll = function () { 2178 if (handle) { 2179 clearTimeout(handle); 2180 } 2181 handle = setTimeout(callback, timeout || 200); // 2182 }; 2183 element.addEventListener('wheel', onScroll); 2184 return function () { 2185 element.removeEventListener('wheel', onScroll); 2186 }; 2187 } 2188 2189 whaler.wheel(function (event, delta, deltaX, deltaY) { 2190 2191 wheelDeltaY = event.deltaY; 2192 event.deltaY < 0 ? wheelDeltaY = -1 * event.deltaY : ''; 2193 tl.timeScale(1 + (wheelDeltaY * 2)) 2194 2195 }); 2196 2197 createWheelStopListener(window, function () { 2198 tl.timeScale(1) 2199 }); 2200 2201 $this.addEventListener('click', function () { 2202 window.scrollTo({ 2203 top: document.querySelector(dataTarget).offsetTop, 2204 behavior: "smooth" 2205 }); 2206 }); 2207 2208 2209 }) 2210 2211 } 2212 2213 2214 2215 2216 2217 } 2218 }); 2219 2220 elementorFrontend.hooks.addAction('frontend/element_ready/pesccontrols.default', function ($scope, $) { 2221 2222 setTimeout(function () { 2223 2224 var jsScopeArray = $scope.toArray(); 2225 2226 for (var i = 0; i < jsScopeArray.length; i++) { 2227 2228 var scope = jsScopeArray[i], 2229 control = scope.querySelector('.pe--sc--controls'), 2230 id = control.dataset.id, 2231 target = document.querySelector('.' + id), 2232 items = target.querySelectorAll('.cr--item'), 2233 vars = { 2234 progress: '', 2235 current: '', 2236 total: target.dataset.total, 2237 width: items[0].offsetWidth 2238 }; 2239 2240 control.classList.add('sc--id__' + id) 2241 2242 if (scope.querySelector('.sc--fraction')) { 2243 2244 const totalElement = scope.querySelector('.sc--total'); 2245 if (totalElement) { 2246 if (control.classList.contains('unitaze--numbers')) { 2247 totalElement.innerHTML = vars.total < 10 ? '0' + vars.total : vars.total; 2248 } else { 2249 totalElement.innerHTML = vars.total; 2250 } 2251 } 2252 2253 } 2254 2255 function getCurrentItem() { 2256
2257 let crValues = []; 2258 2259 items.forEach(item => { 2260 2261 if (item.getBoundingClientRect().x < (document.body.clientWidth * 0.75)) { 2262 crValues.push(parseInt(item.dataset.cr, 10)); 2263 } 2264 2265 }); 2266 2267 if (crValues.length > 0) { 2268 let maxCrValue = Math.max(...crValues); 2269 if (control.classList.contains('unitaze--numbers')) { 2270 2271 vars.current = maxCrValue < 10 ? '0' + maxCrValue : maxCrValue; 2272 2273 } else { 2274 vars.current = maxCrValue; 2275 } 2276 2277 } 2278 2279 scope.querySelector('.sc--current') ? scope.querySelector('.sc--current').innerHTML = vars.current : ''; 2280 2281 } 2282 2283 getCurrentItem() 2284 2285 function updateOthers() { 2286 2287 let allControls = document.querySelectorAll('.sc--id__' + id); 2288 2289 if (allControls.length > 1) { 2290 2291 allControls.forEach(control => { 2292 2293 let fraction = control.querySelector('.sc--fraction'); 2294 2295 if (fraction) { 2296 2297 let current = fraction.querySelector('.sc--current'), 2298 total = fraction.querySelector('.sc--total'); 2299 2300 getCurrentItem() 2301 2302 if (control.classList.contains('unitaze--numbers')) { 2303 2304 current.innerHTML = vars.current < 10 ? '0' + vars.current : vars.current; 2305 total.innerHTML = vars.total < 10 ? '0' + vars.total : vars.total; 2306 2307 } else { 2308 current.innerHTML = vars.current; 2309 total.innerHTML = vars.total; 2310 2311 } 2312 2313 } 2314 2315 }) 2316 2317 } 2318 2319 } 2320 2321 if (target.classList.contains('cr--scroll')) { 2322 2323 let tween = gsap.getById(id); 2324 2325 tween.eventCallback('onUpdate', self => { 2326 2327 vars.progress = tween.progress() * 100; 2328 2329 2330 let crValues = []; 2331 2332 items.forEach(item => { 2333 2334 if (item.getBoundingClientRect().x < (document.body.clientWidth * 0.75)) { 2335 2336 crValues.push(parseInt(item.dataset.cr, 10)); 2337 } 2338 2339 }); 2340 2341 if (crValues.length > 0) { 2342 let maxCrValue = Math.max(...crValues); 2343 vars.current = maxCrValue; 2344 2345 } 2346 2347 2348 if (scope.querySelector('.sc--fraction')) { 2349 2350 let current = scope.querySelector('.sc--current'), 2351 total = scope.querySelector('.sc--total'); 2352 2353 current.innerHTML = vars.current; 2354 total.innerHTML = vars.total; 2355 2356 2357 } 2358 2359 if (scope.querySelector('.sc--progressbar')) { 2360 2361 let prog = scope.querySelector('.sc--prog'); 2362 2363 gsap.to(prog, { 2364 width: vars.progress + '%' 2365 }) 2366 2367 } 2368 2369 }) 2370 2371 2372 } 2373 2374 if (target.classList.contains('cr--drag') || target.classList.contains('cr__drag')) { 2375 2376 let draggable = Draggable.get(target); 2377 2378 if (draggable) { 2379 2380 draggable.addEventListener('throwupdate', () => { 2381 2382 vars.progress = draggable.x / draggable.minX * 100; 2383 2384 if (scope.querySelector('.sc--fraction')) { 2385 2386 let current = scope.querySelector('.sc--current'), 2387 total = scope.querySelector('.sc--total'); 2388 2389 getCurrentItem() 2390 2391 current.innerHTML = vars.current; 2392 total.innerHTML = vars.total; 2393 2394 } 2395 2396 if (scope.querySelector('.sc--progressbar')) { 2397 2398 let prog = scope.querySelector('.sc--prog'); 2399 2400 gsap.to(prog, { 2401 width: vars.progress + '%' 2402 }) 2403 } 2404 2405 }); 2406 2407 2408 if (scope.querySelector('.sc--navigation')) { 2409 2410 let next = scope.querySelector('.sc--next'), 2411 prev = scope.querySelector('.sc--prev'), 2412 xVal = 0; 2413 2414 next.addEventListener('click', () => { 2415 2416 xVal = draggable.x; 2417 xVal -= vars.width; 2418 2419 gsap.to(target, { 2420 x: xVal, 2421 onUpdate: () => { 2422 draggable.update(true); 2423 updateOthers(); 2424 } 2425 }) 2426 2427 }) 2428 2429 prev.addEventListener('click', () => { 2430 2431 xVal = draggable.x; 2432 xVal += vars.width; 2433 2434 gsap.to(target, { 2435 x: xVal, 2436 onUpdate: () => { 2437 draggable.update(true); 2438 updateOthers(); 2439 } 2440 }) 2441 2442 2443 }) 2444 2445 } 2446 2447 } 2448 2449 } 2450 2451 2452 if (target.classList.contains('cr--slideshow')) { 2453 2454 2455 2456 2457 } 2458 2459 } 2460 2461 }, 10) 2462 }) 2463 2464 elementorFrontend.hooks.addAction('frontend/element_ready/pecarousel.default', function ($scope, $) { 2465 2466 var jsScopeArray = $scope.toArray(); 2467 for (var i = 0; i < jsScopeArray.length; i++) { 2468 2469 var scope = jsScopeArray[i], 2470 carousel = scope.querySelector('.pe--carousel'), 2471 wrapper = carousel.querySelector('.carousel--wrapper'), 2472 id = carousel.dataset.id ? carousel.dataset.id : scope.dataset.id, 2473 items = carousel.querySelectorAll('.carousel--item'), 2474 length = items.length,
2475 wrapperWidth = wrapper.offsetWidth, 2476 carouselWidth = carousel.offsetWidth, 2477 trigger = carousel.dataset.trigger ? carousel.dataset.trigger : '.' + carousel.classList[0]; 2478 2479 // document.querySelector(trigger) ? document.querySelector(trigger).classList.add('pin--trigger') : ''; 2480 2481 items.forEach(item => { 2482 var index = parseInt(item.dataset.index); 2483 }); 2484 2485 function carouselScroll() { 2486 2487 gsap.to(wrapper, { 2488 x: (-1 * wrapperWidth) + carouselWidth, 2489 scrollTrigger: { 2490 trigger: trigger, 2491 scrub: true, 2492 pin: trigger, 2493 ease: "elastic.out(1, 0.3)", 2494 start: 'center center', 2495 end: 'bottom+=6000 bottom', 2496 pinSpacing: 'padding', 2497 onEnter: () => isPinnng(trigger, true), 2498 onEnterBack: () => isPinnng(trigger, true), 2499 onLeave: () => isPinnng(trigger, false), 2500 onLeaveBack: () => isPinnng(trigger, false), 2501 } 2502 }) 2503 2504 } 2505 2506 function carouselDrag() { 2507 2508 Draggable.create(wrapper, { 2509 type: 'x', 2510 bounds: { 2511 minX: 0, 2512 maxX: -wrapperWidth + document.body.clientWidth - 50 2513 }, 2514 lockAxis: true, 2515 dragResistance: 0.5, 2516 inertia: true, 2517 }); 2518 2519 2520 } 2521 2522 function carouselLoop() { 2523 2524 var tl = gsap.timeline({ 2525 repeat: -1, 2526 }), 2527 direction = wrapper.dataset.direction, 2528 speed = parseInt(wrapper.dataset.speed), 2529 speedUp = wrapper.dataset.speedUp; 2530 2531 items.forEach(item => { 2532 let clone = item.cloneNode(true); 2533 wrapper.appendChild(clone); 2534 }); 2535 2536 if (direction !== 'right-to-left') { 2537 // Reverse the order of items and prepend 2538 Array.from(items).reverse().forEach(item => { 2539 let clone = item.cloneNode(true); 2540 wrapper.prepend(clone); 2541 }); 2542 } 2543 2544 wrapper.style.width = wrapperWidth * 2 2545 2546 let gap = window.getComputedStyle(wrapper).getPropertyValue('gap'); 2547 2548 if (direction === 'right-to-left') { 2549 2550 tl.to(wrapper, { 2551 x: -wrapperWidth - parseFloat(gap), 2552 duration: speed, 2553 ease: 'none', 2554 }); 2555 2556 } else { 2557 2558 gsap.set(wrapper, { 2559 x: -wrapperWidth - parseFloat(gap) 2560 }) 2561 2562 tl.fromTo(wrapper, { 2563 x: -wrapperWidth - parseFloat(gap) 2564 }, { 2565 x: 0, 2566 duration: speed, 2567 ease: 'none', 2568 }) 2569 } 2570 2571 if (speedUp) { 2572 2573 let whaler = Hamster(document.querySelector('body')), 2574 wheelDeltaY, currentDeltaY; 2575 2576 function createWheelStopListener(element, callback, timeout) { 2577 var handle = null; 2578 var onScroll = function () { 2579 if (handle) { 2580 clearTimeout(handle); 2581 } 2582 handle = setTimeout(callback, timeout || 200); // 2583 }; 2584 element.addEventListener('wheel', onScroll); 2585 return function () { 2586 element.removeEventListener('wheel', onScroll); 2587 }; 2588 } 2589 2590 whaler.wheel(function (event, delta, deltaX, deltaY) { 2591 2592 wheelDeltaY = event.deltaY; 2593 event.deltaY < 0 ? wheelDeltaY = -1 * event.deltaY : ''; 2594 tl.timeScale(1 + (wheelDeltaY * 3)) 2595 2596 }); 2597 2598 createWheelStopListener(window, function () { 2599 tl.timeScale(1) 2600 }); 2601 2602 } 2603 2604 } 2605 2606 carousel.classList.contains('cr--scroll') ? carouselScroll() : carousel.classList.contains('cr--drag') ? carouselDrag() : carouselLoop(); 2607 2608 } 2609 2610 }); 2611 2612 elementorFrontend.hooks.addAction('frontend/element_ready/peicon.default', function ($scope, $) { 2613 2614 var jsScopeArray = $scope.toArray(); 2615 for (var i = 0; i < jsScopeArray.length; i++) { 2616 var scope = jsScopeArray[i], 2617 animated = scope.querySelectorAll('.icon--motion'); 2618 2619 animated.forEach((element) => { 2620 2621 let classes = element.classList, 2622 hasMotion = Array.from(classes).some(className => className.startsWith('me--')); 2623
2624 // Motion Effects 2625 if (hasMotion) { 2626 2627 let motion = hasMotion ? Array.from(classes).find(className => className.startsWith('me--')) : null, 2628 duration = element.dataset.duration, 2629 delay = element.dataset.delay, 2630 ease = motion === 'me--flip-x' ? 'none' : motion === 'me--flip-y' ? 'none' : motion === 'me--hearthbeat-x' ? 'power4.inOut' : motion === 'me--slide-left' ? 'power3.in' : motion === 'me--slide-right' ? 'power3.in' : motion === 'me--slide-down' ? 'expo.in' : motion === 'me--slide-up' ? 'expo.in' : 'expo.out', 2631 tl = gsap.timeline({ 2632 repeat: -1, 2633 repeatDelay: parseInt(delay, 10) 2634 }), 2635 target = element.querySelector('i, svg'); 2636 2637 2638 2639 if (motion === 'me--slide-left' || motion === 'me--slide-right') { 2640 2641 target = element.firstElementChild; 2642 } 2643 2644 tl.fromTo(target, { 2645 xPercent: 0, 2646 yPercent: 0, 2647 scale: motion === 'me--hearth-beat' ? 0.6 : 1 2648 }, { 2649 2650 scale: 1, 2651 rotate: motion === 'me--rotate' ? -360 : 0, 2652 rotateX: motion === 'me--flip-x' ? -360 : 0, 2653 rotateY: motion === 'me--flip-y' ? -360 : 0, 2654 xPercent: motion === 'me--slide-left' ? -300 : motion === 'me--slide-right' ? 300 : 0, 2655 yPercent: motion === 'me--slide-down' ? 200 : motion === 'me--slide-up' ? -200 : 0, 2656 duration: duration, 2657 ease: ease, 2658 2659 }) 2660 2661 if (motion === 'me--slide-left' || motion === 'me--slide-right') { 2662 2663 tl.fromTo(target, { 2664 xPercent: motion === 'me--slide-left' ? 300 : motion === 'me--slide-right' ? -300 : 0 2665 }, { 2666 xPercent: 0, 2667 duration: duration, 2668 ease: 'power3.out', 2669 }) 2670 } 2671 2672 if (motion === 'me--slide-down' || motion === 'me--slide-up') { 2673 2674 tl.fromTo(target, { 2675 yPercent: motion === 'me--slide-down' ? -200 : motion === 'me--slide-up' ? 200 : 0 2676 }, { 2677 yPercent: 0, 2678 duration: duration, 2679 ease: 'power3.out', 2680 }) 2681 } 2682 2683 if (motion === 'me--hearth-beat') { 2684 2685 tl.to(target, { 2686 scale: 0.6, 2687 duration: duration 2688 }) 2689 } 2690 2691 } 2692 2693 }) 2694 2695 2696 } 2697 2698 }); 2699 2700 elementorFrontend.hooks.addAction('frontend/element_ready/pelayoutswitcher.default', function ($scope, $) { 2701 2702 var jsScopeArray = $scope.toArray(); 2703 for (var i = 0; i < jsScopeArray.length; i++) { 2704 var scope = jsScopeArray[i], 2705 switcher = scope.querySelector('.pe-layout-switcher'); 2706 2707 let mainColors = [ 2708 getComputedStyle(document.documentElement).getPropertyValue('--mainColor'), 2709 getComputedStyle(document.documentElement).getPropertyValue('--mainBackground'), 2710 getComputedStyle(document.documentElement).getPropertyValue('--secondaryColor'), 2711 getComputedStyle(document.documentElement).getPropertyValue('--secondaryBackground'), 2712 ] 2713 2714 let switchedColors = [ 2715 getComputedStyle(document.querySelector('.layout--colors')).getPropertyValue('--mainColor'), 2716 getComputedStyle(document.querySelector('.layout--colors')).getPropertyValue('--mainBackgroun
2716d'), 2717 getComputedStyle(document.querySelector('.layout--colors')).getPropertyValue('--secondaryColor'), 2718 getComputedStyle(document.querySelector('.layout--colors')).getPropertyValue('--secondaryBackground'), 2719 ] 2720 2721 2722 switcher.addEventListener('click', () => { 2723 2724 if (document.body.classList.contains('layout--switched')) { 2725 2726 gsap.fromTo(document.body, { 2727 '--mainColor': switchedColors[0], 2728 '--mainBackground': switchedColors[1], 2729 '--secondaryColor': switchedColors[2], 2730 '--secondaryBackground': switchedColors[3], 2731 }, { 2732 '--mainColor': mainColors[0], 2733 '--mainBackground': mainColors[1], 2734 '--secondaryColor': mainColors[2], 2735 '--secondaryBackground': mainColors[3], 2736 duration: 1, 2737 ease: 'power3.out', 2738 onStart: () => { 2739 document.body.classList.remove('layout--switched') 2740 } 2741 }) 2742 2743 } else { 2744 2745 2746 gsap.fromTo(document.body, { 2747 '--mainColor': mainColors[0], 2748 '--mainBackground': mainColors[1], 2749 '--secondaryColor': mainColors[2], 2750 '--secondaryBackground': mainColors[3], 2751 }, { 2752 '--mainColor': switchedColors[0], 2753 '--mainBackground': switchedColors[1], 2754 '--secondaryColor': switchedColors[2], 2755 '--secondaryBackground': switchedColors[3], 2756 duration: 1, 2757 ease: 'power3.out', 2758 onStart: () => { 2759 document.body.classList.add('layout--switched') 2760 } 2761 }) 2762 2763 } 2764 2765 }) 2766 2767 2768 2769 } 2770 2771 }); 2772 2773 elementorFrontend.hooks.addAction('frontend/element_ready/peteammember.default', function ($scope, $) { 2774 2775 var jsScopeArray = $scope.toArray(); 2776 for (var i = 0; i < jsScopeArray.length; i++) { 2777 var scope = jsScopeArray[i], 2778 member = scope.querySelector('.pe--team--member'), 2779 toggle = scope.querySelector('.team--member--toggle'); 2780 2781 toggle.addEventListener('click', () => { 2782 2783 member.classList.toggle('active'); 2784 2785 }) 2786 2787 2788 } 2789 2790 }) 2791 2792 elementorFrontend.hooks.addAction('frontend/element_ready/peclients.default', function ($scope, $) { 2793 2794 var jsScopeArray = $scope.toArray(); 2795 for (var i = 0; i < jsScopeArray.length; i++) { 2796 var scope = jsScopeArray[i], 2797 clients = scope.querySelector('.pe--clients'); 2798 2799 if (clients.classList.contains('pe--clients--carousel')) { 2800 2801 let wrapper = clients.querySelector('.pe--clients--wrapper'), 2802 wrapperWidth = wrapper.offsetWidth, 2803 items = wrapper.querySelectorAll('.pe-client'), 2804 speed = clients.dataset.speed, 2805 direction = clients.dataset.direction, 2806 stopHover = clients.dataset.hover; 2807 2808 if (items.length > 0) { 2809 2810 var tl = gsap.timeline({ 2811 repeat: -1, 2812 }); 2813 2814 items.forEach(item => { 2815 let clone = item.cloneNode(true); 2816 wrapper.appendChild(clone); 2817 }); 2818 2819 if (direction !== 'right-to-left') { 2820 // Reverse the order of items and prepend
2821 Array.from(items).reverse().forEach(item => { 2822 let clone = item.cloneNode(true); 2823 wrapper.prepend(clone); 2824 }); 2825 } 2826 2827 2828 wrapper.style.width = wrapperWidth * 2 2829 2830 2831 let gap = window.getComputedStyle(wrapper).getPropertyValue('gap'); 2832 2833 if (direction === 'right-to-left') { 2834 2835 tl.to(wrapper, { 2836 x: -wrapperWidth - parseFloat(gap), 2837 duration: speed, 2838 ease: 'none', 2839 2840 }); 2841 2842 2843 } else { 2844 2845 gsap.set(wrapper, { 2846 x: -wrapperWidth - parseFloat(gap) 2847 }) 2848 2849 tl.fromTo(wrapper, { 2850 x: -wrapperWidth - parseFloat(gap) 2851 }, { 2852 x: 0, 2853 duration: speed, 2854 ease: 'none', 2855 }) 2856 } 2857 2858 } 2859 2860 if (stopHover) { 2861 wrapper.addEventListener('mouseenter', () => { 2862 tl.pause(); 2863 }) 2864 2865 wrapper.addEventListener('mouseleave', () => { 2866 tl.play(); 2867 }) 2868 } 2869 2870 2871 } 2872 2873 } 2874 2875 2876 }); 2877 2878 elementorFrontend.hooks.addAction('frontend/element_ready/peaccordion.default', function ($scope, $) { 2879 2880 var jsScopeArray = $scope.toArray(); 2881 for (var i = 0; i < jsScopeArray.length; i++) { 2882 var scope = jsScopeArray[i], 2883 accordion = scope.querySelector('.pe--accordion'), 2884 wrapper = accordion.querySelector('.pe--accordion--wrapper'), 2885 items = wrapper.querySelectorAll('.pe-accordion-item'); 2886 2887 items.forEach(item => { 2888 2889 let title = item.querySelector('.pe-accordion-item-title'), 2890 content = item.querySelector('.pe-accordion-item-content'); 2891 2892 title.addEventListener('click', () => { 2893 2894 if (item.classList.contains('accordion--active')) { 2895 2896 var contentState = Flip.getState(content); 2897 item.classList.remove('accordion--active'); 2898 2899 Flip.from(contentState, { 2900 duration: .75, 2901 ease: 'expo.inOut', 2902 absolute: false, 2903 absoluteOnLeave: false, 2904 }) 2905 2906 2907 } else { 2908 2909 2910 if (!accordion.classList.contains('open--multiple')) { 2911 2912 var currentActive = accordion.querySelector('.accordion--active'); 2913 2914 if (currentActive) { 2915 2916 let currentContentState = Flip.getState(currentActive.querySelector('.pe-accordion-item-content')); 2917 2918 currentActive.classList.remove('accordion--active'); 2919 2920 Flip.from(currentContentState, { 2921 duration: .75, 2922 ease: 'expo.inOut', 2923 absolute: false, 2924 absoluteOnLeave: false, 2925 }) 2926 2927 } 2928 } 2929 //Open 2930 2931 var contentState = Flip.getState(content); 2932 item.classList.add('accordion--active'); 2933 2934 Flip.from(contentState, { 2935 duration: .75, 2936 ease: 'expo.inOut', 2937 absolute: false, 2938 absoluteOnLeave: false, 2939 }) 2940 2941 } 2942 2943 2944 }) 2945 2946 }) 2947 2948 } 2949 2950 }); 2951 2952 elementorFrontend.hooks.addAction('frontend/element_ready/pesingleimage.default', function ($scope, $) { 2953 var jsScopeArray = $scope.toArray(); 2954 for (var i = 0; i < jsScopeArray.length; i++) { 2955 var scope = jsScopeArray[i], 2956 image = scope.querySelector('.single-image'); 2957 2958 2959 imagesLoaded(image, function (instance) { 2960 2961 if (image.classList.contains('zoomed--image')) { 2962 2963 var before = image.querySelector('.zoomed--before'), 2964 center = image.querySelector('.zoomed--center'), 2965 after = image.querySelector('.zoomed--after'), 2966 centerWidth = center.getBoundingClientRect().width, 2967 centerHeight = center.getBoundingClientRect().height; 2968 2969 2970 let hold = document.createElement('div'); 2971 2972 image.insertBefore(hold, after); 2973 2974 center.classList.add('zoomed'); 2975 2976 let tl = gsap.timeline({ 2977 scrollTrigger: { 2978 trigger: scope, 2979 start: 'top bottom', 2980 end: 'center center', 2981 scrub: true 2982 } 2983 }); 2984 2985 tl.fromTo(image, { 2986 xPercent: -100, 2987 2988 }, { 2989 xPercent: 0, 2990 duration: 20, 2991 ease: 'none' 2992 }, 0) 2993 2994 gsap.to(center, { 2995 width: '100%', 2996 height: '100%', 2997 scrollTrigger: { 2998 trigger: scope, 2999 scrub: true, 3000 pin: scope, 3001 start: 'center center', 3002 pinSpacing: 'margin' 3003 3004 } 3005 }) 3006 3007 } 3008 3009 if (image.classList.contains('parallax--image')) { 3010 3011 let img = image.querySelectorAll('img'); 3012 3013 for (var i = 0; i < img.length; i++) { 3014 3015 gsap.set(img[i], { 3016 scale: 1.2 3017 }) 3018 3019 gsap.fromTo(img[i], { 3020 yPercent: -10 3021 }, { 3022 yPercent: 10, 3023 ease: 'none', 3024 scrollTrigger: { 3025 trigger: image, 3026 scrub: true, 3027 start: 'top bottom', 3028 end: 'bottom top' 3029 } 3030 }) 3031 3032 3033 } 3034 3035 } 3036 3037 }); 3038 3039 } 3040 3041 3042 }); 3043 3044 elementorFrontend.hooks.addAction('frontend/element_ready/pemarquee.default', function ($scope, $) { 3045 3046 var jsScopeArray = $scope.toArray(); 3047 for (var i = 0; i < jsScopeArray.length; i++) { 3048 var scope = jsScopeArray[i], 3049 marquee = document.querySelectorAll('.pe-marquee'); 3050 3051 marquee.forEach(function (marqueeElement) { 3052 3053 var text = marqueeElement.children, 3054 dataDuration = marqueeElement.getAttribute('data-duration'), 3055 separator = marqueeElement.getAttribute('data-seperator'); 3056 var wrapperElement = document.createElement("div"); 3057 wrapperElement.className = "marquee-wrap"; 3058 3059 while (marqueeElement.firstChild) { 3060 wrapperElement.appendChild(marqueeElement.firstChild); 3061 } 3062 marqueeElement.appendChild(wrapperElement); 3063 3064 var infItem = marqueeElement.querySelector('.marquee-wrap'), 3065 infWidth = infItem.offsetWidth; 3066 3067 if (infWidth > 0) { 3068 3069 var infLength = window.innerWidth / infWidth, 3070 gap = infItem.getBoundingClientRect().left; 3071 if (marqueeElement.classList.contains('icon_font')) { 3072 var separators = infItem.querySelectorAll('.seperator');
3073 separators.forEach(function (separator) { 3074 separator.style.fontSize = window.getComputedStyle(separator.parentNode).getPropertyValue('font-size'); 3075 }); 3076 } 3077 3078 function infinityOnResize() { 3079 for (var i = 2; i < infLength + 2; i++) { 3080 var clonedItem = infItem.cloneNode(true); 3081 marqueeElement.appendChild(clonedItem); 3082 } 3083 var infItemLength = marqueeElement.querySelectorAll('.marquee-wrap').length; 3084 infWidth = parseInt(infWidth); 3085 infItem.style.width = infWidth + 'px'; 3086 marqueeElement.style.width = (infItemLength * infItem.offsetWidth) + 'px'; 3087 marqueeElement.style.display = 'flex'; 3088 3089 var tl = gsap.timeline({ 3090 repeat: -1 3091 }); 3092 var tl2 = gsap.timeline({ 3093 repeat: -1 3094 }); 3095 3096 if (marqueeElement.classList.contains('left-to-right')) { 3097 tl.fromTo(marqueeElement, { 3098 x: -1 * (infWidth + gap) 3099 }, { 3100 x: -1 * gap, 3101 ease: 'none', 3102 duration: infWidth / 1000 * dataDuration 3103 }); 3104 } else { 3105 tl.fromTo(marqueeElement, { 3106 x: -1 * gap 3107 }, { 3108 x: -1 * (infWidth + gap), 3109 ease: 'none', 3110 duration: infWidth / 1000 * dataDuration 3111 }); 3112 } 3113 3114 if (marqueeElement.classList.contains('rotating_seperator')) { 3115 var sepDuration = marqueeElement.getAttribute('data-sepduration'); 3116 var rotateValue = marqueeElement.classList.contains('counter-clockwise') ? -360 : 360; 3117 tl2.fromTo(marqueeElement.querySelectorAll('.seperator'), { 3118 rotate: 0 3119 }, { 3120 rotate: rotateValue, 3121 duration: sepDuration, 3122 ease: 'none' 3123 }); 3124 } 3125 } 3126 3127 infinityOnResize(); 3128 } 3129 }); 3130 } 3131 3132 }); 3133 elementorFrontend.hooks.addAction('frontend/element_ready/peblogposts.default', function ($scope, $) { 3134 3135 var jsScopeArray = $scope.toArray(); 3136 for (var i = 0; i < jsScopeArray.length; i++) { 3137 var scope = jsScopeArray[i], 3138 grid = scope.querySelector('.pe--posts--grid'), 3139 wrapper = scope.querySelector('.grid--posts--wrapper'), 3140 posts = wrapper.querySelectorAll('.grid--post--item'), 3141 filters = grid.querySelector('.grid--filters'); 3142 3143 if (filters) { 3144 3145 let filter = filters.querySelectorAll('.post-filter'), 3146 ul = filters.querySelector('.filters-list'); 3147 3148 let filterAll = ul.querySelector('.filter--all'); 3149 3150 gsap.set(ul, { 3151 '--activeLeft': filterAll.offsetLeft - 10 + 'px', 3152 '--activeWidth': filterAll.offsetWidth + filterAll.offsetLeft - 35 + 'px', 3153 }) 3154 3155 filter.forEach(filter => { 3156 3157 3158 3159 filter.addEventListener('click', () => { 3160 3161 filters.querySelector('.active').classList.remove('active'); 3162 filter.classList.add('active'); 3163 3164 gsap.to(ul, {
3165 '--activeLeft': filter.offsetLeft - 10 + 'px', 3166 '--activeWidth': filter.offsetWidth + filter.offsetLeft - 35 + 'px', 3167 duration: .5, 3168 ease: 'expo.out' 3169 }) 3170 3171 let cat = filter.dataset.category, 3172 findPosts = 'cat_' + cat; 3173 3174 let state = Flip.getState(posts); 3175 3176 posts.forEach(post => { 3177 3178 if (cat !== 'all') { 3179 3180 post.classList.contains(findPosts) ? post.style.display = 'block' : post.style.display = 'none'; 3181 3182 } else { 3183 3184 post.style.display = 'block' 3185 } 3186 3187 }) 3188 3189 Flip.from(state, { 3190 duration: 1, 3191 absolute: false, 3192 absoluteOnLeave: false, 3193 ease: "expo.inOut", 3194 onEnter: elements => gsap.fromTo(elements, { 3195 opacity: 0, 3196 xPercent: 100 3197 }, { 3198 opacity: 1, 3199 xPercent: 0 3200 }), 3201 onLeave: elements => gsap.fromTo(elements, { 3202 opacity: 1, 3203 xPercent: 0 3204 }, { 3205 opacity: 0, 3206 xPercent: -100, 3207 stagger: 0.1 3208 }), 3209 }) 3210 3211 }) 3212 3213 }) 3214 3215 } 3216 3217 if (grid.querySelector('.pe-load-more')) { 3218 3219 let button = grid.querySelector('.pe-load-more'), 3220 currentWrapper = wrapper, 3221 count = grid.dataset.total, 3222 link = button.querySelector('a'); 3223 3224 link.addEventListener('click', (e) => { 3225 3226 let apiUrl = link.getAttribute("href"); 3227 e.preventDefault(); 3228 3229 button.classList.add('plm--loading'); 3230 document.documentElement.classList.add('loading'); 3231 3232 var xhr = new XMLHttpRequest(); 3233 xhr.open('GET', apiUrl); 3234 xhr.onreadystatechange = function () { 3235 3236 if (xhr.readyState === XMLHttpRequest.DONE) { 3237 3238 if (xhr.status === 200) { 3239 3240 var response = xhr.responseText; 3241 3242 setTimeout(function () { 3243 var parser = new DOMParser(), 3244 htmlDoc = parser.parseFromString(response, 'text/html'), 3245 newPosts = htmlDoc.querySelectorAll('.pe--posts--grid .grid--post--item'), 3246 newUrl = htmlDoc.querySelector('.pe-load-more a').getAttribute('href'); 3247 3248 link.setAttribute("href", newUrl); 3249 3250 if (newPosts.length > 0) { 3251 3252 let tl = gsap.timeline({ 3253 onComplete: () => { 3254 ScrollTrigger.refresh() 3255 3256 } 3257 }); 3258 3259 newPosts.forEach(function (post, i) { 3260 3261 let clone = post.cloneNode(true) 3262 currentWrapper.appendChild(clone); 3263 3264 tl.fromTo(clone, { 3265 opacity: 0, 3266 yPercent: 100 3267 }, { 3268 opacity: 1, 3269 yPercent: 0, 3270 duration: .75, 3271 ease: 'expo.out' 3272 }, i * 0.15) 3273 3274 }); 3275 3276 3277 3278 3279 if (grid.querySelectorAll('.grid--post--item').length >= count) { 3280 button.classList.add('plm--disabled'); 3281 } 3282 3283 button.classList.remove('plm--loading'); 3284 document.documentElement.classList.remove('loading'); 3285 } 3286 3287 }, 200); 3288 } else { 3289 console.error('Request failed. Status: ' + xhr.status); 3290 } 3291 } 3292 }; 3293 xhr.send(); 3294 3295 }) 3296 3297 } 3298 3299 } 3300 3301 }); 3302 3303 elementorFrontend.hooks.addAction('frontend/element_ready/pepostmedia.default', function ($scope, $) { 3304 var jsScopeArray = $scope.toArray(); 3305 for (var i = 0; i < jsScopeArray.length; i++) { 3306 var scope = jsScopeArray[i], 3307 image = scope.querySelector('.single-image'); 3308 3309 if (image.classList.contains('parallax--image')) { 3310 3311 let img = image.querySelectorAll('img'); 3312 3313 for (var i = 0; i < img.length; i++) { 3314 3315 gsap.fromTo(img[i], { 3316 yPercent: 0 3317 }, { 3318 yPercent: -10, 3319 ease: 'none', 3320 scrollTrigger: { 3321 trigger: image, 3322 scrub: true, 3323 start: 0, 3324 end: 'bottom top' 3325 } 3326 }) 3327 3328 3329 } 3330 3331 } 3332 } 3333 3334 }); 3335 3336 elementorFrontend.hooks.addAction('frontend/element_ready/projectmedia.default', function ($scope, $) { 3337 var jsScopeArray = $scope.toArray(); 3338 for (var i = 0; i < jsScopeArray.length; i++) { 3339 var scope = jsScopeArray[i], 3340 gallery = scope.querySelector('.project--image--gallery'); 3341 3342 if (gallery) { 3343 3344 let wrapper = gallery.querySelector('.project--image--gallery--wrapper'), 3345 images = wrapper.querySelectorAll('.project--gallery--image'), 3346 gap = parseInt(window.getComputedStyle(wrapper).getPropertyValue('gap')), 3347 val = wrapper.getBoundingClientRect().left + (wrapper.offsetWidth - document.body.clientWidth) + gap, 3348 id = wrapper.dataset.id ? wrapper.dataset.id : scope.dataset.id, 3349 trigger = gallery.dataset.trigger ? gallery.dataset.trigger : scope, 3350 speed = wrapper.dataset.speed, 3351 integrated = gallery.dataset.integrated; 3352 3353 wrapper.classList.add(id); 3354 wrapper.setAttribute('data-total', images.length);
3355 images.forEach((image, i) => { 3356 3357 image.setAttribute('data-cr', i + 1); 3358 }) 3359 3360 if (scope.classList.contains('cr--scroll')) { 3361 3362 wrapper.classList.add('cr--scroll'); 3363 3364 let crScroll = gsap.to(wrapper, { 3365 id: id, 3366 x: -val, 3367 ease: "sine.inOut", 3368 scrollTrigger: { 3369 trigger: trigger, 3370 pin: trigger, 3371 pinSpacing: 'margin', 3372 scrub: true, 3373 start: 'top top', 3374 end: 'bottom+=3000 top', 3375 onEnter: () => isPinnng(trigger, true), 3376 onEnterBack: () => isPinnng(trigger, true), 3377 onLeave: () => isPinnng(trigger, false), 3378 onLeaveBack: () => isPinnng(trigger, false), 3379 onUpdate: self => { 3380 3381 if (integrated && !mobileQuery.matches) { 3382 3383 gsap.to(integrated, { 3384 opacity: 1 - (self.progress * 5) 3385 }) 3386 } 3387 } 3388 } 3389 }) 3390 3391 matchMedia.add({ 3392 isPhone: "(max-width: 550px)" 3393 }, (context) => { 3394 3395 crScroll.scrollTrigger.kill(true); 3396 3397 Draggable.create(wrapper, { 3398 type: 'x', 3399 dragResistance: 0.35, 3400 inertia: true, 3401 bounds: { 3402 minX: 0, 3403 maxX: -val 3404 }, 3405 }) 3406 3407 }); 3408 3409 } 3410 3411 if (scope.classList.contains('cr--drag')) { 3412 3413 wrapper.classList.add('cr--drag'); 3414 3415 let drag = Draggable.create(wrapper, { 3416 id: id, 3417 type: 'x', 3418 dragResistance: 0.35, 3419 inertia: true, 3420 bounds: { 3421 minX: 0, 3422 maxX: -val 3423 }, 3424 onThrowUpdate: () => { 3425 let prog = drag[0].x / drag[0].minX; 3426 3427 if (integrated) { 3428 3429 gsap.to(integrated, { 3430 opacity: 1 - (prog * 5) 3431 }) 3432 } 3433 3434 }, 3435 onMove: () => { 3436 3437 let prog = drag[0].x / drag[0].minX; 3438 3439 if (integrated) { 3440 3441 gsap.to(integrated, { 3442 opacity: 1 - (prog * 5) 3443 }) 3444 } 3445 3446 }, 3447 lockAxis: true, 3448 dragResistance: 0.5, 3449 inertia: true, 3450 }); 3451 3452 } 3453 3454 3455 } else { 3456 3457 let image = scope.querySelector('.project-featured-image'); 3458 3459 if (image && image.classList.contains('parallax--image')) { 3460 3461 let img = image.querySelectorAll('img'); 3462 3463 3464 for (var i = 0; i < img.length; i++) { 3465 3466 gsap.fromTo(img[i], { 3467 yPercent: 0 3468 }, { 3469 yPercent: 20, 3470 ease: 'none', 3471 scrollTrigger: { 3472 trigger: image, 3473 scrub: 1.2, 3474 start: 'top top', 3475 end: 'bottom top' 3476 } 3477 }) 3478 3479 3480 } 3481 3482 } 3483 } 3484 3485 } 3486 3487 }); 3488 3489 elementorFrontend.hooks.addAction('frontend/element_ready/peportfolio.default', function ($scope, $) { 3490 3491 var jsScopeArray = $scope.toArray(); 3492 for (var i = 0; i < jsScopeArray.length; i++) { 3493 var scope = jsScopeArray[i], 3494 filters = scope.querySelector('.portfolio--filters'), 3495 id = scope.dataset.id, 3496 wrapper = scope.querySelector('.portfolio--projects--wrapper'), 3497 url = scope.querySelector('input[name="url"]').value, 3498 catdata = scope.querySelector('input[name="cat"]'), 3499 portfolio = scope.querySelector('.pe--portfolio'), 3500 pagination = scope.querySelector('.portfolio--pagination'), 3501 switcher = scope.querySelector('.ps--switch'), 3502 projects = scope.querySelectorAll('.portfolio--project'); 3503 3504 if (switcher) { 3505 3506 let switchGrid = switcher.querySelector('.ps--grid'), 3507 switchList = switcher.querySelector('.ps--list'), 3508 follower = switcher.querySelector('.ps--follower'), 3509 sgWidth = switchGrid.offsetWidth, 3510 slWidth = switchList.offsetWidth; 3511 3512 if (portfolio.classList.contains('portfolio--list')) { 3513 3514 switchGrid.classList.remove('active') 3515 switchList.classList.add('active') 3516 3517 switcher.classList.contains('switcher--switcher') ? follower.style.width = slWidth + 'px' : ''; 3518 3519 } else { 3520 3521 switchGrid.classList.add('active') 3522 switchList.classList.remove('active') 3523 3524 switcher.classList.contains('switcher--switcher') ? follower.style.width = sgWidth + 'px' : ''; 3525 3526 } 3527 3528 switcher.addEventListener('click', () => { 3529 3530 let tl = gsap.timeline(); 3531 3532 tl.to(wrapper, { 3533 opacity: 0, 3534 duration: .5, 3535 onComplete: () => { 3536 3537 if (portfolio.classList.contains('portfolio--list')) { 3538 3539 portfolio.classList.remove('portfolio--list') 3540 portfolio.classList.add('portfolio--grid'); 3541 3542 switchGrid.classList.add('active') 3543 switchList.classList.remove('active') 3544 3545 3546 } else { 3547 portfolio.classList.remove('portfolio--grid') 3548 portfolio.classList.add('portfolio--list') 3549 3550 farahPortfolioList(); 3551 3552 switchGrid.classList.remove('active') 3553 switchList.classList.add('active') 3554 } 3555 } 3556 }) 3557 3558 tl.to(wrapper, { 3559 opacity: 1, 3560 duration: .5 3561 }) 3562 3563 3564 3565 3566 }) 3567 3568 } 3569 3570 if (filters) { 3571 3572 let trigger = filters.querySelector('.filter--active'), 3573 cats = filters.querySelectorAll('.filter--cat'); 3574 3575 trigger.addEventListener('click', () => { 3576 3577 filters.classList.toggle('filt--active'); 3578 3579 3580 }) 3581
3582 cats.forEach(cat => { 3583 3584 cat.addEventListener('click', (e) => { 3585 3586 scope.querySelector('.filter--cat.active').classList.remove('active'); 3587 cat.classList.add('active'); 3588 3589 var apiUrl = cat.dataset.id ? url + '?cat=' + cat.dataset.id : url; 3590 3591 e.preventDefault(); 3592 3593 document.documentElement.classList.add('loading'); 3594 3595 var xhr = new XMLHttpRequest(); 3596 xhr.open('GET', apiUrl); 3597 xhr.onreadystatechange = function () { 3598 3599 if (xhr.readyState === XMLHttpRequest.DONE) { 3600 3601 if (xhr.status === 200) { 3602 3603 var response = xhr.responseText; 3604 3605 setTimeout(function () { 3606 3607 let items = wrapper.querySelectorAll('.portfolio--project'), 3608 state = Flip.getState(items); 3609 3610 items.forEach(item => item.classList.add('hidden')) 3611 3612 Flip.from(state, { 3613 duration: 1, 3614 ease: "power3.inOut", 3615 fade: true, 3616 absolute: false, 3617 absoluteOnLeave: false, 3618 onComplete: () => { 3619 items.forEach(item => item.remove()) 3620 3621 }, 3622 onLeave: elements => gsap.fromTo(elements, { 3623 opacity: 1, 3624 y: 0 3625 }, { 3626 opacity: 0, 3627 y: -50, 3628 }), 3629 }); 3630 3631 var parser = new DOMParser(), 3632 htmlDoc = parser.parseFromString(response, 'text/html'), 3633 newElement = htmlDoc.querySelector('.elementor-element-' + id), 3634 newPosts = newElement.querySelectorAll('.portfolio--project'); 3635 3636 3637 if (newPosts.length > 0) { 3638 portfolio.setAttribute('data-max-pages', newElement.querySelector('.pe--portfolio').dataset.maxPages) 3639 3640 3641 let tl = gsap.timeline({ 3642 onComplete: () => { 3643 ScrollTrigger.refresh() 3644 3645 } 3646 }); 3647 3648 newPosts.forEach(function (post, i) { 3649 3650 let clone = post.cloneNode(true) 3651 wrapper.appendChild(clone); 3652 3653 tl.fromTo(clone, { 3654 opacity: 0, 3655 yPercent: 100 3656 }, { 3657 opacity: 1, 3658 yPercent: 0, 3659 duration: .75, 3660 ease: 'expo.out' 3661 }, i * 0.15) 3662 3663 }); 3664 3665 3666 cat.dataset.id ? trigger.classList.add('filtered') : trigger.classList.remove('filtered'); 3667 cat.dataset.id ? portfolio.classList.add('filtered') : portfolio.classList.remove('filtered'); 3668 filters.classList.remove('filt--active'); 3669 trigger.innerHTML = cat.innerHTML; 3670 trigger.setAttribute('data-length', cat.dataset.length) 3671 document.documentElement.classList.remove('loading'); 3672 catdata.value = cat.dataset.id; 3673 } 3674 3675 }, 200); 3676 } else { 3677 console.error('Request failed. Status: ' + xhr.status); 3678 } 3679 } 3680 }; 3681 xhr.send(); 3682 3683 }) 3684 3685 3686 }) 3687 3688 } 3689 3690 if (pagination) { 3691 3692 let loadMore = pagination.querySelector('a'), 3693 clicks = 0; 3694 3695 if (loadMore) { 3696
3697 loadMore.addEventListener('click', (e) => { 3698 3699 pagination.classList.add('loading'); 3700 3701 clicks++ 3702 var apiUrl = catdata.value ? url + '?offset=' + clicks + '&cat=' + catdata.value : url + '?offset=' + clicks; 3703 3704 e.preventDefault(); 3705 3706 3707 document.documentElement.classList.add('loading'); 3708 pagination.classList.add('loading'); 3709 3710 var xhr = new XMLHttpRequest(); 3711 xhr.open('GET', apiUrl); 3712 xhr.onreadystatechange = function () { 3713 3714 if (xhr.readyState === XMLHttpRequest.DONE) { 3715 3716 if (xhr.status === 200) { 3717 3718 var response = xhr.responseText; 3719 3720 setTimeout(function () { 3721 3722 var parser = new DOMParser(), 3723 htmlDoc = parser.parseFromString(response, 'text/html'), 3724 newElement = htmlDoc.querySelector('.elementor-element-' + id), 3725 newPosts = newElement.querySelectorAll('.portfolio--project'); 3726 3727 if (newPosts.length > 0) { 3728 3729 let tl = gsap.timeline({ 3730 onComplete: () => { 3731 ScrollTrigger.refresh() 3732 3733 } 3734 }); 3735 3736 newPosts.forEach(function (post, i) { 3737 3738 let clone = post.cloneNode(true) 3739 wrapper.appendChild(clone); 3740 3741 tl.fromTo(clone, { 3742 opacity: 0, 3743 yPercent: 100 3744 }, { 3745 opacity: 1, 3746 yPercent: 0, 3747 duration: .75, 3748 ease: 'expo.out', 3749 onComplete: () => { 3750 pagination.classList.remove('loading'); 3751 3752 if (clone.querySelector('.pe-video')) { 3753 3754 let videos = clone.querySelectorAll('.pe-video') 3755 3756 for (var i = 0; i < videos.length; i++) { 3757 new peVideoPlayer(videos[i]); 3758 } 3759 3760 } 3761 3762 } 3763 }, i * 0.15) 3764 3765 }); 3766 3767 if (portfolio.dataset.maxPages == clicks + 1) { 3768 3769 pagination.classList.add('hidden'); 3770 } 3771 3772 document.documentElement.classList.remove('loading'); 3773 3774 } 3775 3776 }, 200); 3777 } else { 3778 console.error('Request failed. Status: ' + xhr.status); 3779 } 3780 } 3781 }; 3782 xhr.send(); 3783 3784 }) 3785 3786 } 3787 3788 } 3789 3790 function farahPortfolioList() { 3791 3792 let portfolio = $scope.find('.pe--portfolio'), 3793 titlesWrap = $scope.find('.portfolio--projects--wrapper'), 3794 imagesWrap = $scope.find('.portfolio--list--images--wrapper'); 3795 3796 3797 titlesWrap.hover( 3798 () => { 3799 imagesWrap.addClass('active'); 3800 titlesWrap.addClass('active'); 3801 3802 }, 3803 () => { 3804 imagesWrap.removeClass('active') 3805 titlesWrap.removeClass('active') 3806 } 3807 ); 3808 3809 gsap.set(imagesWrap, { 3810 xPercent: -75, 3811 yPercent: -50 3812 }); 3813 3814 titlesWrap.on('mousemove', function (e) { 3815 3816 let xTo = gsap.quickTo(imagesWrap, "left", { 3817 duration: 0.6, 3818 ease: "power3" 3819 }), 3820 yTo = gsap.quickTo(imagesWrap, "top", { 3821 duration: 0.6, 3822 ease: "power3" 3823 }); 3824 3825 3826 function icko(e) { 3827 xTo(e.pageX); 3828 yTo(e.pageY - portfolio.offset().top); 3829 } 3830 3831 icko(e) 3832 3833 }); 3834 3835 matchMedia.add({ 3836 isMobile: "(max-width: 550px)" 3837 3838 }, (context) => { 3839 let { 3840 isMobile 3841 } = context.conditions; 3842 3843 titlesWrap.off('mousemove') 3844 3845 return () => { 3846 3847 titlesWrap.on('mousemove') 3848 3849 } 3850 }); 3851 3852 3853 3854 let projects = titlesWrap.find('.portfolio--project'), 3855 count = 0; 3856 3857 3858 projects.each(function () { 3859
3860 let $this = $(this); 3861 3862 $this.on('mouseenter', function () { 3863 3864 let image = $('.image_' + $this.data('id')); 3865 $this.addClass('active') 3866 3867 gsap.set(image, { 3868 zIndex: 1 3869 }) 3870 3871 image.addClass('active') 3872 image.addClass('trans-media') 3873 3874 let tl = gsap.timeline(); 3875 3876 tl.fromTo(image, { 3877 3878 y: '100%' 3879 }, { 3880 3881 y: '0%', 3882 duration: 1.5, 3883 ease: 'power3.inOut' 3884 }, 0) 3885 3886 tl.fromTo(image.children('div'), { 3887 3888 scale: 1.3, 3889 y: '-100%' 3890 }, { 3891 3892 y: '0%', 3893 scale: 1, 3894 duration: 1.5, 3895 ease: 'power3.inOut' 3896 }, 0) 3897 3898 }) 3899 3900 $this.on('mouseleave', function () { 3901 3902 count++ 3903 3904 $this.removeClass('active') 3905 3906 let image = $('.image_' + $this.data('id')); 3907 3908 image.removeClass('active') 3909 image.removeClass('trans-media') 3910 3911 gsap.set(image, { 3912 zIndex: 0 - count 3913 }) 3914 3915 let tl = gsap.timeline(); 3916 3917 tl.fromTo(image, { 3918 3919 y: '0%' 3920 }, { 3921 3922 y: '-100%', 3923 duration: 1.5, 3924 ease: 'power3.inOut' 3925 }, 0) 3926 3927 tl.fromTo(image.children('div'), { 3928 3929 y: '0%', 3930 scale: 1 3931 }, { 3932 3933 y: '100%', 3934 scale: 1.3, 3935 duration: 1.5, 3936 ease: 'power3.inOut' 3937 }, 0) 3938 3939 }) 3940 3941 $this.find('a').on('click', function () { 3942 3943 $this.off('mouseleave') 3944 3945 3946 }) 3947 3948 3949 }) 3950 3951 3952 } 3953 3954 if (portfolio.classList.contains('portfolio--list')) { 3955 3956 farahPortfolioList(); 3957 3958 } 3959 3960 3961 3962 3963 } 3964 3965 }); 3966 3967 // Showcases 3968 elementorFrontend.hooks.addAction('frontend/element_ready/pefullscreenslideshow.default', function ($scope, $) { 3969 var jsScopeArray = $scope.toArray(); 3970 3971 for (var i = 0; i < jsScopeArray.length; i++) { 3972 var scope = jsScopeArray[i], 3973 fullscreenSlideshow = document.querySelectorAll('.fullscreen--slideshow'); 3974 3975 fullscreenSlideshow.forEach(function ($this) { 3976 let interleaveOffset = 0.5, 3977 swiper = new Swiper('.fullscreen--slideshow', { 3978 slidesPerView: 1, 3979 speed: 1500, 3980 autoplay: ($this.classList.contains('autoplay__active')) ? true : false, 3981 delay: parseInt($this.getAttribute('data-delay')), 3982 loop: ($this.classList.contains('loop__active')) ? true : false, 3983 direction: 'horizontal', 3984 pagination: { 3985 el: ".sc--fraction", 3986 type: "fraction", 3987 }, 3988 parallax: true, 3989 navigation: { 3990 nextEl: '.sc--next', 3991 prevEl: '.sc--prev', 3992 }, 3993 mousewheel: { 3994 invert: false 3995 }, 3996 watchSlideProgress: true, 3997 on: { 3998 progress: function () { 3999 let swiper = this; 4000 for (let i = 0; i < swiper.slides.length; i++) { 4001 let slideProgress = swiper.slides[i].progress, 4002 innerOffset = swiper.width * interleaveOffset, 4003 innerTranslate = slideProgress * innerOffset; 4004 4005 swiper.slides[i].querySelector(".slide-bgimg").style.transform =
4006 "translateX(" + innerTranslate + "px)"; 4007 if (!mobileQuery.matches) { 4008 swiper.slides[i].querySelector(".project--top").style.transform = 4009 "translateX(" + innerTranslate / 2 + "px)"; 4010 swiper.slides[i].querySelector(".project--excerpt").style.transform = 4011 "translateX(" + innerTranslate / 2 + "px)"; 4012 } 4013 4014 4015 } 4016 }, 4017 setTransition: function (speed) { 4018 let swiper = this; 4019 for (let i = 0; i < swiper.slides.length; i++) { 4020 swiper.slides[i].style.transition = speed + "ms"; 4021 swiper.slides[i].querySelector(".slide-bgimg").style.transition = 1500 + "ms"; 4022 swiper.slides[i].querySelector(".project--top").style.transition = 1500 + "ms"; 4023 swiper.slides[i].querySelector(".project--excerpt").style.transition = 1500 + "ms"; 4024 } 4025 }, 4026 slideChangeTransitionEnd: () => { 4027 4028 for (let i = 0; i < swiper.slides.length; i++) { 4029 4030 let bgs = swiper.slides[i].querySelector('.slide-bgimg'); 4031 4032 swiper.slides[i].querySelector(".slide-bgimg").style.transform = 4033 "translateX(0px)"; 4034 4035 if (!mobileQuery.matches) { 4036 swiper.slides[i].querySelector(".project--top").style.transform = 4037 "translateX(0px)"; 4038 swiper.slides[i].querySelector(".project--excerpt").style.transform = 4039 "translateX(0px)"; 4040 } 4041 } 4042 } 4043 } 4044 }); 4045 4046 if ($this.classList.contains('autoplay__active')) { 4047 $this.querySelectorAll('.project--button').forEach(function (button) { 4048 button.addEventListener('mouseenter', function () { 4049 swiper.autoplay.stop() 4050 }) 4051 button.addEventListener('mouseleave', function () { 4052 swiper.autoplay.start() 4053 }) 4054 }) 4055 } 4056 }) 4057 4058 } 4059 }); 4060 4061 4062 elementorFrontend.hooks.addAction('frontend/element_ready/peinfinitecarousel.default', function ($scope, $) { 4063 var jsScopeArray = $scope.toArray(); 4064 for (var i = 0; i < jsScopeArray.length; i++) { 4065 var scope = jsScopeArray[i]; 4066 4067 let infiniteCarousel = document.querySelectorAll('.infinite--carousel'); 4068 infiniteCarousel.forEach(function ($this) { 4069 let wrap = $this.querySelector('.infinite--carousel--wrapper'), 4070 inner = $this.querySelector('.infinite--carousel--inner'), 4071 project = $this.querySelectorAll('.showcase--project'), 4072 width = project[1].offsetWidth, 4073 activeWidth = project[0].offsetWidth, 4074 plength = project.length, 4075 totalWidth = inner.offsetWidth, 4076 totalHeight = inner.offsetHeight, 4077 length = project.length; 4078 4079 for (let i = 0; i <= 1; i++) { 4080 project.forEach(function (item, i) { 4081 let clone = item.cloneNode(true) 4082 inner.appendChild(clone) 4083 }) 4084 } 4085 project = $this.querySelectorAll('.showcase--project'); 4086 4087 4088 matchMedia.add({ 4089 isDesktop: "(min-width: 571px)" 4090 4091 }, (context) => { 4092 4093 let { 4094 isDesktop 4095 } = context.conditions; 4096 let wheeler = Hamster($this), 4097 prog1 = activeWidth / 2; 4098 4099 gsap.set(wrap, { 4100 x: (-1 * totalWidth) + (document.body.offsetWidth / 2) 4101 }) 4102 gsap.set(inner, { 4103 x: -1 * prog1 4104 }) 4105 4106 wheeler.wheel(function (event, delta, deltaX, deltaY) { 4107 4108 4109 4110 matchMedia.add({ 4111 isDesktop: "(min-width: 551px)" 4112 4113 }, (context) => { 4114 4115 if (window.navigator.platform === 'MacIntel') { 4116 prog1 += event.deltaY * 2; 4117 } else { 4118 prog1 += event.deltaY * 10; 4119 } 4120 4121 4122 4123 }); 4124 4125 4126 matchMedia.add({ 4127 isPhone: "(max-width: 550px)" 4128 }, (context) => { 4129 prog1 += event.deltaY * 2; 4130 }); 4131 4132 4133 4134 if (prog1 > totalWidth) { 4135 prog1 = prog1 - totalWidth 4136 } else if (prog1 < 0) { 4137 prog1 = prog1 + totalWidth 4138 } 4139 4140 gsap.set(inner, { 4141 x: (-1 * prog1) 4142 }) 4143 4144 let centerIndex = Math.floor(prog1 / (totalWidth / plength)); 4145 4146 if (centerIndex >= length) { 4147 centerIndex = centerIndex - length 4148 } else if (centerIndex < 0) { 4149 centerIndex = centerIndex + length 4150 } 4151 4152 project.forEach((item, index) => { 4153 4154 index = index % length 4155 4156 // if (index === centerIndex) { 4157 // item.classList.add('showcase--project--active') 4158 // gsap.to(item, { 4159 // minWidth: activeWidth, 4160 // }) 4161 // } else { 4162 // item.classList.remove('showcase--project--active') 4163 // gsap.to(item, { 4164 // minWidth: width, 4165 // }) 4166 // } 4167 }); 4168 }); 4169 }); 4170 4171 matchMedia.add({ 4172 isMobile: "(max-width: 570px)" 4173 }, (context) => { 4174 let activeHeight = project[0].offsetHeight, 4175 normalHeight = project[1].offsetHeight 4176 gsap.set(wrap, { 4177 x: (-1 * totalWidth) + (document.body.offsetHeight / 2) 4178 }) 4179 let drag = Draggable.create(inner, { 4180 type: 'x', 4181 inertia: true, 4182 onThrowUpdate: function () { 4183 if (this.x < -1 * totalWidth) { 4184 gsap.set(inner, { 4185 x: this.x + totalWidth 4186 }) 4187 } else if (this.y > 0) { 4188 gsap.set(inner, { 4189 x: this.x - totalWidth 4190 }) 4191 } 4192 let activeIndex = parseInt(this.y / (totalWidth / plength)) 4193 4194 if (activeIndex < 0) { 4195 activeIndex = activeIndex * -1 4196 } 4197 4198 activeIndex = activeIndex % plength; 4199 4200 4201 4202 } 4203 }) 4204 }) 4205 }) 4206 } 4207 }); 4208 4209 elementorFrontend.hooks.addAction('frontend/element_ready/peshowcaselist.default', function ($scope, $) { 4210 var jsScopeArray = $scope.toArray(); 4211 4212 for (var i = 0; i < jsScopeArray.length; i++) { 4213 var scope = jsScopeArray[i], 4214 fsList = document.querySelectorAll('.showcase--list'); 4215 fsList.forEach(function ($this) { 4216 let project = $this.querySelectorAll('.showcase--project'); 4217 project.forEach(function (item) { 4218 let content = item.querySelector('.project--content'); 4219 item.querySelector('.project--head').addEventListener('click', function (click) { 4220 if (!item.classList.contains('showcase--project--active')) { 4221 4222 project.forEach(function (close) { 4223 content = close.querySelectorAll('.project--content') 4224 var contentState = Flip.getState(content, { 4225 props: ['padding'] 4226 }); 4227 close.classList.remove('showcase--project--active') 4228 4229 Flip.from(contentState, { 4230 duration: .75, 4231 ease: 'expo.inOut', 4232 absolute: false, 4233 absoluteOnLeave: false, 4234 }) 4235 }) 4236 4237 content = item.querySelectorAll('.project--content') 4238 var contentState = Flip.getState(content, { 4239 props: ['padding'] 4240 }); 4241 item.classList.add('showcase--project--active') 4242 Flip.from(contentState, { 4243 duration: .75, 4244 ease: 'expo.inOut', 4245 absolute: false, 4246 absoluteOnLeave: false, 4247 onStart: () => { 4248 if (!$this.classList.contains('project__active')) { 4249 $this.classList.add('project__active') 4250 } 4251 4252 } 4253 }) 4254 } else { 4255 content = item.querySelectorAll('.project--content') 4256 var contentState = Flip.getState('.project--content', { 4257 props: ['padding'] 4258 }) 4259 item.classList.remove('showcase--project--active') 4260 Flip.from(contentState, { 4261 duration: .75, 4262 ease: 'expo.inOut', 4263 absolute: false, 4264 absoluteOnLeave: false, 4265 onComplete: () => { 4266 $this.classList.remove('project__active') 4267 } 4268 }) 4269 } 4270 }) 4271 }) 4272 }) 4273 } 4274 }); 1 4275 4276 elementorFrontend.hooks.addAction('frontend/element_ready/peshowcasevoid.default', function ($scope, $) { 4277 var jsScopeArray = $scope.toArray(); 4278 4279 for (var i = 0; i < jsScopeArray.length; i++) { 4280 var scope = jsScopeArray[i], 4281 fsList = document.querySelectorAll('.showcase--void'); 4282 fsList.forEach(function ($this) { 4283 let wrapper = $this.querySelector('.showcase--void--wrapper'), 4284 metaWrapper = $this.querySelector('.showcase--void--meta--wrapper'), 4285 project = $this.querySelectorAll('.showcase--project'), 4286 meta = $this.querySelectorAll('.project--meta'), 4287 length = project.length; 4288 4289 if (length % 2 !== 0) { 4290 var middleIndex = Math.floor(length / 2), 4291 middleElement = project[middleIndex], 4292 clone = middleElement.cloneNode(true); 4293 clone.classList.add('clone') 4294 wrapper.appendChild(clone); 4295 4296 } 4297 4298 4299 4300 project = $this.querySelectorAll('.showcase--project') 4301 4302 project.forEach(function (item, i) { 4303 gsap.set(item, { 4304 top: gsap.utils.random(0, 100) + '%', 4305 }) 4306 if (i % 2 === 0) { 4307 gsap.set(item, { 4308 left: gsap.utils.random(-5, -25) + '%' 4309 }) 4310 } else { 4311 gsap.set(item, { 4312 left: gsap.utils.random(50, 90) + '%' 4313 }) 4314 } 4315 let clone = item.cloneNode(true) 4316 clone.classList.add('clone') 4317 wrapper.appendChild(clone) 4318 }) 4319 4320 4321 project = $this.querySelectorAll('.showcase--project') 4322 project.forEach(function (item, i) { 4323 item.setAttribute('data-z', -3000 * i) 4324 item.setAttribute('data-opacity', 1 - (i * 0.2)) 4325 gsap.set(item, {
4326 z: -3000 * i, 4327 }) 4328 item.style.opacity = 1 - (i * 0.25) 4329 item.style.zIndex = 100 - i 4330 }) 4331 4332 let wheeler = Hamster(document.querySelector('body')), 4333 z = 0; 4334 project = $this.querySelectorAll('.showcase--project'), 4335 meta = $this.querySelectorAll('.project--meta'); 4336 let smoothZ = 0; 4337 4338 wheeler.wheel(function (event, delta, deltaX, deltaY) { 4339 updateProjects(deltaY); 4340 }); 4341 4342 matchMedia.add({ 4343 isMobile: "(max-width: 570px)" 4344 4345 }, (context) => { 4346 4347 let { 4348 isMobile 4349 } = context.conditions; 4350 4351 let touchStartY = 0; 4352 4353 document.addEventListener('touchstart', function (event) { 4354 touchStartY = event.touches[0].clientY; 4355 }); 4356 4357 document.addEventListener('touchmove', function (event) { 4358 let touchEndY = event.touches[0].clientY; 4359 let deltaY = touchStartY - touchEndY; 4360 touchStartY = touchEndY; 4361 updateProjects(deltaY * -10); 4362 }); 4363 4364 4365 }); 4366 4367 function updateProjects(deltaY) { 4368 z += deltaY * -1; 4369 } 4370 4371 function smoothAnimation() { 4372 if (window.navigator.platform === 'MacIntel') { 4373 smoothZ += (z - smoothZ) * 0.1; 4374 } else { 4375 smoothZ += (z * 50 - smoothZ) 4376 } 4377 4378 project.forEach(function (item, i) { 4379 gsap.set(item, { 4380 z: parseInt(item.getAttribute('data-z')) + smoothZ 4381 }); 4382 item.style.opacity = (1 - (i * 0.25)) + (smoothZ / 12000); 4383 4384 if (smoothZ > $this.querySelectorAll('.clone').length * 3000) { 4385 smoothZ = 0; 4386 z = 0; 4387 } else if (smoothZ < 0) { 4388 smoothZ = $this.querySelectorAll('.clone').length * 3000 + smoothZ; 4389 z = smoothZ; 4390 } 4391 }); 4392 4393 meta.forEach(function ($meta, i) { 4394 if ((1 - (i * 0.25)) + (smoothZ / 12000) > 0.85) { 4395 $meta.classList.add('project--meta--active'); 4396 // scope.querySelector('.project_' + $meta.dataset.id).classList.add('showcase--project--active') 4397 4398 } else { 4399 $meta.classList.remove('project--meta--active'); 4400 // scope.querySelector('.project_' + $meta.dataset.id).classList.remove('showcase--project--active') 4401 } 4402 if ((1 - (i * 0.25)) + (smoothZ / 12000) > 1.1) { 4403 $meta.classList.remove('project--meta--active'); 4404 // scope.querySelector('.project_' + $meta.dataset.id).classList.remove('showcase--project--active') 4405 } 4406 }); 4407 4408 requestAnimationFrame(smoothAnimation); 4409 } 4410 smoothAnimation(); 4411 }) 4412 } 4413 }); 4414 4415 elementorFrontend.hooks.addAction('frontend/element_ready/peshowcaseslider.default', function ($scope, $) { 4416 var jsScopeArray = $scope.toArray(); 4417 4418 for (var i = 0; i < jsScopeArray.length; i++) { 4419 var scope = jsScopeArray[i], 4420 fsList = document.querySelectorAll('.showcase--slider'); 4421 fsList.forEach(function ($this) { 4422 let project = $this.querySelectorAll('.showcase--project'), 4423 total = $this.querySelector('.fraction--item.item--total'); 4424 total.innerText = project.length; 4425 4426 function linesAnimate(image) { 4427 4428 let grid = scope.querySelector('.showcase--slider--gri
4428d'), 4429 lines = grid.querySelectorAll('span'); 4430 4431 lines.forEach((line, i) => { 4432 4433 gsap.to(line, { 4434 x: i = 0 ? image.getBoundingClientRect().left : '' 4435 }) 4436 4437 }) 4438 4439 } 4440 4441 project.forEach(function (item, i) { 4442 let headerHeight = document.querySelector('.site-header').offsetHeight, 4443 image = item.querySelector('.project--image'); 4444 4445 linesAnimate 4446 4447 gsap.set(item, { 4448 top: gsap.utils.random(headerHeight, $this.offsetHeight - item.offsetHeight - $this.querySelector('.showcase--slider--footer').offsetHeight), 4449 left: gsap.utils.random(0, $this.offsetWidth - item.offsetWidth) 4450 }) 4451 4452 gsap.set(item.querySelector('.project--image'), { 4453 height: item.querySelector('.project--meta--bottom').offsetHeight 4454 }) 4455 4456 }) 4457 4458 4459 let navItem = $this.querySelectorAll('.nav--item'); 4460 navItem.forEach(function (navClick) { 4461 let activeIndex = 0; 4462 navClick.addEventListener('click', function () { 4463 if (!$this.classList.contains('is_animating')) { 4464 gsap.to($this.querySelectorAll('.project--image'), { 4465 clipPath: 'inset(0% 100% 0% 0%)', 4466 ease: 'expo.in', 4467 duration: .75, 4468 onStart: () => { 4469 $this.classList.add('is_animating') 4470 } 4471 }) 4472 if (navClick.classList.contains('nav--prev')) { 4473 if (activeIndex === 0) { 4474 activeIndex = project.length - 1 4475 } else { 4476 activeIndex = activeIndex - 1 4477 } 4478 } else if (navClick.classList.contains('nav--next')) { 4479 if (activeIndex === project.length - 1) { 4480 activeIndex = 0 4481 } else { 4482 activeIndex = activeIndex + 1 4483 } 4484 } 4485 4486 gsap.fromTo(project[activeIndex].querySelectorAll('.project--image'), { 4487 clipPath: 'inset(0% 0% 0% 100%)' 4488 }, { 4489 clipPath: 'inset(0% 0% 0% 0%)', 4490 duration: .75, 4491 ease: 'expo.out', 4492 delay: .75, 4493 onComplete: () => { 4494 $this.classList.remove('is_animating') 4495 } 4496 }) 4497 4498 project.forEach(function (item) { 4499 item.classList.remove('showcase--project--active') 4500 }) 4501 $this.querySelector('.showcase--project__' + activeIndex).classList.add('showcase--project--active') 4502 $this.querySelector('.fraction--item.item--active').innerText = activeIndex + 1 4503 } 4504 }) 4505 4506 if ($this.classList.contains('wheel--navigate')) { 4507 let wheler = Hamster($this); 4508 wheler.wheel(function (deltaY) { 4509 let delta = event.deltaY 4510 if (delta > 0) { 4511 navItem[1].click(); 4512 } else if (delta < 0) { 4513 navItem[0].click(); 4514 } 4515 $this.classList.add('is_animating') 4516 }); 4517 4518 let touchStartY = 0; 4519 4520 $this.addEventListener('touchstart', function (event) { 4521 touchStartY = event.touches[0].clientY; 4522 }); 4523 4524 $this.addEventListener('touchmove', function (event) { 4525 let touchEndY = event.touches[0].clientY; 4526 let deltaY = touchStartY - touchEndY; 4527 4528 if (deltaY > 0) { 4529 navItem[1].click(); 4530 } else if (deltaY < 0) { 4531 navItem[0].click(); 4532 } 4533 $this.classList.add('is_animating'); 4534 touchStartY = touchEndY; 4535 }); 4536 } 4537 4538 }) 4539 4540 if ($this.classList.contains('autoplay')) { 4541 let delay, 4542 autoplay; 4543 if ($this.dataset.delay) {
4544 delay = parseInt($this.dataset.delay) 4545 } else { 4546 delay = 5000 4547 } 4548 4549 function startAutoplay() { 4550 autoplay = setInterval(function () { 4551 navItem[1].click(); 4552 }, delay) 4553 } 4554 4555 function stopAutoplay() { 4556 clearInterval(autoplay); 4557 } 4558 4559 startAutoplay(); 4560 4561 project.forEach(function (item) { 4562 item.querySelector('.project-button').addEventListener('mouseenter', function () { 4563 stopAutoplay(); 4564 }) 4565 item.querySelector('.project-button').addEventListener('mouseleave', function () { 4566 startAutoplay(); 4567 }) 4568 }) 4569 4570 4571 4572 4573 } 4574 4575 4576 }) 4577 } 4578 }); 4579 4580 elementorFrontend.hooks.addAction('frontend/element_ready/peinfinitegrid.default', function ($scope, $) { 4581 var jsScopeArray = $scope.toArray(); 4582 4583 for (var i = 0; i < jsScopeArray.length; i++) { 4584 var scope = jsScopeArray[i], 4585 infiniteGrid = document.querySelectorAll('.infinite--grid'); 4586 infiniteGrid.forEach(function ($this) { 4587 let column = parseInt($this.getAttribute('data-column')), 4588 wrapper = $this.querySelector('.infinite--grid--wrapper'), 4589 gridColumn = $this.querySelectorAll('.grid--column'), 4590 project = $this.querySelectorAll('.showcase--project'), 4591 residual = column - (project.length % column), 4592 tl = gsap.timeline({ 4593 repeat: -1 4594 }), 4595 wheeler = Hamster(document.querySelector('body')), 4596 autoplay = $this.dataset.autoplay, 4597 duration = $this.dataset.autoplayDuration, 4598 prog = 0, 4599 wheelDeltaY; 4600 4601 matchMedia.add({ 4602 isDesktop: "(min-width: 571px)" 4603 4604 }, (context) => { 4605 4606 let { 4607 isDesktop 4608 } = context.conditions; 4609 4610 let e = 0 4611 if (residual !== column) { 4612 for (e = 0; e < residual; e++) { 4613 let clone = $this.querySelector('.project__' + e).cloneNode(true); 4614 gridColumn[e + (column - residual)].appendChild(clone) 4615 } 4616 } 4617 gridColumn.forEach(function (grid, i) { 4618 if (i % 2 === 0) { 4619 grid.classList.add('grid__up') 4620 } else { 4621 grid.classList.add('grid__down') 4622 } 4623 let item = grid.querySelectorAll('.showcase--project'); 4624 for (let clone = 0; clone < 2; clone++) { 4625 item.forEach(function (item) { 4626 let itemClone = item.cloneNode(true); 4627 grid.appendChild(itemClone); 4628 }); 4629 } 4630 }) 4631 4632 4633 4634 if (autoplay == 'true') { 4635 4636 gridColumn.forEach(function (grid) { 4637 if (grid.classList.contains('grid__up')) { 4638 tl.to(grid, { 4639 y: -33.3333333 + '%', 4640 duration: duration, 4641 ease: 'none' 4642 }, 0) 4643 } else { 4644 tl.fromTo(grid, { 4645 y: -33.333333 + '%' 4646 }, { 4647 y: -0 + '%', 4648 duration: duration, 4649 ease: 'none' 4650 }, 0) 4651 } 4652 }) 4653 } 4654 4655 wheeler.wheel(function (event, deltaY) { 4656 prog = prog + (deltaY / 100) 4657 4658 if (autoplay == 'true') { 4659 4660 wheeler.wheel(function (event, delta, deltaX, deltaY) { 4661 4662 wheelDeltaY = event.deltaY; 4663 event.deltaY < 0 ? wheelDeltaY = -1 * event.deltaY : ''; 4664 tl.timeScale(1 + (wheelDeltaY * 5)) 4665 4666 }); 4667 4668 } else { 4669 4670 if (prog < -33.333333) { 4671 prog = 0 4672 } else if (prog > 0) { 4673 prog = -33.333333 4674 } 4675 4676
4677 gridColumn.forEach(function (grid) { 4678 if (grid.classList.contains('grid__up')) { 4679 gsap.set(grid, { 4680 y: prog + '%' 4681 }) 4682 } else { 4683 gsap.set(grid, { 4684 y: (-33.333333 - prog) + '%' 4685 }) 4686 } 4687 }) 4688 } 4689 }) 4690 4691 project = $this.querySelectorAll('.showcase--project') 4692 project.forEach(function (item) { 4693 const mouseEnterHandler = function () { 4694 $this.classList.add('hovered'); 4695 prog = 0 4696 this.classList.add('showcase--project--active'); 4697 tl.pause(); 4698 }; 4699 4700 const mouseLeaveHandler = function () { 4701 $this.classList.remove('hovered'); 4702 prog = 0 4703 this.classList.remove('showcase--project--active'); 4704 tl.play(); 4705 }; 4706 4707 const clickHandler = function () { 4708 tl.pause(); 4709 prog = 0 4710 item.removeEventListener('mouseleave', mouseLeaveHandler); 4711 }; 4712 4713 item.addEventListener('mouseenter', mouseEnterHandler); 4714 item.addEventListener('mouseleave', mouseLeaveHandler); 4715 item.addEventListener('click', clickHandler); 4716 }); 4717 4718 4719 4720 }); 4721 4722 matchMedia.add({ 4723 isMobile: "(max-width: 570px)" 4724 4725 }, (context) => { 4726 4727 let { 4728 isMobile 4729 } = context.conditions; 4730 4731 gridColumn.forEach(function (column) { 4732 let clone = column.cloneNode(true); 4733 wrapper.appendChild(clone) 4734 }) 4735 let drag = Draggable.create(wrapper, { 4736 type: 'y', 4737 inertia: true, 4738 onThrowUpdate: function () { 4739 var yPosition = this.y; 4740 if (yPosition > 0) { 4741 gsap.set(wrapper, { 4742 y: -1 * (wrapper.offsetHeight / 2) + yPosition 4743 }) 4744 } else if (yPosition < -1 * (wrapper.offsetHeight / 2)) { 4745 gsap.set(wrapper, { 4746 y: yPosition + (wrapper.offsetHeight / 2) 4747 }) 4748 } 4749 }, 4750 }) 4751 4752 4753 }); 4754 4755 }) 4756 4757 4758 4759 4760 } 4761 }); 4762 4763 elementorFrontend.hooks.addAction('frontend/element_ready/peshowcasewall.default', function ($scope, $) { 4764 var jsScopeArray = $scope.toArray(); 4765 4766 for (var i = 0; i < jsScopeArray.length; i++) { 4767 var scope = jsScopeArray[i], 4768 showcaseWall = scope.querySelector('.showcase--wall'), 4769 wrapper = showcaseWall.querySelector('.showcase--wall--wrapper'), 4770 pinnedElements = wrapper.dataset.pinnedElements, 4771 project = scope.querySelectorAll('.showcase--project'); 4772 let speed; 4773 if (showcaseWall.dataset.speed) { 4774 speed = 'bottom+=' + showcaseWall.dataset.speed + ' top' 4775 } else { 4776 speed = 'bottom+=5000 top' 4777 } 4778 4779 let tl = gsap.timeline({ 4780 scrollTrigger: { 4781 trigger: showcaseWall, 4782 start: 'top top', 4783 end: speed, 4784 pin: true, 4785 scrub: 1.5 4786 } 4787 }); 4788 4789 4790 setTimeout(() => { 4791 if (pinnedElements) { 4792 4793 document.querySelectorAll(pinnedElements).forEac
4793h(element => { 4794 4795 ScrollTrigger.create({ 4796 trigger: element, 4797 start: 0, 4798 end: tl.scrollTrigger.end - tl.scrollTrigger.start, 4799 pin: true, 4800 pinSpacing: false, 4801 }) 4802 }) 4803 } 4804 }, 50); 4805 4806 matchMedia.add({ 4807 isMobile: "(max-width: 570px)" 4808 }, (context) => { 4809 4810 let { 4811 isMobile 4812 } = context.conditions; 4813 4814 tl.to(document.querySelectorAll('.left__to__right'), { 4815 x: '100%', 4816 }, 0) 4817 4818 tl.to(document.querySelectorAll('.right__to__left'), { 4819 x: '-100%' 4820 }, 0) 4821 4822 4823 }); 4824 4825 matchMedia.add({ 4826 isDesktop: "(min-width: 571px)" 4827 }, (context) => { 4828 let { 4829 isDesktop 4830 } = context.conditions; 4831 4832 tl.to(document.querySelectorAll('.left__to__right'), { 4833 x: '50%' 4834 }, 0) 4835 4836 tl.to(document.querySelectorAll('.right__to__left'), { 4837 x: '-50%' 4838 }, 0) 4839 4840 4841 }); 4842 4843 4844 4845 project.forEach(function (item) { 4846 item.addEventListener('mouseenter', function () { 4847 showcaseWall.classList.add('showcase--hovered') 4848 let activeIndex = parseInt(item.getAttribute('data-index')) 4849 document.querySelector('.image__' + activeIndex).classList.add('showcase--image--active') 4850 }) 4851 item.addEventListener('mouseleave', function () { 4852 showcaseWall.classList.remove('showcase--hovered') 4853 let activeIndex = parseInt(item.getAttribute('data-index')) 4854 document.querySelector('.image__' + activeIndex).classList.remove('showcase--image--active') 4855 }) 4856 4857 item.addEventListener('mousemove', function (e) { 4858 4859 let mouseLeft = e.clientX, 4860 mouseTop = e.clientY, 4861 movX = event.movementX < 0 ? event.movementX * -1 : event.movementX; 4862 4863 gsap.to(document.querySelector('.showcase--wall--image--overlay'), { 4864 left: mouseLeft, 4865 top: mouseTop, 4866 rotate: gsap.utils.clamp(-10, 10, (event.movementX / 5)), 4867 duration: 1, 4868 ease: 'power3.out', 4869 }) 4870 }) 4871 }) 4872 4873 } 4874 }); 4875 4876 elementorFrontend.hooks.addAction('frontend/element_ready/peshowcasecarousel.default', function ($scope, $) { 4877 var jsScopeArray = $scope.toArray(); 4878 4879 for (var i = 0; i < jsScopeArray.length; i++) { 4880 4881 var scope = jsScopeArray[i], 4882 showcaseCarousel = document.querySelectorAll('.showcase--carousel'); 4883 4884 showcaseCarousel.forEach(function ($this) { 4885 let wrap = $this.querySelector('.showcase--carousel--wrapper'), 4886 project = $this.querySelectorAll('.showcase--project'), 4887 centersArray = [], 4888 pinnedElements = $this.dataset.pinnedElements, 4889 sizes = getComputedStyle($this), 4890 activeWidth = sizes.getPropertyValue('--activeWidth'), 4891 act = document.body.clientWidth / (100 / parseInt(activeWidth)), 4892 finish; 4893 if ($this.dataset.speed) { 4894 finish = 'bottom+=' + $this.dataset.speed + ' center'; 4895 } else { 4896 finish = 'bottom+=3000 center'; 4897 } 4898 // matchMedia.add({ 4899 // isMobile: "(max-width: 570px)" 4900 // }, (context) => { 4901 // let { 4902 // isMobile 4903 // } = context.conditions; 4904 // project[0].classList.add('showcase--project--active') 4905 // }); 4906 4907 var tl = gsap.timeline(), 4908 scrollera = ScrollTrigger.create({ 4909 trigger: $this, 4910 start: 'center center', 4911 end: finish, 4912 pin: true, 4913 scrub: 1.5, 4914 id: 'showcase--scroll', 4915 animation: tl, 4916 onUpdate: function (self) { 4917 matchMedia.add({ 4918 isMobile: "(max-width: 570px)" 4919 }, (context) => { 4920 let { 4921 isMobile 4922 } = context.conditions; 4923 let activeIndex = Math.round(self.progress * project.length) 4924 project.forEach(function ($item, index) { 4925 if (index === activeIndex) { 4926 $item.classList.add('showcase--project--active') 4927 } else { 4928 $item.classList.remove('showcase--project--active') 4929 } 4930 }) 4931 4932 4933 }); 4934 } 4935 }); 4936 4937 setTimeout(() => { 4938 if (pinnedElements) { 4939 4940 document.querySelectorAll(pinnedElements).forEac
4940h(element => { 4941 4942 ScrollTrigger.create({ 4943 trigger: element, 4944 start: 0, 4945 end: tl.scrollTrigger.end - tl.scrollTrigger.start, 4946 pin: true, 4947 pinSpacing: false, 4948 }) 4949 }) 4950 } 4951 }, 50); 4952 4953 matchMedia.add({ 4954 isMobile: "(max-width: 550px)" 4955 4956 }, (context) => { 4957 4958 let { 4959 isMobile 4960 } = context.conditions; 4961 4962 tl.kill(); 4963 scrollera.kill(true) 4964 4965 let wrapper = scope.querySelector('.showcase--carousel--wrapper'); 4966 4967 4968 Draggable.create(wrapper, { 4969 type: 'x', 4970 bounds: { 4971 // minX: 0, 4972 // maxX: -wrap.getBoundingClientRect().width + document.body.clientWidth 4973 }, 4974 lockAxis: true, 4975 dragResistance: 0.5, 4976 inertia: true, 4977 }); 4978 4979 4980 }); 4981 4982 var end = wrap.getBoundingClientRect().width - (document.body.clientWidth / 2); 4983 4984 if (!mobileQuery.matches) { 4985 4986 project.forEach(function (item, i) { 4987 4988 let sc = item.getBoundingClientRect().left + item.getBoundingClientRect().width - (item.getBoundingClientRect().width / 2) - (document.body.clientWidth / 2), 4989 bc = item.getBoundingClientRect().left + act - (act / 2) - (document.body.clientWidth / 2); 4990 4991 centersArray.push({ 4992 smallCenter: sc, 4993 bigCenter: bc 4994 }) 4995 if (bc > 0) { 4996 4997 tl.to(wrap, { 4998 x: -1 * (bc + (item.getBoundingClientRect().width)), 4999 ease: 'none' 5000 }, 'label_' + (item.dataset.index)) 5001 } 5002 5003 item.addEventListener('click', function (i) { 5004 5005 reset(); 5006 gsap.to(item, { 5007 width: activeWidth, 5008 height: sizes.getPropertyValue('--activeHeight'), 5009 duration: .75, 5010 ease: 'expo.inOut', 5011 onStart: () => { 5012 item.classList.add('showcase--project--active') 5013 }, 5014 }) 5015 5016 gsap.to(window, { 5017 scrollTo: scrollera.labelToScroll('label_' + (parseInt(item.dataset.index))), 5018 duration: .75, 5019 ease: 'expo.inOut', 5020 }); 5021 5022 }) 5023 }) 5024 5025 } 5026 5027 let animating = false; 5028 5029 function reset() { 5030 if (scope.querySelector('.showcase--project--active')) { 5031 5032 gsap.to(scope.querySelector('.showcase--project--active'), { 5033 width: sizes.getPropertyValue('--inactiveWidth'), 5034 height: sizes.getPropertyValue('--inactiveHeight'), 5035 duration: .75, 5036 ease: 'expo.inOut', 5037 onComplete: () => { 5038 animating = false 5039 }, 5040 onStart: () => { 5041 animating = true; 5042 if (scope.querySelector('.showcase--project--active')) { 5043 scope.querySelector('.showcase--project--active').classList.remove('showcase--project--active') 5044 } 5045 5046 } 5047 }) 5048 } 5049 5050 } 5051 5052 $this.addEventListener('wheel', () => { 5053 if (!animating) { 5054 reset(); 5055 } 5056 }) 5057 5058 document.addEventListener('keydown', function (event) { 5059 if (event.key === 'Escape' || event.keyCode === 27) { 5060 reset(); 5061 } 5062 }); 5063 5064 5065 }) 5066 5067 } 5068 }); 5069 5070 5071 }) 5072 5073 5074}
5074)(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.