1(function ($) { 2 "use strict"; 3 /*================================= 4 JS Index Here 5 ==================================*/ 6 /* 7 01. On Load Function 8 02. Preloader 9 03. Mobile Menu 10 04. Sticky fix 11 05. Scroll To Top 12 06. Set Background Image Color & Mask 13 07. Global Slider 14 08. Ajax Contact Form 15 09. Search Box Popup 16 10. Popup Sidemenu 17 11. Magnific Popup 18 12. Section Position 19 13. Filter 20 14. Counter Up 21 15. Shape Mockup 22 16. Progress Bar Animation 23 17. Countdown 24 18. Image to SVG Code 25 00. Woocommerce Toggle 26 00. Right Click Disable 27 */ 28 /*================================= 29 JS Index End 30 ==================================*/ 31 /* 32 33 /*---------- 01. On Load Function ----------*/ 34 $(window).on("load", function () { 35 $(".preloader").fadeOut(); 36 }); 37 38 /*---------- 02. Preloader ----------*/ 39 $(document).on("click", ".preloaderCls", function (e) { 40 e.preventDefault(); 41 $(".preloader").css("display", "none"); 42 }); 43 44 // $('select').niceSelect(); 45 if ($('.nice-select').length) { 46 $('.nice-select').niceSelect(); 47 } 48 49 /*---------- 03. Mobile Menu ----------*/ 50 $.fn.thmobilemenu = function (options) { 51 var opt = $.extend({ 52 menuToggleBtn: ".th-menu-toggle", 53 bodyToggleClass: "th-body-visible", 54 subMenuClass: "th-submenu", 55 subMenuParent: "menu-item-has-children", 56 thSubMenuParent: "th-item-has-children", 57 subMenuParentToggle: "th-active", 58 meanExpandClass: "th-mean-expand", 59 // appendElement: '<span class="th-mean-expand"></span>', 60 subMenuToggleClass: "th-open", 61 toggleSpeed: 400, 62 }, 63 options 64 ); 65 66 return this.each(function () { 67 var menu = $(this); // Select menu 68 69 // Menu Show & Hide 70 function menuToggle() { 71 menu.toggleClass(opt.bodyToggleClass); 72 73 // collapse submenu on menu hide or show 74 var subMenu = "." + opt.subMenuClass; 75 $(subMenu).each(function () { 76 if ($(this).hasClass(opt.subMenuToggleClass)) { 77 $(this).removeClass(opt.subMenuToggleClass); 78 $(this).css("display", "none"); 79 $(this).parent().removeClass(opt.subMenuParentToggle); 80 } 81 }); 82 } 83 84 // Class Set Up for every submenu 85 menu.find("." + opt.subMenuParent).each(function () { 86 var submenu = $(this).find("ul"); 87 submenu.addClass(opt.subMenuClass); 88 submenu.css("display", "none"); 89 $(this).addClass(opt.subMenuParent); 90 $(this).addClass(opt.thSubMenuParent); // Add th-item-has-children class 91 $(this).children("a").append(opt.appendElement); 92 }); 93 94 // Toggle Submenu 95 function toggleDropDown($element) { 96 var submenu = $element.children("ul"); 97 if (submenu.length > 0) { 98 $element.toggleClass(opt.subMenuParentToggle); 99 submenu.slideToggle(opt.toggleSpeed); 100 submenu.toggleClass(opt.subMenuToggleClass); 101 } 102 } 103 104 // Submenu toggle Button 105 var itemHasChildren = "." + opt.thSubMenuParent + " > a"; 106 $(itemHasChildren).each(function () { 107 $(this).on("click", function (e) { 108 e.preventDefault(); 109 toggleDropDown($(this).parent()); 110 }); 111 }); 112 113 // Menu Show & Hide On Toggle Btn click 114 $(opt.menuToggleBtn).each(function () { 115 $(this).on("click", function () { 116 menuToggle(); 117 }); 118 }); 119 120 // Hide Menu On outside click 121 menu.on("click", function (e) { 122 e.stopPropagation(); 123 menuToggle(); 124 }); 125 126 // Stop Hide full menu on menu click 127 menu.find("div").on("click", function (e) { 128 e.stopPropagation(); 129 }); 130 }); 131 }; 132 133 134 $(".th-menu-wrapper").thmobilemenu(); 135 136 /*---------- 04. Sticky fix ----------*/ 137 $(window).scroll(function () { 138 var topPos = $(this).scrollTop(); 139 if (topPos > 500) { 140 $('.sticky-wrapper').addClass('sticky'); 141 } else { 142 $('.sticky-wrapper').removeClass('sticky') 143 } 144 }) 145 146 /*----------- 04.1. One Page Nav ----------*/ 147 function onePageNav(element) { 148 if ($(element).length > 0) { 149 $(element).each(function () { 150 var link = $(this).find('a'); 151 $(this).find(link).each(function () { 152 $(this).on('click', function () { 153 var target = $(this.getAttribute('href')); 154 if (target.length) { 155 event.preventDefault(); 156 $('html, body').stop().animate({ 157 scrollTop: target.offset().top - 10 158 }, 1000); 159 }; 160 161 }); 162 }); 163 }) 164 } 165 }; 166 onePageNav('.onepage-nav'); 167 onePageNav('.scroll-down'); 168 //one page sticky menu 169 $(window).on('scroll', function(){ 170 if ($('.onepage-nav').length > 0) { 171 }; 172 }); 173 174 /*---------- 04. Sticky fix ----------*/ 175 $(window).scroll(function () { 176 var topPos = $(this).scrollTop(); 177 if (topPos > 500) { 178 $('.sticky-wrapper').addClass('sticky'); 179 $('.category-menu').addClass('close-category'); 180 } else { 181 $('.sticky-wrapper').removeClass('sticky') 182 $('.category-menu').removeClass('close-category'); 183 } 184 }) 185 186 $(".menu-expand").each(function () { 187 $(this).on("click", function (e) { 188 e.preventDefault(); 189 $('.category-menu').toggleClass('open-category'); 190 }); 191 }); 192 193 194 /*---------- 05. Scroll To Top ----------*/ 195 $(document).ready(function () { 196 if ($('.scroll-top').length > 0) { 197 var scrollTopbtn = $('.scroll-top')[0]; 198 var progressPath = $('.scroll-top path')[0]; 199 var pathLength = progressPath.getTotalLength(); 200 201 // Initialize stroke-dasharray and stroke-dashoffset for the progress path 202 progressPath.style.transition = progressPath.style.WebkitTransition = '
202none'; 203 progressPath.style.strokeDasharray = pathLength + ' ' + pathLength; 204 progressPath.style.strokeDashoffset = pathLength; 205 progressPath.getBoundingClientRect(); 206 progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear'; 207 208 // Update the progress bar 209 var updateProgress = function () { 210 var scroll = $(window).scrollTop(); 211 var height = $(document).height() - $(window).height(); 212 var progress = pathLength - (scroll * pathLength / height); 213 progressPath.style.strokeDashoffset = progress; 214 }; 215 updateProgress(); 216 217 $(window).on('scroll', updateProgress); 218 219 var offset = 50; 220 var duration = 750; 221 222 // Show the scroll-to-top button on scroll 223 $(window).on('scroll', function () { 224 if ($(this).scrollTop() > offset) { 225 $(scrollTopbtn).addClass('show'); 226 } else { 227 $(scrollTopbtn).removeClass('show'); 228 } 229 }); 230 231 // Click event to scroll to top 232 $(scrollTopbtn).on('click', function (event) { 233 event.preventDefault(); 234 $('html, body').animate({ 235 scrollTop: 0 236 }, duration); 237 return false; 238 }); 239 } 240 }); 241 242 243 /*---------- 06. Set Background Image Color & Mask ----------*/ 244 if ($("[data-bg-src]").length > 0) { 245 $("[data-bg-src]").each(function () { 246 var src = $(this).attr("data-bg-src"); 247 $(this).css("background-image", "url(" + src + ")"); 248 $(this).removeAttr("data-bg-src"); 249 // Only add class if not already present to avoid hydration issues 250 if (!$(this).hasClass("background-image")) { 251 $(this).addClass("background-image"); 252 } 253 }); 254 } 255 256 if ($('[data-bg-color]').length > 0) { 257 $('[data-bg-color]').each(function () { 258 var color = $(this).attr('data-bg-color'); 259 $(this).css('background-color', color); 260 $(this).removeAttr('data-bg-color'); 261 }); 262 }; 263 264 $('[data-border]').each(function () { 265 var borderColor = $(this).data('border'); 266 $(this).css('--th-border-color', borderColor); 267 }); 268 269 if ($('[data-mask-src]').length > 0) { 270 $('[data-mask-src]').each(function () { 271 var mask = $(this).attr('data-mask-src'); 272 $(this).css({ 273 'mask-image': 'url(' + mask + ')', 274 '-webkit-mask-image': 'url(' + mask + ')' 275 }); 276 $(this).addClass('bg-mask'); 277 $(this).removeAttr('data-mask-src'); 278 }); 279 }; 280 281 /*----------- 07. Global Slider ----------*/ 282 283 $('.th-slider').each(function () { 284 var thSlider = $(this); 285 var settings = $(this).data('slider-options'); 286 287 // Store references to the navigation Slider 288 var prevArrow = thSlider.find('.slider-prev'); 289 var nextArrow = thSlider.find('.slider-next'); 290 var paginationElN = thSlider.find('.slider-pagination.pagi-number'); 291 var paginationExternel = thSlider.siblings('.slider-controller').find('.slider-pagination'); 292 293 var paginationEl = paginationExternel.length ? paginationExternel.get(0) : thSlider.find('.slider-pagination').get(0); 294 295 var paginationType = settings['paginationType'] ? settings['paginationType'] : 'bullets'; 296 var autoplayconditon = settings['autoplay']; 297 298 var sliderDefault = { 299 slidesPerView: 1, 300 spaceBetween: settings['spaceBetween'] || 24, 301 loop: settings['loop'] !== false, 302 speed: settings['speed'] || 1000, 303 autoplay: autoplayconditon || { 304 delay: 6000, 305 disableOnInteraction: false 306 }, 307 navigation: { 308 nextEl: nextArrow.get(0), 309 prevEl: prevArrow.get(0), 310 }, 311 pagination: { 312 el: paginationEl, 313 type: paginationType, 314 clickable: true, 315 renderBullet: function (index, className) { 316 var number = index + 1; 317 var formattedNumber = number < 10 ? '0' + number : number; 318 if (paginationElN.length) { 319 return '<span class="' + className + ' number">' + formattedNumber + '</span>'; 320 } else { 321 return '<span class="' + className + '" aria-label="Go to Slide ' + formattedNumber + '"></span>'; 322 } 323 }, 324 formatFractionCurrent: function (number) { 325 return number < 10 ? '0' + number : number; 326 }, 327 formatFractionTotal: function (number) { 328 return number < 10 ? '0' + number : number; 329 } 330 }, 331 on: { 332 slideChange: function () { 333 setTimeout(function () { 334 swiper.params.mousewheel.releaseOnEdges = false;
335 }, 500); 336 }, 337 reachEnd: function () { 338 setTimeout(function () { 339 swiper.params.mousewheel.releaseOnEdges = true; 340 }, 750); 341 } 342 } 343 }; 344 345 var options = JSON.parse(thSlider.attr('data-slider-options')); 346 options = $.extend({}, sliderDefault, options); 347 var swiper = new Swiper(thSlider.get(0), options); // Assign the swiper variable 348 349 if ($('.slider-area').length > 0) { 350 $('.slider-area').closest(".container").parent().addClass("arrow-wrap"); 351 } 352 353 // Category slider specific wheel effect 354 if (thSlider.hasClass('categorySlider')) { 355 const multiplier = { 356 translate: 0.1, 357 rotate: 0.008 358 }; 359 360 function calculateWheel() { 361 const slides = document.querySelectorAll('.single'); 362 slides.forEach((slide) => { 363 const rect = slide.getBoundingClientRect(); 364 const r = window.innerWidth * 0.5 - (rect.x + rect.width * 0.5); 365 let ty = Math.abs(r) * multiplier.translate - rect.width * multiplier.translate; 366 367 if (ty < 0) { 368 ty = 0; 369 } 370 const transformOrigin = r < 0 ? 'left top' : 'right top'; 371 slide.style.transform = `translate(0, ${ty}px) rotate(${-r * multiplier.rotate}deg)`; 372 slide.style.transformOrigin = transformOrigin; 373 }); 374 } 375 376 function raf() { 377 requestAnimationFrame(raf); 378 calculateWheel(); 379 } 380 381 raf(); 382 } 383 }); 384 385 // Function to add animation classes 386 function animationProperties() { 387 $('[data-ani]').each(function () { 388 var animationName = $(this).data('ani'); 389 $(this).addClass(animationName); 390 }); 391 392 $('[data-ani-delay]').each(function () { 393 var delayTime = $(this).data('ani-delay'); 394 $(this).css('animation-delay', delayTime); 395 }); 396 } 397 animationProperties(); 398 399 // Add click event handlers for external slider arrows based on data attributes 400 $(document).on('click', '[data-slider-prev], [data-slider-next]', function () { 401 var sliderSelector = $(this).data('slider-prev') || $(this).data('slider-next'); 402 var targetSlider = $(sliderSelector); 403 404 if (targetSlider.length) { 405 var swiper = targetSlider[0].swiper; 406 407 if (swiper) { 408 if ($(this).data('slider-prev')) { 409 swiper.slidePrev(); 410 } else { 411 swiper.slideNext(); 412 } 413 } 414 } 415 }); 416 417 418 // Function to add animation classes 419 function animationProperties() { 420 $('[data-ani]').each(function () { 421 var animationName = $(this).data('ani'); 422 $(this).addClass(animationName); 423 }); 424 425 $('[data-ani-delay]').each(function () { 426 var delayTime = $(this).data('ani-delay'); 427 $(this).css('animation-delay', delayTime); 428 }); 429 } 430 animationProperties(); 431 432 var swiper = new Swiper(".heroThumbs", { 433 spaceBetween: 10, 434 slidesPerView: 1, 435 loop: true, 436 watchSlidesProgress: true, 437 slideToClickedSlide: true, 438 navigation: { 439 nextEl: '.slider-next', 440 prevEl: '.slider-prev' 441 }, 442 }); 443 444 var swiper = new Swiper('.hero-slider-2', { 445 spaceBetween: 10, 446 thumbs: { 447 swiper: '.heroThumbs', 448 }, 449 effect: "fade", 450 pagination: { 451 el: '.swiper-pagination', 452 clickable: true 453 }, 454 navigation: { 455 nextEl: '.swiper-button-next', 456 prevEl: '.swiper-button-prev' 457 }, 458 autoplay: { 459 delay: 6000, 460 disableOnInteraction: false 461 }, 462 loop: true, 463 watchSlidesProgress: true 464 }); 465 466 /* hero-3 start */ 467 var swiper = new Swiper(".hero3Thumbs", { 468 spaceBetween: 10, 469 slidesPerView: 1, 470 freeMode: true, 471 watchSlidesProgress: true, 472 }); 473 474 var swiper = new Swiper('.hero-slider-3', { 475 thumbs: { 476 swiper: swiper, 477 }, 478 loop: true, 479 effect: "fade", 480 autoplay: { 481 delay: 6000, 482 disableOnInteraction: false 483 }, 484 pagination: { 485 el: '.swiper-pagination', 486 type: 'fraction', 487 formatFractionCurrent: function (number) { 488 return '0' + number; 489 } 490 }, 491 navigation: { 492 nextEl: '.swiper-button-next', 493 prevEl: '.swiper-button-prev' 494 } 495 }); 496 497 /* hero-3 end */ 498 499 /* hero-6 start */ 500 var swiper = new Swiper(".hero6Thumbs", { 501 spaceBetween: 3, 502 slidesPerView: 1, 503 freeMode: true, 504 watchSlidesProgress: true, 505 }); 506 507 var swiper = new Swiper('.hero-slider-6', { 508 thumbs: { 509 swiper: swiper, 510 }, 511 loop: true, 512 effect: "fade", 513 autoplay: { 514 delay: 6000, 515 disableOnInteraction: false 516 }, 517 pagination: { 518 el: '.swiper-pagination', 519 type: 'fraction', 520 formatFractionCurrent: function (number) { 521 return '' + number; 522 } 523 }, 524 navigation: { 525 nextEl: '.swiper-button-next', 526 prevEl: '.swiper-button-prev' 527 } 528 }); 529 530 /* hero-6 end */ 531 532 /* hero-6 start */ 533 var swiper = new Swiper(".hero6Thumbs", { 534 spaceBetween: 3, 535 slidesPerView: 1, 536 freeMode: true, 537 watchSlidesProgress: true, 538 }); 539 540 var swiper = new Swiper('.hero-slider-6', { 541 thumbs: { 542 swiper: swiper, 543 }, 544 loop: true, 545 effect: "fade", 546 autoplay: { 547 delay: 6000, 548 disableOnInteraction: false 549 }, 550 pagination: { 551 el: '.swiper-pagination', 552 type: 'fraction', 553 formatFractionCurrent: function (number) { 554 return '' + number; 555 } 556 }, 557 navigation: { 558 nextEl: '.swiper-button-next', 559 prevEl: '.swiper-button-prev' 560 } 561 }); 562 563 /* hero-6 end */ 564 /* hero-10 start */ 565 var swiper = new Swiper(".hero9Thumbs", { 566 spaceBetween: 10, 567 slidesPerView: 1, 568 freeMode: true, 569 watchSlidesProgress: true, 570 }); 571 572 var swiper = new Swiper('.hero-slider-9', { 573 thumbs: { 574 swiper: swiper, 575 }, 576 loop: true, 577 effect: "fade", 578 autoplay: { 579 delay: 6000, 580 disableOnInteraction: false 581 }, 582 pagination: { 583 el: '.swiper-pagination', 584 type: 'fraction', 585 formatFractionCurrent: function (number) { 586 return '0' + number; 587 } 588 }, 589 navigation: { 590 nextEl: '.swiper-button-next', 591 prevEl: '.swiper-button-prev' 592 } 593 }); 594 595 /* hero-3 end */ 596 597 /* hero-10 start */ 598 var swiper = new Swiper(".hero10Thumbs", { 599 spaceBetween: 10, 600 slidesPerView: 3, 601 freeMode: true, 602 watchSlidesProgress: true, 603 }); 604 605 var swiper = new Swiper('.hero-slider-10', { 606 spaceBetween: 10, 607 thumbs: { 608 swiper: swiper, 609 }, 610 effect: "fade", 611 pagination: { 612 el: '.swiper-pagination', 613 type: 'fraction', 614 }, 615 navigation: { 616 nextEl: '.swiper-button-next', 617 prevEl: '.swiper-button-prev' 618 }, 619 autoplay: { 620 delay: 6000, 621 disableOnInteraction: false 622 }, 623 loop: true, 624 watchSlidesProgress: true 625 }); 626 /* hero-10 end */ 627 628 // var swiperEl = document.querySelector('.swiper-container'); 629 630 // swiperEl.addEventListener('mouseenter', function(event) { 631 document.addEventListener('mouseenter', event => { 632 const el = event.target; 633 if (el && el.matches && el.matches('.swiper-container')) { 634 // console.log('mouseenter'); 635 // console.log('autoplay running', swiper.autoplay.running); 636 el.swiper.autoplay.stop(); 637 el.classList.add('swiper-paused'); 638 639 const activeNavItem = el.querySelector('.swiper-pagination-bullet-active'); 640 activeNavItem.style.animationPlayState = "paused"; 641 } 642 }, true); 643 644 document.addEventListener('mouseleave', event => { 645 // console.log('mouseleave', swiper.activeIndex, swiper.slides[swiper.activeIndex].progress); 646 // console.log('autoplay running', swiper.autoplay.running); 647 const el = event.target; 648 if (el && el.matches && el.matches('.swiper-container')) { 649 el.swiper.autoplay.start(); 650 el.classList.remove('swiper-paused'); 651 652 const activeNavItem = el.querySelector('.swiper-pagination-bullet-active'); 653 654 activeNavItem.classList.remove('swiper-pagination-bullet-active');
655 // activeNavItem.style.animation = 'none'; 656 657 setTimeout(() => { 658 activeNavItem.classList.add('swiper-pagination-bullet-active'); 659 // activeNavItem.style.animation = ''; 660 }, 10); 661 } 662 }, true); 663 664 665 666 /* category slider 2 end ---------------------*/ 667 668 $(document).ready(function () { 669 /*-------------- 09. Custom service Slider -------------*/ 670 671 // Bind click event for .service-list-wrap with event delegation 672 $(document).on('click', '.service-list-wrap', function () { 673 $(this).addClass('active').siblings().removeClass('active'); 674 }); 675 676 // Accordion initial setup 677 $('.accordion-item-wrapp li:first-child').addClass('active'); 678 $('.according-img-tab').hide(); 679 $('.according-img-tab:first').show(); 680 681 // Mouseenter event for .accordion-item-content (using delegation) 682 $(document).on('mouseenter', '.accordion-item-wrapp .accordion-item-content', function () { 683 $('.accordion-item-wrapp .accordion-item-content').removeClass('active'); 684 $('.according-img-tab').hide(); 685 686 var activeTab = $(this).find('.accordion-tab-item').attr('data-bs-target'); 687 $(activeTab).fadeIn(); 688 return false; 689 }); 690 691 // Mouseover event for .hover-item (using delegation) 692 $(document).on('mouseover', '.hover-item', function () { 693 $(this).addClass('item-active'); 694 $('.hover-item').removeClass('item-active'); 695 $(this).addClass('item-active'); 696 }); 697 }); 698 699 700 $(document).ready(function () { 701 // Function to add animation classes 702 function animationProperties() { 703 // Delegate animation class addition 704 $(document).find('[data-ani]').each(function () { 705 var animationName = $(this).data('ani'); 706 $(this).addClass(animationName); 707 }); 708 709 // Delegate adding animation delay style 710 $(document).find('[data-ani-delay]').each(function () { 711 var delayTime = $(this).data('ani-delay'); 712 $(this).css('animation-delay', delayTime); 713 }); 714 } 715 animationProperties(); 716 717 // Add event delegation for slider arrows 718 $(document).on('click', '[data-slider-prev], [data-slider-next]', function () { 719 var sliderSelector = $(this).data('slider-prev') || $(this).data('slider-next'); 720 var targetSlider = $(sliderSelector); 721 722 if (targetSlider.length) { 723 var swiper = targetSlider[0].swiper; 724 725 if (swiper) { 726 if ($(this).data('slider-prev')) { 727 swiper.slidePrev(); 728 } else { 729 swiper.slideNext(); 730 } 731 } 732 } 733 }); 734 }); 735 736 737 /*-------------- 08. Slider Tab -------------*/ 738 $.fn.activateSliderThumbs = function (options) { 739 var opt = $.extend({ 740 sliderTab: false, 741 tabButton: ".tab-btn", 742 }, options); 743 744 return this.each(function () { 745 var $container = $(this); 746 var $thumbs = $container.find(opt.tabButton); 747 var $line = $('<span class="indicator"></span>').appendTo($container); 748 749 var sliderSelector = $container.data("slider-tab"); 750 var $slider = $(sliderSelector); 751 var swiper = $slider[0].swiper; 752 753 // Use event delegation for tab buttons 754 $(document).on("click", opt.tabButton, function (e) { 755 e.preventDefault(); 756 var clickedThumb = $(this); 757 758 clickedThumb.addClass("active").siblings().removeClass("active"); 759 linePos(clickedThumb, $container); 760 761 clickedThumb.prevAll(opt.tabButton).addClass('list-active'); 762 clickedThumb.nextAll(opt.tabButton).removeClass('list-active'); 763 764 if (opt.sliderTab) { 765 var slideIndex = clickedThumb.index(); 766 swiper.slideTo(slideIndex); 767 } 768 }); 769 770 // Handle swiper slide change event 771 if (opt.sliderTab) { 772 swiper.on("slideChange", function () { 773 var activeIndex = swiper.realIndex; 774 var $activeThumb = $thumbs.eq(activeIndex); 775 776 $activeThumb.addClass("active").siblings().removeClass("active"); 777 linePos($activeThumb, $container); 778 779 $activeThumb.prevAll(opt.tabButton).addClass('list-active'); 780 $activeThumb.nextAll(opt.tabButton).removeClass('list-active'); 781 }); 782 783 // Set the initial active thumb and line position 784 var initialSlideIndex = swiper.activeIndex; 785 var $initialThumb = $thumbs.eq(initialSlideIndex); 786 $initialThumb.addClass("active").siblings().removeClass("active"); 787 linePos($initialThumb, $container); 788 789 $initialThumb.prevAll(opt.tabButton).addClass('list-active'); 790 $initialThumb.nextAll(opt.tabButton).removeClass('list-active'); 791 } 792 793 // Function to set the position of the line indicator 794 function linePos($activeThumb) { 795 var thumbOffset = $activeThumb.position(); 796 var marginTop = parseInt($activeThumb.css('margin-top')) || 0; 797 var marginLeft = parseInt($activeThumb.css('margin-left')) || 0; 798 799 $line.css("--height-set", $activeThumb.outerHeight() + "px"); 800 $line.css("--width-set", $activeThumb.outerWidth() + "px"); 801 $line.css("--pos-y", thumbOffset.top + marginTop + "px"); 802 $line.css("--pos-x", thumbOffset.left + marginLeft + "px"); 803 } 804 }); 805 }; 806 807 808 if ($(".product-thumb").length) { 809 $(".product-thumb").activateSliderThumbs({ 810 sliderTab: true, 811 tabButton: ".tab-btn", 812 }); 813 } 814 815 if ($(".team-thumb").length) { 816 $(".team-thumb").activateSliderThumbs({ 817 sliderTab: true, 818 tabButton: ".tab-btn", 819 }); 820 } 821 822 if ($(".testi-thumb").length) { 823 $(".testi-thumb").activateSliderThumbs({ 824 sliderTab: true, 825 tabButton: ".tab-btn", 826 }); 827 } 828 if ($(".testi-thumb2").length) { 829 $(".testi-thumb2").activateSliderThumbs({ 830 sliderTab: true, 831 tabButton: ".tab-btn", 832 }); 833 } 834 835 // case-study active 836 var grid = $('.grid').isotope({ 837 itemSelector: '.grid-item', 838 percentPosition: true, 839 masonry: { 840 // use outer width of grid-sizer for columnWidth 841 columnWidth: '.grid-item' 842 } 843 }) 844 845 $('.case-menu').on('click', 'button', function () { 846 var filterValue = $(this).attr('data-filter'); 847 grid.isotope({ filter: filterValue }); 848 }); 849 850 //for portfolio menu active class 851 $('.portfolio-menu button').on('click', function (event) { 852 $(this).siblings('.active').removeClass('active'); 853 $(this).addClass('active'); 854 event.preventDefault(); 855 }); 856 857 $(".filter-active").imagesLoaded(function () { 858 var $filter = ".filter-active", 859 $filterItem = ".filter-item",
860 $filterMenu = ".filter-menu-active"; 861 862 if ($($filter).length > 0) { 863 var $grid = $($filter).isotope({ 864 itemSelector: $filterItem, 865 filter: "*", 866 masonry: { 867 // use outer width of grid-sizer for columnWidth 868 columnWidth: 1, 869 }, 870 }); 871 872 // filter items on button click 873 $($filterMenu).on("click", "button", function () { 874 var filterValue = $(this).attr("data-filter"); 875 $grid.isotope({ 876 filter: filterValue, 877 }); 878 }); 879 880 // Menu Active Class 881 $($filterMenu).on("click", "button", function (event) { 882 event.preventDefault(); 883 $(this).addClass("active"); 884 $(this).siblings(".active").removeClass("active"); 885 }); 886 } 887 }); 888 889 $(".masonary-active, .woocommerce-Reviews .comment-list").imagesLoaded(function () { 890 var $filter = ".masonary-active, .woocommerce-Reviews .comment-list", 891 $filterItem = ".filter-item, .woocommerce-Reviews .comment-list li"; 892 893 if ($($filter).length > 0) { 894 $($filter).isotope({ 895 itemSelector: $filterItem, 896 filter: "*", 897 masonry: { 898 // use outer width of grid-sizer for columnWidth 899 columnWidth: 1, 900 }, 901 }); 902 } 903 $('[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) { 904 $($filter).isotope({ 905 filter: "*", 906 }); 907 }); 908 }); 909 910 /*----------- 08. Ajax Contact Form ----------*/ 911 var form = ".ajax-contact"; 912 var invalidCls = "is-invalid"; 913 var $email = '[name="email"]'; 914 var $validation = 915 '[name="name"],[name="email"],[name="subject"],[name="number"],[name="message"]'; // Must be use (,) without any space 916 var formMessages = $(".form-messages"); 917 918 function sendContact() { 919 var formData = $(form).serialize(); 920 var valid; 921 valid = validateContact(); 922 if (valid) { 923 jQuery 924 .ajax({ 925 url: $(form).attr("action"), 926 data: formData, 927 type: "POST", 928 }) 929 .done(function (response) { 930 // Make sure that the formMessages div has the 'success' class. 931 formMessages.removeClass("error"); 932 formMessages.addClass("success"); 933 // Set the message text. 934 formMessages.text(response); 935 // Clear the form. 936 $( 937 form + 938 ' input:not([type="submit"]),' + 939 form + 940 " textarea" 941 ).val(""); 942 }) 943 .fail(function (data) { 944 // Make sure that the formMessages div has the 'error' class. 945 formMessages.removeClass("success"); 946 formMessages.addClass("error"); 947 // Set the message text. 948 if (data.responseText !== "") { 949 formMessages.html(data.responseText); 950 } else { 951 formMessages.html( 952 "Oops! An error occured and your message could not be sent." 953 ); 954 } 955 }); 956 } 957 } 958 959 function validateContact() { 960 var valid = true; 961 var formInput; 962 963 function unvalid($validation) { 964 $validation = $validation.split(","); 965 for (var i = 0; i < $validation.length; i++) { 966 formInput = form + " " + $validation[i]; 967 if (!$(formInput).val()) { 968 $(formInput).addClass(invalidCls); 969 valid = false; 970 } else { 971 $(formInput).removeClass(invalidCls); 972 valid = true; 973 } 974 } 975 } 976 unvalid($validation); 977 978 if ( 979 !$($email).val() || 980 !$($email) 981 .val() 982 .match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) 983 ) { 984 $($email).addClass(invalidCls); 985 valid = false;
986 } else { 987 $($email).removeClass(invalidCls); 988 valid = true; 989 } 990 return valid; 991 } 992 993 $(form).on("submit", function (element) { 994 element.preventDefault(); 995 sendContact(); 996 }); 997 998 /*---------- 09. Search Box Popup ----------*/ 999 function popupSarchBox($searchBox, $searchOpen, $searchCls, $toggleCls) { 1000 // Delegate events for opening the search box 1001 $(document).on("click", $searchOpen, function (e) { 1002 e.preventDefault(); 1003 $($searchBox).addClass($toggleCls); 1004 }); 1005 1006 // Delegate event for closing the search box when clicking outside 1007 $(document).on("click", function (e) { 1008 if (!$(e.target).closest($searchBox).length && !$(e.target).closest($searchOpen).length) { 1009 $($searchBox).removeClass($toggleCls); 1010 } 1011 }); 1012 1013 // Prevent the click inside the search box from closing it 1014 $(document).on("click", $searchBox + " form", function (e) { 1015 e.stopPropagation(); 1016 $($searchBox).addClass($toggleCls); 1017 }); 1018 1019 // Delegate event for closing the search box on clicking close button 1020 $(document).on("click", $searchCls, function (e) { 1021 e.preventDefault(); 1022 e.stopPropagation(); 1023 $($searchBox).removeClass($toggleCls); 1024 }); 1025 } 1026 1027 // Call function 1028 popupSarchBox(".popup-search-box", ".searchBoxToggler", ".searchClose", "show"); 1029 1030 1031 /*---------- 10. Popup Sidemenu ----------*/ 1032 function popupSideMenu($sideMenu, $sideMenuOpen, $sideMenuCls, $toggleCls) { 1033 // Delegate event for opening the side menu 1034 $(document).on('click', $sideMenuOpen, function (e) { 1035 e.preventDefault(); 1036 $($sideMenu).addClass($toggleCls); 1037 }); 1038 1039 // Delegate event for closing the side menu when clicking outside 1040 $(document).on('click', function (e) { 1041 if (!$(e.target).closest($sideMenu).length && !$(e.target).closest($sideMenuOpen).length) { 1042 $($sideMenu).removeClass($toggleCls); 1043 } 1044 }); 1045 1046 // Prevent closing side menu when clicking on side menu content 1047 $(document).on('click', $sideMenu + ' > div', function (e) { 1048 e.stopPropagation(); 1049 $($sideMenu).addClass($toggleCls); 1050 }); 1051 1052 // Delegate event for closing the side menu 1053 $(document).on('click', $sideMenuCls, function (e) { 1054 e.preventDefault(); 1055 e.stopPropagation(); 1056 $($sideMenu).removeClass($toggleCls); 1057 }); 1058 } 1059 1060 // Call the function for the sidemenu 1061 popupSideMenu('.sidemenu-wrapper', '.sideMenuToggler', '.sideMenuCls', 'show'); 1062 1063 1064 /*---------- 10. Popup Sidemenu ----------*/ 1065 function popupSideMenu($sideMenu2, $sideMunuOpen2, $sideMenuCls2, $toggleCls2) { 1066 // Sidebar Popup 1067 $($sideMunuOpen2).on('click', function (e) { 1068 e.preventDefault(); 1069 $($sideMenu2).addClass($toggleCls2); 1070 }); 1071 $($sideMenu2).on('click', function (e) { 1072 e.stopPropagation(); 1073 $($sideMenu2).removeClass($toggleCls2) 1074 }); 1075 var sideMenuChild = $sideMenu2 + ' > div'; 1076 $(sideMenuChild).on('click', function (e) { 1077 e.stopPropagation(); 1078 $($sideMenu2).addClass($toggleCls2) 1079 }); 1080 $($sideMenuCls2).on('click', function (e) { 1081 e.preventDefault(); 1082 e.stopPropagation(); 1083 $($sideMenu2).removeClass($toggleCls2); 1084 }); 1085 }; 1086 popupSideMenu('.shopping-cart', '.sideMenuToggler2', '.sideMenuCls', 'show'); 1087 1088 1089 /*----------- Pricing-switch & Tab ----------*/ 1090 $(document).ready(function () { 1091 var e = $("#filt-monthly"), 1092 d = $("#filt-yearly"), 1093 t = $("#switcher"), 1094 m = $("#monthly"), 1095 y = $("#yearly"); 1096 1097 if ($('.pricing-tabs').length) { 1098 // Using jQuery to bind click events to the elements 1099 e.on("click", function () { 1100 t.prop("checked", false); 1101 e.addClass("toggler--is-active"); 1102 d.removeClass("toggler--is-active"); 1103 m.removeClass("hide"); 1104 y.addClass("hide"); 1105 }); 1106 1107 d.on("click", function () { 1108 t.prop("checked", true); 1109 d.addClass("toggler--is-active"); 1110 e.removeClass("toggler--is-active"); 1111 m.addClass("hide"); 1112 y.removeClass("hide"); 1113 }); 1114 1115 t.on("click", function () { 1116 d.toggleClass("toggler--is-active"); 1117 e.toggleClass("toggler--is-active"); 1118 m.toggleClass("hide"); 1119 y.toggleClass("hide"); 1120 }); 1121 } 1122 }); 1123 1124 1125 /*----------- 11. Magnific Popup ----------*/ 1126 /* magnificPopup img view */ 1127 $(".popup-image").magnificPopup({ 1128 type: "image", 1129 mainClass: 'mfp-zoom-in', 1130 removalDelay: 260, 1131 gallery: { 1132 enabled: true, 1133 }, 1134 }); 1135 1136 /* magnificPopup video view */ 1137 $(".popup-video").magnificPopup({ 1138 type: "iframe", 1139 }); 1140 1141 /* magnificPopup video view */ 1142 $(".popup-content").magnificPopup({ 1143 type: "inline", 1144 midClick: true, 1145 }); 1146 1147 /* ================================================== 1148 # Wow Init 1149 ===============================================*/ 1150 var wow = new WOW({ 1151 boxClass: 'wow', 1152 animateClass: 'animated', 1153 offset: 0, 1154 mobile: true, 1155 live: true 1156 }); 1157 new WOW().init(); 1158 1159 1160 1161 1162 1163 1164 /* Image Reveal Animation */ 1165 if ($('.reveal').length) { 1166 gsap.registerPlugin(ScrollTrigger); 1167 let revealContainers = document.querySelectorAll(".reveal");
1168 revealContainers.forEach((container) => { 1169 let image = container.querySelector("img"); 1170 let tl = gsap.timeline({ 1171 scrollTrigger: { 1172 trigger: container, 1173 toggleActions: "play none none none" 1174 } 1175 }); 1176 tl.set(container, { 1177 autoAlpha: 1 1178 }); 1179 tl.from(container, 1, { 1180 xPercent: -100, 1181 ease: Power2.out 1182 }); 1183 1184 // Verificar se image existe antes de animar 1185 if (image) { 1186 tl.from(image, 1, { 1187 xPercent: 100, 1188 scale: 1, 1189 delay: -1, 1190 ease: Power2.out 1191 }); 1192 } 1193 }); 1194 } 1195 1196 1197 /* Text Effect Animation */ 1198 if ($('.text-anime-style-1').length) { 1199 let staggerAmount = 0.05, 1200 translateXValue = 0, 1201 delayValue = 0.5, 1202 animatedTextElements = document.querySelectorAll('.text-anime-style-1'); 1203 1204 animatedTextElements.forEach((element) => { 1205 let animationSplitText = new SplitText(element, { 1206 type: "chars, words" 1207 }); 1208 1209 // Verificar se animationSplitText.words existe e não está vazio 1210 if (animationSplitText && animationSplitText.words && animationSplitText.words.length > 0) { 1211 gsap.from(animationSplitText.words, { 1212 duration: 1, 1213 delay: delayValue, 1214 x: 20, 1215 autoAlpha: 0, 1216 stagger: staggerAmount, 1217 scrollTrigger: { 1218 trigger: element, 1219 start: "top 85%" 1220 }, 1221 }); 1222 } 1223 }); 1224 } 1225 1226 if ($('.text-anime-style-2').length) { 1227 let staggerAmount = 0.03, 1228 translateXValue = 20, 1229 delayValue = 0.1, 1230 easeType = "power2.out", 1231 animatedTextElements = document.querySelectorAll('.text-anime-style-2'); 1232 1233 animatedTextElements.forEach((element) => { 1234 let animationSplitText = new SplitText(element, { 1235 type: "chars, words" 1236 }); 1237 1238 // Verificar se animationSplitText.chars existe e não está vazio 1239 if (animationSplitText && animationSplitText.chars && animationSplitText.chars.length > 0) { 1240 gsap.from(animationSplitText.chars, { 1241 duration: 2, 1242 delay: delayValue, 1243 x: translateXValue, 1244 autoAlpha: 0, 1245 stagger: staggerAmount, 1246 ease: easeType, 1247 scrollTrigger: { 1248 trigger: element, 1249 start: "top 85%" 1250 }, 1251 }); 1252 } 1253 }); 1254 } 1255 1256 if ($('.text-anime-style-3').length) { 1257 let animatedTextElements = document.querySelectorAll('.text-anime-style-3'); 1258 1259 animatedTextElements.forEach((element) => { 1260 //Reset if needed 1261 if (element.animation) { 1262 element.animation.progress(1).kill(); 1263 element.split.revert(); 1264 } 1265 1266 element.split = new SplitText(element, { 1267 type: "lines,words,chars", 1268 linesClass: "split-line", 1269 }); 1270 1271 // Verificar se element.split.chars existe antes de usar 1272 if (element.split && element.split.chars && element.split.chars.length > 0) { 1273 gsap.set(element, { 1274 perspective: 400 1275 }); 1276 1277 gsap.set(element.split.chars, { 1278 opacity: 0, 1279 x: "50", 1280 }); 1281 1282 element.animation = gsap.to(element.split.chars, { 1283 scrollTrigger: { 1284 trigger: element, 1285 start: "top 90%" 1286 }, 1287 x: "0", 1288 y: "0", 1289 rotateX: "0", 1290 opacity: 1, 1291 duration: 1, 1292 ease: Back.easeOut, 1293 stagger: 0.02, 1294 }); 1295 } 1296 }); 1297 } 1298 1299 //Image Reveal Animation 1300 if ($('.th-anim').length) { 1301 gsap.registerPlugin(ScrollTrigger); 1302 let revealContainers = document.querySelectorAll(".th-anim");
1303 revealContainers.forEach((container) => { 1304 let image = container.querySelector("img"); 1305 let tl = gsap.timeline({ 1306 scrollTrigger: { 1307 trigger: container, 1308 toggleActions: "play none none none" 1309 } 1310 }); 1311 tl.set(container, { 1312 autoAlpha: 1 1313 }); 1314 tl.from(container, 1.5, { 1315 xPercent: -100, 1316 ease: Power2.out 1317 }); 1318 // Verificar se image existe antes de animar 1319 if (image) { 1320 tl.from(image, 1.5, { 1321 xPercent: 100, 1322 scale: 1.3, 1323 delay: -1.5, 1324 ease: Power2.out 1325 }); 1326 } 1327 }); 1328 } 1329 1330 // /*----------- Slider Drag Cursor ----------*/ 1331 const cursor = document.querySelector(".slider-drag-cursor"); 1332 1333 // Verificar se o cursor existe antes de usar 1334 if (cursor) { 1335 const pos = { x: window.innerWidth / 2, y: window.innerHeight / 2 }; 1336 const mouse = { x: pos.x, y: pos.y }; 1337 const speed = 1; 1338 1339 const xSet = gsap.quickSetter(cursor, "x", "px"); 1340 const ySet = gsap.quickSetter(cursor, "y", "px"); 1341 1342 window.addEventListener("pointermove", e => { 1343 mouse.x = e.x; 1344 mouse.y = e.y; 1345 }); 1346 1347 gsap.set(cursor, { xPercent: -50, yPercent: -50 }); 1348 1349 gsap.ticker.add(() => { 1350 const dt = 1.0 - Math.pow(1.0 - speed, gsap.ticker.deltaRatio()); 1351 pos.x += (mouse.x - pos.x) * dt; 1352 pos.y += (mouse.y - pos.y) * dt; 1353 xSet(pos.x); 1354 ySet(pos.y); 1355 }); 1356 } 1357 1358 // Use event delegation and .on() for better performance 1359 $(document).on("mouseenter", ".slider-drag-wrap", function () { 1360 $('.slider-drag-cursor').addClass('active'); 1361 }).on("mouseleave", ".slider-drag-wrap", function () { 1362 $('.slider-drag-cursor').removeClass('active'); 1363 }); 1364 1365 $(document).on("mouseenter", ".slider-drag-wrap a, .slider-drag-wrap .slider-pagination", function () { 1366 $('.slider-drag-cursor').removeClass('active'); 1367 }).on("mouseleave", ".slider-drag-wrap a, .slider-drag-wrap .slider-pagination", function () { 1368 $('.slider-drag-cursor').addClass('active'); 1369 }); 1370 1371 /* cursor area end */ 1372 1373 /*---------- 12. Section Position ----------*/ 1374 // Interger Converter 1375 function convertInteger(str) { 1376 return parseInt(str, 10); 1377 } 1378 1379 $.fn.sectionPosition = function (mainAttr, posAttr) { 1380 $(this).each(function () { 1381 var section = $(this); 1382 1383 function setPosition() { 1384 var sectionHeight = Math.floor(section.height() / 2), // Main Height of section 1385 posData = section.attr(mainAttr), // where to position 1386 posFor = section.attr(posAttr), // On Which section is for positioning 1387 topMark = "top-half", // Pos top 1388 bottomMark = "bottom-half", // Pos Bottom 1389 parentPT = convertInteger($(posFor).css("padding-top")), // Default Padding of parent 1390 parentPB = convertInteger($(posFor).css("padding-bottom")); // Default Padding of parent 1391 1392 if (posData === topMark) { 1393 $(posFor).css( 1394 "padding-bottom", 1395 parentPB + sectionHeight + "px" 1396 ); 1397 section.css("margin-top", "-" + sectionHeight + "px"); 1398 } else if (posData === bottomMark) { 1399 $(posFor).css( 1400 "padding-top", 1401 parentPT + sectionHeight + "px" 1402 ); 1403 section.css("margin-bottom", "-" + sectionHeight + "px"); 1404 } 1405 } 1406 setPosition(); // Set Padding On Load 1407 }); 1408 }; 1409 1410 var postionHandler = "[data-sec-pos]"; 1411 if ($(postionHandler).length) { 1412 $(postionHandler).imagesLoaded(function () { 1413 $(postionHandler).sectionPosition("data-sec-pos", "data-pos-for"); 1414 }); 1415 } 1416 1417 /*---------- 22. Circle Progress ----------*/ 1418 function animateElements() { 1419 $('.feature-circle .progressbar').each(function () { 1420 var pathColor = $(this).attr('data-path-color'); 1421 var elementPos = $(this).offset().top; 1422 var topOfWindow = $(window).scrollTop(); 1423 var percent = $(this).find('.circle').attr('data-percent'); 1424 var percentage = parseInt(percent, 10) / parseInt(100, 10); 1425 var animate = $(this).data('animate'); 1426 if (elementPos < topOfWindow + $(window).height() - 30 && !animate) { 1427 $(this).data('animate', true);
1428 $(this).find('.circle').circleProgress({ 1429 startAngle: -Math.PI / 2, 1430 value: percent / 100, 1431 size: 100, 1432 thickness: 8, 1433 emptyFill: "#E4E4E4", 1434 lineCap: 'round', 1435 fill: { 1436 color: pathColor, 1437 } 1438 }).on('circle-animation-progress', function (event, progress, stepValue) { 1439 $(this).find('.circle-num').text((stepValue * 100).toFixed(0) + "%"); 1440 }).stop(); 1441 } 1442 }); 1443 1444 $('.about-circle .progressbar').each(function () { 1445 var elementPos = $(this).offset().top; 1446 var topOfWindow = $(window).scrollTop(); 1447 var percent = $(this).find('.circle').attr('data-percent'); 1448 var percentage = parseInt(percent, 10) / parseInt(100, 10); 1449 var animate = $(this).data('animate'); 1450 if (elementPos < topOfWindow + $(window).height() - 30 && !animate) { 1451 $(this).data('animate', true); 1452 $(this).find('.circle').circleProgress({ 1453 startAngle: -Math.PI / 2, 1454 value: percent / 100, 1455 size: 160, 1456 thickness: 6, 1457 emptyFill: "#ffffff33", 1458 lineCap: 'round', 1459 fill: { 1460 gradient: ["#0B59DB", "#0B59DB"] 1461 } 1462 }).on('circle-animation-progress', function (event, progress, stepValue) { 1463 $(this).find('.circle-num').text((stepValue * 100).toFixed(0) + "%"); 1464 }).stop(); 1465 } 1466 }); 1467 } 1468 1469 1470 // Show animated elements 1471 animateElements(); 1472 $(window).scroll(animateElements); 1473 1474 /*----------- 15. Filter ----------*/ 1475 $(document).ready(function () { 1476 // Using imagesLoaded for proper filtering initialization 1477 $(".filter-active").imagesLoaded(function () { 1478 var $filter = $(".filter-active"), 1479 $filterItem = ".filter-item", 1480 $filterMenu = ".filter-menu-active"; 1481 1482 if ($filter.length > 0) { 1483 var $grid = $filter.isotope({ 1484 itemSelector: $filterItem, 1485 filter: "*", 1486 masonry: { 1487 columnWidth: 1, 1488 }, 1489 }); 1490 1491 // Filter items on button click using delegated event 1492 $($filterMenu).on("click", "button", function () { 1493 var filterValue = $(this).attr("data-filter"); 1494 $grid.isotope({ 1495 filter: filterValue, 1496 }); 1497 }); 1498 1499 // Menu Active Class management with event delegation 1500 $($filterMenu).on("click", "button", function (event) { 1501 event.preventDefault(); 1502 $(this).addClass("active").siblings(".active").removeClass("active"); 1503 }); 1504 } 1505 }); 1506 1507 // Initialize masonary grid with imagesLoaded for better performance 1508 $(".masonary-active").imagesLoaded(function () { 1509 var $filter = $(".masonary-active"), 1510 $filterItem = ".filter-item"; 1511 1512 if ($filter.length > 0) { 1513 $filter.isotope({ 1514 itemSelector: $filterItem, 1515 filter: "*", 1516 masonry: { 1517 columnWidth: 1, 1518 }, 1519 }); 1520 } 1521 }); 1522 1523 // Handling multiple grids with imagesLoaded for masonry and WooCommerce reviews 1524 $(".masonary-active, .woocommerce-Reviews .comment-list").imagesLoaded(function () { 1525 var $filter = $(".masonary-active, .woocommerce-Reviews .comment-list"), 1526 $filterItem = ".filter-item, .woocommerce-Reviews .comment-list li"; 1527 1528 if ($filter.length > 0) { 1529 $filter.isotope({ 1530 itemSelector: $filterItem, 1531 filter: "*", 1532 masonry: { 1533 columnWidth: 1, 1534 }, 1535 }); 1536 } 1537 1538 // Event binding for Bootstrap tab shown event 1539 $('[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) { 1540 $filter.isotope({ 1541 filter: "*", 1542 }); 1543 }); 1544 }); 1545 }); 1546 1547 1548 /*----------- 14. Counter Up ----------*/ 1549 $(".counter-number").counterUp({ 1550 delay: 10, 1551 time: 1000, 1552 }); 1553 1554 /*----------- 15. Shape Mockup ----------*/ 1555 $.fn.shapeMockup = function () { 1556 var $shape = $(this); 1557 $shape.each(function () { 1558 var $currentShape = $(this), 1559 shapeTop = $currentShape.data("top"), 1560 shapeRight = $currentShape.data("right"), 1561 shapeBottom = $currentShape.data("bottom"), 1562 shapeLeft = $currentShape.data("left"); 1563 $currentShape 1564 .css({ 1565 top: shapeTop, 1566 right: shapeRight, 1567 bottom: shapeBottom, 1568 left: shapeLeft, 1569 }) 1570 .removeAttr("data-top") 1571 .removeAttr("data-right") 1572 .removeAttr("data-bottom") 1573 .removeAttr("data-left") 1574 .parent() 1575 .addClass("shape-mockup-wrap"); 1576 }); 1577 }; 1578 1579 if ($(".shape-mockup")) { 1580 $(".shape-mockup").shapeMockup(); 1581 } 1582 1583 /*----------- 16. Progress Bar Animation ----------*/ 1584 $('.progress-bar').waypoint(function () {
1585 $('.progress-bar').css({ 1586 animation: "animate-positive 1.8s", 1587 opacity: "1" 1588 }); 1589 }, { 1590 offset: '75%' 1591 }); 1592 1593 /*----------- 17. Countdown ----------*/ 1594 1595 $.fn.countdown = function () { 1596 $(this).each(function () { 1597 var $counter = $(this), 1598 countDownDate = new Date($counter.data("offer-date")).getTime(), // Set the date we're counting down toz 1599 exprireCls = "expired"; 1600 1601 // Finding Function 1602 function s$(element) { 1603 return $counter.find(element); 1604 } 1605 1606 // Update the count down every 1 second 1607 var counter = setInterval(function () { 1608 // Get today's date and time 1609 var now = new Date().getTime(); 1610 1611 // Find the distance between now and the count down date 1612 var distance = countDownDate - now; 1613 1614 // Time calculations for days, hours, minutes and seconds 1615 var days = Math.floor(distance / (1000 * 60 * 60 * 24)); 1616 var hours = Math.floor( 1617 (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) 1618 ); 1619 var minutes = Math.floor( 1620 (distance % (1000 * 60 * 60)) / (1000 * 60) 1621 ); 1622 var seconds = Math.floor((distance % (1000 * 60)) / 1000); 1623 1624 // Check If value is lower than ten, so add zero before number 1625 days < 10 ? (days = "0" + days) : null; 1626 hours < 10 ? (hours = "0" + hours) : null; 1627 minutes < 10 ? (minutes = "0" + minutes) : null; 1628 seconds < 10 ? (seconds = "0" + seconds) : null; 1629 1630 // If the count down is over, write some text 1631 if (distance < 0) { 1632 clearInterval(counter); 1633 $counter.addClass(exprireCls); 1634 $counter.find(".message").css("display", "block"); 1635 } else { 1636 // Output the result in elements 1637 s$(".day").html(days); 1638 s$(".hour").html(hours); 1639 s$(".minute").html(minutes); 1640 s$(".seconds").html(seconds); 1641 } 1642 }, 1000); 1643 }); 1644 }; 1645 1646 if ($(".counter-list").length) { 1647 $(".counter-list").countdown(); 1648 } 1649 1650 /* ================================================== 1651# Load More 1652===============================================*/ 1653 1654 $(document).ready(function () { 1655 // Initially show the first 4 items 1656 $(".faq-area").slice(0, 4).show(); 1657 1658 // Use event delegation for better event handling on the #loadMore button 1659 $(document).on("click", "#loadMore", function (e) { 1660 e.preventDefault(); 1661 1662 // Show the next 3 hidden content elements 1663 $(".loadcontent:hidden").slice(0, 3).slideDown(); 1664 1665 // If there are no more hidden elements, update the button text 1666 if ($(".loadcontent:hidden").length === 0) { 1667 $("#loadMore").text("No Content").addClass("noContent").prop("disabled", true); // Optional: disable button when no content is left 1668 } 1669 }); 1670 }); 1671 1672 1673 /*----------- 21. Price Slider ----------*/ 1674 $(".price_slider").slider({ 1675 range: true, 1676 min: 0, 1677 max: 100, 1678 values: [0, 30], 1679 slide: function (event, ui) { 1680 $(".from").text("$" + ui.values[0]); 1681 $(".to").text("$" + ui.values[1]); 1682 } 1683 }); 1684 $(".from").text("$" + $(".price_slider").slider("values", 0)); 1685 $(".to").text("$" + $(".price_slider").slider("values", 1)); 1686 1687 1688 1689 /*---------- 18. Image to SVG Code ----------*/ 1690 const cache = {}; 1691 1692 $.fn.inlineSvg = function fnInlineSvg() { 1693 this.each(imgToSvg); 1694 1695 return this; 1696 }; 1697 1698 function imgToSvg() { 1699 const $img = $(this); 1700 const src = $img.attr("src"); 1701 1702 // fill cache by src with promise 1703 if (!cache[src]) { 1704 const d = $.Deferred(); 1705 $.get(src, (data) => { 1706 d.resolve($(data).find("svg")); 1707 }); 1708 cache[src] = d.promise(); 1709 } 1710 1711 // replace img with svg when cached promise resolves 1712 cache[src].then((svg) => { 1713 const $svg = $(svg).clone(); 1714 1715 if ($img.attr("id")) $svg.attr("id", $img.attr("id")); 1716 if ($img.attr("class")) $svg.attr("class", $img.attr("class")); 1717 if ($img.attr("style")) $svg.attr("style", $img.attr("style")); 1718 1719 if ($img.attr("width")) { 1720 $svg.attr("width", $img.attr("width")); 1721 if (!$img.attr("height")) $svg.removeAttr("height"); 1722 } 1723 if ($img.attr("height")) { 1724 $svg.attr("height", $img.attr("height")); 1725 if (!$img.attr("width")) $svg.removeAttr("width"); 1726 } 1727 1728 $svg.insertAfter($img); 1729 $img.trigger("svgInlined", $svg[0]); 1730 $img.remove(); 1731 }); 1732 } 1733 1734 $(".svg-img").inlineSvg(); 1735 1736 1737 //Image Reveal Animation 1738 if ($('.th-anim').length) { 1739 gsap.registerPlugin(ScrollTrigger); 1740 let revealContainers = document.querySelectorAll(".th-anim");
1741 revealContainers.forEach((container) => { 1742 let image = container.querySelector("img"); 1743 let tl = gsap.timeline({ 1744 scrollTrigger: { 1745 trigger: container, 1746 toggleActions: "play none none none" 1747 } 1748 }); 1749 tl.set(container, { 1750 autoAlpha: 1 1751 }); 1752 tl.from(container, 1.5, { 1753 xPercent: -100, 1754 ease: Power2.out 1755 }); 1756 // Verificar se image existe antes de animar 1757 if (image) { 1758 tl.from(image, 1.5, { 1759 xPercent: 100, 1760 scale: 1.3, 1761 delay: -1.5, 1762 ease: Power2.out 1763 }); 1764 } 1765 }); 1766 } 1767 1768 /************lettering js***********/ 1769 function injector(t, splitter, klass, after) { 1770 var a = t.text().split(splitter), 1771 inject = ''; 1772 if (a.length) { 1773 $(a).each(function (i, item) { 1774 inject += '<span class="' + klass + (i + 1) + '">' + item + '</span>' + after; 1775 }); 1776 t.empty().append(inject); 1777 } 1778 } 1779 1780 var methods = { 1781 init: function () { 1782 1783 return this.each(function () { 1784 injector($(this), '', 'char', ''); 1785 }); 1786 1787 }, 1788 1789 words: function () { 1790 1791 return this.each(function () { 1792 injector($(this), ' ', 'word', ' '); 1793 }); 1794 1795 }, 1796 1797 lines: function () { 1798 1799 return this.each(function () { 1800 var r = "eefec303079ad17405c889e092e105b0"; 1801 // Because it's hard to split a <br/> tag consistently across browsers, 1802 // (*ahem* IE *ahem*), we replaces all <br/> instances with an md5 hash 1803 // (of the word "split"). If you're trying to use this plugin on that 1804 // md5 hash string, it will fail because you're being ridiculous. 1805 injector($(this).children("br").replaceWith(r).end(), r, 'line', ''); 1806 }); 1807 1808 } 1809 }; 1810 1811 $.fn.lettering = function (method) { 1812 // Method calling logic 1813 if (method && methods[method]) { 1814 return methods[method].apply(this, [].slice.call(arguments, 1)); 1815 } else if (method === 'letters' || !method) { 1816 return methods.init.apply(this, [].slice.call(arguments, 0)); // always pass an array 1817 } 1818 $.error('Method ' + method + ' does not exist on jQuery.lettering'); 1819 return this; 1820 }; 1821 1822 $(".discount-anime").lettering(); 1823 1824 1825 /*----------- 00. Woocommerce Toggle ----------*/ 1826 // Ship To Different Address 1827 $(document).on("change", "#ship-to-different-address-checkbox", function () { 1828 if ($(this).is(":checked")) { 1829 $("#ship-to-different-address") 1830 .next(".shipping_address") 1831 .slideDown(); 1832 } else { 1833 $("#ship-to-different-address").next(".shipping_address").slideUp(); 1834 } 1835 }); 1836 1837 // Login Toggle 1838 $(document).on("click", ".woocommerce-form-login-toggle a", function (e) { 1839 e.preventDefault(); 1840 $(".woocommerce-form-login").slideToggle(); 1841 }); 1842 1843 // Coupon Toggle 1844 $(document).on("click", ".woocommerce-form-coupon-toggle a", function (e) { 1845 e.preventDefault(); 1846 $(".woocommerce-form-coupon").slideToggle(); 1847 }); 1848 1849 // Woocommerce Shipping Method 1850 $(document).on("click", ".shipping-calculator-button", function (e) { 1851 e.preventDefault(); 1852 $(this).next(".shipping-calculator-form").slideToggle(); 1853 }); 1854 1855 // Woocommerce Payment Toggle 1856 $(document).on("change", '.wc_payment_methods input[type="radio"]', function () { 1857 $(".payment_box").slideUp(); 1858 $(this).siblings(".payment_box").slideDown(); 1859 }); 1860 1861 // Woocommerce Rating Toggle 1862 $(document).on("click", ".rating-select .stars a", function (e) { 1863 e.preventDefault(); 1864 $(this).siblings().removeClass("active"); 1865 $(this).parent().parent().addClass("selected"); 1866 $(this).addClass("active"); 1867 }); 1868 1869 // Quantity Plus Minus --------------------------- 1870 $(document).on("click", ".quantity-plus", function (e) { 1871 e.preventDefault(); 1872 var $qty = $(this).siblings(".qty-input"); 1873 var currentVal = parseInt($qty.val(), 10); 1874 if (!isNaN(currentVal)) { 1875 $qty.val(currentVal + 1); 1876 } 1877 }); 1878 1879 $(document).on("click", ".quantity-minus", function (e) { 1880 e.preventDefault(); 1881 var $qty = $(this).siblings(".qty-input"); 1882 var currentVal = parseInt($qty.val(), 10); 1883 if (!isNaN(currentVal) && currentVal > 1) { 1884 $qty.val(currentVal - 1); 1885 } 1886 }); 1887 1888 // ---------- Smooth Scroll ---------- 1889 gsap.registerPlugin(ScrollTrigger); 1890 1891 let lenis;
1892 let gsapTickerAdded = false; 1893 1894 const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; 1895 1896 function initializeLenis() { 1897 lenis = new Lenis({ 1898 lerp: 0.07, // Smoothing factor 1899 }); 1900 1901 lenis.on("scroll", ScrollTrigger.update); 1902 1903 // Allow native scroll inside specified elements 1904 document.querySelectorAll(".allow-natural-scroll").forEach((el) => { 1905 el.addEventListener("wheel", (e) => e.stopPropagation(), { passive: true }); 1906 el.addEventListener("touchmove", (e) => e.stopPropagation(), { passive: true }); 1907 }); 1908 } 1909 1910 function enableOrDisableLenis() { 1911 if (prefersReducedMotion) return; 1912 1913 if (window.innerWidth > 991) { 1914 if (!lenis) { 1915 initializeLenis(); 1916 // Add GSAP ticker after Lenis is initialized (only once) 1917 if (!gsapTickerAdded) { 1918 gsap.ticker.add((time) => { 1919 if (lenis && lenis.raf) { 1920 lenis.raf(time * 1000); 1921 } 1922 }); 1923 gsapTickerAdded = true; 1924 } 1925 } 1926 lenis.start(); 1927 } else { 1928 if (lenis) { 1929 lenis.stop(); 1930 lenis = null; 1931 } 1932 } 1933 } 1934 1935 // Initial call 1936 enableOrDisableLenis(); 1937 window.addEventListener("resize", enableOrDisableLenis); 1938 1939 1940 /*----------- 00. Right Click Disable ----------*/ 1941 // window.addEventListener('contextmenu', function (e) { 1942 // // do something here... 1943 // e.preventDefault(); 1944 // }, false); 1945 1946 /*----------- 00. Inspect Element Disable ----------*/ 1947 // document.onkeydown = function (e) { 1948 // if (event.keyCode == 123) { 1949 // return false; 1950 // } 1951 // if (e.ctrlKey && e.shiftKey && e.keyCode == 'I'.charCodeAt(0)) { 1952 // return false; 1953 // } 1954 // if (e.ctrlKey && e.shiftKey && e.keyCode == 'C'.charCodeAt(0)) { 1955 // return false; 1956 // } 1957 // if (e.ctrlKey && e.shiftKey && e.keyCode == 'J'.charCodeAt(0)) { 1958 // return false; 1959 // } 1960 // if (e.ctrlKey && e.keyCode == 'U'.charCodeAt(0)) { 1961 // return false; 1962 // } 1963 // } 1964 1965})(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.