1function schon_content_load_scripts() { 2 var $ = jQuery; 3 "use strict"; 4 /*================================= 5 JS Index Here 6 ==================================*/ 7 /* 8 01. On Load Function 9 02. Preloader 10 03. Mobile Menu Active 11 04. Sticky fix 12 05. Scroll To Top 13 06. Set Background Image Color & Mask 14 07. Global Slider 15 08. Custom Animaiton For Slider 16 09. Ajax Contact Form 17 10. Search Box Popup 18 11. Popup Sidemenu 19 12. Magnific Popup 20 13. Section Position 21 14. Filter 22 15. Counter Up 23 16. AS Tab 24 17. Shape Mockup 25 18. Progress Bar Animation 26 19. Price Slider 27 21. Indicator 28 22. Circle Progress 29 00. Woocommerce Toggle 30 00. Right Click Disable 31 */ 32 /*================================= 33 JS Index End 34 ==================================*/ 35 /* 36 37 /*---------- 01. On Load Function ----------*/ 38 $(window).on("load", function () { 39 $(".preloader").fadeOut(); 40 }); 41 42 /*---------- 02. Preloader ----------*/ 43 if ($("#preloader").length) { 44 $("#preloader").delay(1600).fadeOut(); 45 setTimeout(function () { 46 $(".preloader-bg-one").css("transform", "translateY(-100%)"); 47 $(".preloader-bg-two").css("transform", "translateY(100%)"); 48 $(".txt-loading").css("opacity", 0); 49 }, 1000); 50 } 51 52 // ------------ Preloader ----------- 53 54 /** 55 * ====================================== 56 * 02. custom cursor 57 * ====================================== 58 */ 59 if ($(".mouseCursor").length > 0) { 60 function itCursor() { 61 var myCursor = jQuery(".mouseCursor"); 62 if (myCursor.length) { 63 if ($("body")) { 64 const e = document.querySelector(".cursor-inner"), 65 t = document.querySelector(".cursor-outer"); 66 let n, 67 i = 0, 68 o = !1; 69 (window.onmousemove = function (s) { 70 o || 71 (t.style.transform = 72 "translate(" + s.clientX + "px, " + s.clientY + "px)"), 73 (e.style.transform = 74 "translate(" + s.clientX + "px, " + s.clientY + "px)"), 75 (n = s.clientY), 76 (i = s.clientX); 77 }), 78 $("body").on( 79 "mouseenter", 80 "button:not(.not-cursor), a:not(.not-cursor), .cursor-pointer", 81 function () { 82 e.classList.add("cursor-hover"), 83 t.classList.add("cursor-hover"); 84 } 85 ), 86 $("body").on( 87 "mouseleave", 88 "button, a, .cursor-pointer", 89 function () { 90 ($(this).is("a", "button") && 91 $(this).closest(".cursor-pointer").length) || 92 (e.classList.remove("cursor-hover"), 93 t.classList.remove("cursor-hover")); 94 } 95 ), 96 (e.style.visibility = "visible"), 97 (t.style.visibility = "visible"); 98 99 // text view cursor 100 $("h1, h2, h3, h4, h5, h6, .cursor-lg").on( 101 "mouseenter", 102 function () { 103 $(".mouseCursor").addClass("cursor-big"); 104 } 105 ); 106 107 $("h1, h2, h3, h4, h5, h6, .cursor-lg").on( 108 "mouseleave", 109 function () { 110 $(".mouseCursor").removeClass("cursor-big"); 111 } 112 ); 113 114 // no cursor 115 $(".not-cursor").on("mouseenter", function () { 116 $(".mouseCursor").addClass("not-cursor-outer"); 117 }); 118 119 $(".not-cursor").on("mouseleave", function () { 120 $(".mouseCursor").removeClass("not-cursor-outer"); 121 }); 122 } 123 } 124 }
125 itCursor(); 126 } 127 128 129 // $('select').niceSelect(); 130 if ($('.nice-select').length) { 131 $('.nice-select').niceSelect(); 132 } 133 134 135 /*---------- 03. Mobile Menu Active ----------*/ 136 $.fn.thmobilemenu = function (options) { 137 var opt = $.extend({ 138 menuToggleBtn: ".th-menu-toggle", 139 bodyToggleClass: "th-body-visible", 140 subMenuClass: "th-submenu", 141 subMenuParent: "th-item-has-children", 142 subMenuParentToggle: "th-active", 143 meanExpandClass: "th-mean-expand", 144 appendElement: '<span class="th-mean-expand"></span>', 145 subMenuToggleClass: "th-open", 146 toggleSpeed: 400, 147 }, 148 options 149 ); 150 151 return this.each(function () { 152 var menu = $(this); // Select menu 153 154 // Menu Show & Hide 155 function menuToggle() { 156 menu.toggleClass(opt.bodyToggleClass); 157 158 // collapse submenu on menu hide or show 159 var subMenu = "." + opt.subMenuClass; 160 $(subMenu).each(function () { 161 if ($(this).hasClass(opt.subMenuToggleClass)) { 162 $(this).removeClass(opt.subMenuToggleClass); 163 $(this).css("display", "none"); 164 $(this).parent().removeClass(opt.subMenuParentToggle); 165 } 166 }); 167 } 168 169 // Class Set Up for every submenu 170 menu.find("li").each(function () { 171 var submenu = $(this).find("ul"); 172 submenu.addClass(opt.subMenuClass); 173 submenu.css("display", "none"); 174 submenu.parent().addClass(opt.subMenuParent); 175 submenu.prev("a").append(opt.appendElement); 176 submenu.next("a").append(opt.appendElement); 177 }); 178 179 // Toggle Submenu 180 function toggleDropDown($element) { 181 if ($($element).next("ul").length > 0) { 182 $($element).parent().toggleClass(opt.subMenuParentToggle); 183 $($element).next("ul").slideToggle(opt.toggleSpeed); 184 $($element).next("ul").toggleClass(opt.subMenuToggleClass); 185 } else if ($($element).prev("ul").length > 0) { 186 $($element).parent().toggleClass(opt.subMenuParentToggle); 187 $($element).prev("ul").slideToggle(opt.toggleSpeed); 188 $($element).prev("ul").toggleClass(opt.subMenuToggleClass); 189 } 190 } 191 192 // Submenu toggle Button 193 var expandToggler = "." + opt.meanExpandClass; 194 $(expandToggler).each(function () { 195 $(this).on("click", function (e) { 196 e.preventDefault(); 197 toggleDropDown($(this).parent()); 198 }); 199 }); 200 201 // Menu Show & Hide On Toggle Btn click 202 $(opt.menuToggleBtn).each(function () { 203 $(this).on("click", function () { 204 menuToggle(); 205 }); 206 }); 207 208 // Hide Menu On out side click 209 menu.on("click", function (e) { 210 e.stopPropagation(); 211 menuToggle(); 212 }); 213 214 // Stop Hide full menu on menu click 215 menu.find("div").on("click", function (e) { 216 e.stopPropagation(); 217 }); 218 }); 219 }; 220 221 $(".th-menu-wrapper").thmobilemenu(); 222 223 /*---------- 04. Sticky fix ----------*/ 224 $(window).scroll(function () { 225 var topPos = $(this).scrollTop(); 226 if (topPos > 500) { 227 $('.sticky-wrapper').addClass('sticky'); 228 } else { 229 $('.sticky-wrapper').removeClass('sticky') 230 } 231 }) 232 233 /*----------- 04.1. One Page Nav ----------*/ 234 function onePageNav(element) { 235 if ($(element).length > 0) { 236 $(element).each(function () { 237 var link = $(this).find('a'); 238 $(this).find(link).each(function () { 239 $(this).on('click', function () { 240 var target = $(this.getAttribute('href')); 241 if (target.length) { 242 event.preventDefault(); 243 $('html, body').stop().animate({ 244 scrollTop: target.offset().top - 10 245 }, 1000); 246 }; 247 248 }); 249 }); 250 }) 251 } 252 }; 253 onePageNav('.onepage-nav'); 254 onePageNav('.scroll-down'); 255 256 /*---------- 05. Scroll To Top ----------*/ 257 // progressAvtivation 258 if ($('.scroll-top').length) { 259 var scrollTopbtn = document.querySelector('.scroll-top'); 260 var offset = 50; 261 var duration = 750; 262 263 jQuery(window).on('scroll', function () { 264 if (jQuery(this).scrollTop() > offset) { 265 jQuery(scrollTopbtn).addClass('show'); 266 } else { 267 jQuery(scrollTopbtn).removeClass('show'); 268 } 269 }); 270 271 jQuery(scrollTopbtn).on('click', function (event) { 272 event.preventDefault(); 273 jQuery('html, body').animate({ 274 scrollTop: 0 275 }, duration); 276 return false; 277 }); 278 } 279 280
281 /*---------- 06. Set Background Image Color & Mask ----------*/ 282 if ($("[data-bg-src]").length > 0) { 283 $("[data-bg-src]").each(function () { 284 var src = $(this).attr("data-bg-src"); 285 $(this).css("background-image", "url(" + src + ")"); 286 $(this).removeAttr("data-bg-src").addClass("background-image"); 287 }); 288 } 289 290 if ($('[data-bg-color]').length > 0) { 291 $('[data-bg-color]').each(function () { 292 var color = $(this).attr('data-bg-color'); 293 $(this).css('background-color', color); 294 $(this).removeAttr('data-bg-color'); 295 }); 296 }; 297 298 $('[data-border]').each(function () { 299 var borderColor = $(this).data('border'); 300 $(this).css('--th-border-color', borderColor); 301 }); 302 303 if ($('[data-mask-src]').length > 0) { 304 $('[data-mask-src]').each(function () { 305 var mask = $(this).attr('data-mask-src'); 306 $(this).css({ 307 'mask-image': 'url(' + mask + ')', 308 '-webkit-mask-image': 'url(' + mask + ')' 309 }); 310 $(this).addClass('bg-mask'); 311 $(this).removeAttr('data-mask-src'); 312 }); 313 }; 314 315 316 317 /*----------- 07. Global Slider ----------*/ 318/* -------------------------------- 319 WebGL Distortion with Displacement Map 320-------------------------------- */ 321let scene, camera, renderer, material, uniforms; 322 323function initWebGL() { 324 const container = document.querySelector("#slider-webgl"); 325 if (!container) return; // Stop if container is missing 326 327 scene = new THREE.Scene(); 328 camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); 329 renderer = new THREE.WebGLRenderer({ alpha: true }); 330 renderer.setSize(window.innerWidth, window.innerHeight); 331 container.appendChild(renderer.domElement); 332 333 const slides = document.querySelectorAll(".swiper-slide"); 334 if (!slides.length) return; 335 336 const firstImage = slides[0].getAttribute("data-image") || ""; 337 338 const textureLoader = new THREE.TextureLoader(); 339 const dispMapSrc = container.dataset.disp || "../img/icon/line-shape1.svg/hero/pattan.png"; 340 const dispTexture = textureLoader.load(dispMapSrc); 341 342 uniforms = { 343 progress: { value: 0 }, 344 texture1: { value: textureLoader.load(firstImage) }, 345 texture2: { value: textureLoader.load(firstImage) }, 346 disp: { value: dispTexture }, 347 intensity: { value: 0.3 } 348 }; 349 350 material = new THREE.ShaderMaterial({ 351 uniforms, 352 vertexShader: ` 353 varying vec2 vUv; 354 void main() { 355 vUv = uv; 356 gl_Position = vec4(position, 1.0); 357 } 358 `, 359 fragmentShader: ` 360 varying vec2 vUv; 361 uniform sampler2D texture1; 362 uniform sampler2D texture2; 363 uniform sampler2D disp; 364 uniform float progress; 365 uniform float intensity; 366 367 void main() { 368 vec2 uv = vUv; 369 vec4 dispTex = texture2D(disp, uv); 370 vec2 distortedPosition = uv + (dispTex.rg * 2.0 - 1.0) * intensity * progress; 371 vec2 distortedPosition2 = uv - (dispTex.rg * 2.0 - 1.0) * intensity * (1.0 - progress); 372 vec4 _texture1 = texture2D(texture1, distortedPosition); 373 vec4 _texture2 = texture2D(texture2, distortedPosition2); 374 gl_FragColor = mix(_texture1, _texture2, progress); 375 } 376 `, 377 transparent: true 378 }); 379 380 const geometry = new THREE.PlaneBufferGeometry(2, 2); 381 const mesh = new THREE.Mesh(geometry, material); 382 scene.add(mesh); 383 384 animate(); 385} 386 387function animate() { 388 requestAnimationFrame(animate); 389 if (renderer && camera && scene) renderer.render(scene, camera); 390} 391 392function changeSlide(index) { 393 if (!uniforms) return; 394 395 const slides = document.querySelectorAll(".swiper-slide"); 396 if (!slides[index]) return; 397 398 const nextImage = slides[index].getAttribute("data-image"); 399 if (!nextImage) return; 400 401 const nextTexture = new THREE.TextureLoader().load(nextImage); 402 uniforms.texture2.value = nextTexture; 403 uniforms.progress.value = 0; 404 405 gsap.to(uniforms.progress, { 406 value: 1, 407 duration: 1.8, 408 ease: "power2.inOut", 409 onComplete: () => { 410 uniforms.texture1.value = nextTexture; 411 uniforms.progress.value = 0; 412 } 413 });
414} 415 416initWebGL(); 417 418/* -------------------------------- 419 Initialize .th-slider instances 420-------------------------------- */ 421$('.th-slider').each(function () { 422 const thSlider = $(this); 423 let settings = {}; 424 try { 425 settings = JSON.parse(thSlider.attr('data-slider-options') || '{}'); 426 } catch (e) { 427 console.warn('Invalid data-slider-options JSON', e); 428 } 429 430 const prevArrow = thSlider.find('.slider-prev').length ? thSlider.find('.slider-prev').get(0) : null; 431 const nextArrow = thSlider.find('.slider-next').length ? thSlider.find('.slider-next').get(0) : null; 432 433 const paginationExternel = thSlider.siblings('.slider-controller').find('.slider-pagination'); 434 const paginationEl = paginationExternel.length ? paginationExternel.get(0) : (thSlider.find('.slider-pagination').length ? thSlider.find('.slider-pagination').get(0) : undefined); 435 const paginationEl2 = paginationExternel.length ? paginationExternel.get(0) : thSlider.find('.slider-pagination2').get(0); 436 const paginationElN = thSlider.find('.slider-pagination.pagi-number'); 437 438 const paginationType = settings['paginationType'] || 'bullets'; 439 const autoplayCondition = settings['autoplay'] || { delay: 6000, disableOnInteraction: false }; 440 441 const sliderDefault = { 442 slidesPerView: 1, 443 spaceBetween: settings['spaceBetween'] || 24, 444 loop: settings['loop'] !== false, 445 speed: 1800, 446 autoplay: autoplayCondition, 447 navigation: { 448 nextEl: nextArrow, 449 prevEl: prevArrow 450 }, 451 pagination: { 452 el: paginationEl, 453 type: paginationType, 454 clickable: true, 455 renderBullet: function (index, className) { 456 const number = index + 1; 457 const formattedNumber = number < 10 ? '0' + number : number; 458 if (paginationElN.length) return `<span class="${className} number">${formattedNumber}</span>`; 459 return `<span class="${className}" aria-label="Go to Slide ${formattedNumber}"></span>`; 460 }, 461 formatFractionCurrent: number => (number < 10 ? '0' + number : number), 462 formatFractionTotal: number => (number < 10 ? '0' + number : number) 463 }, 464 on: { 465 init: function () { 466 if (paginationEl2) { 467 const totalSlides = this.slides.length; 468 $(paginationEl2).html('<span class="current-slide">01</span> <span class="total-slides">' + (totalSlides < 10 ? '0' + totalSlides : totalSlides) + '</span>'); 469 } 470 }, 471 slideChangeTransitionStart: function () { 472 if (typeof changeSlide === "function") changeSlide(this.realIndex); 473 474 if (paginationEl2) { 475 const activeIndex = this.realIndex + 1; 476 const totalSlides = this.slides.length; 477 $(paginationEl2).html( 478 `<span class="current-slide">${activeIndex < 10 ? '0' + activeIndex : activeIndex}</span> 479 <span class="total-slides">${totalSlides < 10 ? '0' + totalSlides : totalSlides}</span>` 480 ); 481 } 482 } 483 } 484 }; 485 486 const options = $.extend({}, sliderDefault, settings); 487 new Swiper(thSlider.get(0), options); 488 489 if ($('.slider-area').length > 0) { 490 $('.slider-area').closest(".container").parent().addClass("arrow-wrap"); 491 } 492}); 493 494 495 /* ------------------------------ 496 Wheel-like effect slider 497 -------------------------------- */ 498 const multiplier = { 499 translate: 0.1, 500 rotate: 0.01 501 }; 502 503 504 function calculateWheel() { 505 const slides = document.querySelectorAll('.swiper .single'); 506 slides.forEach((slide) => { 507 const rect = slide.getBoundingClientRect(); 508 const r = window.innerWidth * 0.5 - (rect.x + rect.width * 0.5); 509 let ty = Math.abs(r) * multiplier.translate - rect.width * multiplier.translate; 510 511 if (ty < 0) ty = 0; 512 513 const transformOrigin = r < 0 ? 'left top' : 'right top'; 514 slide.style.transform = `translate(0, ${ty}px) rotate(${-r * multiplier.rotate}deg)`; 515 slide.style.transformOrigin = transformOrigin; 516 }); 517 } 518 519 function raf() { 520 requestAnimationFrame(raf); 521 calculateWheel(); 522 } 523 raf(); 524 525 526 function animationProperties() { 527 $('[data-ani]').each(function () { 528 var animationName = $(this).data('ani'); 529 $(this).addClass(animationName); 530 }); 531 532 $('[data-ani-delay]').each(function () { 533 var delayTime = $(this).data('ani-delay'); 534 $(this).css('animation-delay', delayTime); 535 }); 536 } 537 animationProperties(); 538 539 // Add click event handlers for external slider arrows based on data attributes
540 $('[data-slider-prev], [data-slider-next]').on('click', function () { 541 var sliderSelector = $(this).data('slider-prev') || $(this).data('slider-next'); 542 var targetSlider = $(sliderSelector); 543 544 if (targetSlider.length) { 545 var swiper = targetSlider[0].swiper; 546 547 if (swiper) { 548 if ($(this).data('slider-prev')) { 549 swiper.slidePrev(); 550 } else { 551 swiper.slideNext(); 552 } 553 } 554 } 555 }); 556 557 558 559 /*----------- 21. image Slider ----------*/ 560 $("#slider").on("input change", (e) => { 561 const sliderPos = e.target.value; 562 $('.foreground-img').css('width', `${sliderPos}%`) 563 $('.slider-button').css('left', `calc(${sliderPos}% - 18px)`) 564 }); 565 566 $(document).on('mouseover', '.hover-item', function () { 567 $(this).addClass('item-active'); 568 $('.hover-item').removeClass('item-active'); 569 $(this).addClass('item-active'); 570 }); 571 /*-------------- 08. Slider Tab -------------*/ 572 $.fn.activateSliderThumbs = function (options) { 573 var opt = $.extend({ 574 sliderTab: false, 575 tabButton: ".tab-btn", 576 }, 577 options 578 ); 579 580 return this.each(function () { 581 var $container = $(this); 582 var $thumbs = $container.find(opt.tabButton); 583 var $line = $('<span class="indicator"></span>').appendTo($container); 584 585 var sliderSelector = $container.data("slider-tab"); 586 var $slider = $(sliderSelector); 587 588 var swiper = $slider[0].swiper; 589 590 $thumbs.on("click", function (e) { 591 e.preventDefault(); 592 var clickedThumb = $(this); 593 594 clickedThumb.addClass("active").siblings().removeClass("active"); 595 linePos(clickedThumb, $container); 596 597 if (opt.sliderTab) { 598 var slideIndex = clickedThumb.index(); 599 swiper.slideTo(slideIndex); 600 } 601 }); 602 603 if (opt.sliderTab) { 604 swiper.on("slideChange", function () { 605 var activeIndex = swiper.realIndex; 606 var $activeThumb = $thumbs.eq(activeIndex); 607 608 $activeThumb.addClass("active").siblings().removeClass("active"); 609 linePos($activeThumb, $container); 610 }); 611 612 var initialSlideIndex = swiper.activeIndex; 613 var $initialThumb = $thumbs.eq(initialSlideIndex); 614 $initialThumb.addClass("active").siblings().removeClass("active"); 615 linePos($initialThumb, $container); 616 } 617 618 function linePos($activeThumb) { 619 var thumbOffset = $activeThumb.position(); 620 621 var marginTop = parseInt($activeThumb.css('margin-top')) || 0; 622 var marginLeft = parseInt($activeThumb.css('margin-left')) || 0; 623 624 $line.css("--height-set", $activeThumb.outerHeight() + "px"); 625 $line.css("--width-set", $activeThumb.outerWidth() + "px"); 626 $line.css("--pos-y", thumbOffset.top + marginTop + "px"); 627 $line.css("--pos-x", thumbOffset.left + marginLeft + "px"); 628 } 629 }); 630 }; 631 632 if ($(".testi-thumb").length) { 633 $(".testi-thumb").activateSliderThumbs({ 634 sliderTab: true, 635 tabButton: ".tab-btn", 636 }); 637 } 638 // if ($(".hero-thumb").length) { 639 // $(".hero-thumb").activateSliderThumbs({ 640 // sliderTab: true, 641 // tabButton: ".tab-btn", 642 // }); 643 // } 644 645 if ($(".project-thumb").length) { 646 $(".project-thumb").activateSliderThumbs({ 647 sliderTab: true, 648 tabButton: ".tab-btn", 649 }); 650 } 651 652 653 /*----------- 09. Ajax Contact Form ----------*/ 654 var form = ".ajax-contact"; 655 var invalidCls = "is-invalid"; 656 var $email = '[name="email"]'; 657 var $validation = 658 '[name="name"],[name="email"],[name="subject"],[name="number"],[name="message"]'; // Must be use (,) without any space 659 var formMessages = $(".form-messages"); 660 661 function sendContact() { 662 var formData = $(form).serialize();
663 var valid; 664 valid = validateContact(); 665 if (valid) { 666 jQuery 667 .ajax({ 668 url: $(form).attr("action"), 669 data: formData, 670 type: "POST", 671 }) 672 .done(function (response) { 673 // Make sure that the formMessages div has the 'success' class. 674 formMessages.removeClass("error"); 675 formMessages.addClass("success"); 676 // Set the message text. 677 formMessages.text(response); 678 // Clear the form. 679 $( 680 form + 681 ' input:not([type="submit"]),' + 682 form + 683 " textarea" 684 ).val(""); 685 }) 686 .fail(function (data) { 687 // Make sure that the formMessages div has the 'error' class. 688 formMessages.removeClass("success"); 689 formMessages.addClass("error"); 690 // Set the message text. 691 if (data.responseText !== "") { 692 formMessages.html(data.responseText); 693 } else { 694 formMessages.html( 695 "Oops! An error occured and your message could not be sent." 696 ); 697 } 698 }); 699 } 700 } 701 702 function validateContact() { 703 var valid = true; 704 var formInput; 705 706 function unvalid($validation) { 707 $validation = $validation.split(","); 708 for (var i = 0; i < $validation.length; i++) { 709 formInput = form + " " + $validation[i]; 710 if (!$(formInput).val()) { 711 $(formInput).addClass(invalidCls); 712 valid = false; 713 } else { 714 $(formInput).removeClass(invalidCls); 715 valid = true; 716 } 717 } 718 } 719 unvalid($validation); 720 721 if ( 722 !$($email).val() || 723 !$($email) 724 .val() 725 .match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) 726 ) { 727 $($email).addClass(invalidCls); 728 valid = false; 729 } else { 730 $($email).removeClass(invalidCls); 731 valid = true; 732 } 733 return valid; 734 } 735 736 $(form).on("submit", function (element) { 737 element.preventDefault(); 738 sendContact(); 739 }); 740 741 /*---------- 10. Search Box Popup ----------*/ 742 function popupSarchBox($searchBox, $searchOpen, $searchCls, $toggleCls) { 743 $($searchOpen).on("click", function (e) { 744 e.preventDefault(); 745 $($searchBox).addClass($toggleCls); 746 }); 747 $($searchBox).on("click", function (e) { 748 e.stopPropagation(); 749 $($searchBox).removeClass($toggleCls); 750 }); 751 $($searchBox) 752 .find("form") 753 .on("click", function (e) { 754 e.stopPropagation(); 755 $($searchBox).addClass($toggleCls); 756 }); 757 $($searchCls).on("click", function (e) { 758 e.preventDefault(); 759 e.stopPropagation(); 760 $($searchBox).removeClass($toggleCls); 761 }); 762 } 763 popupSarchBox( 764 ".popup-search-box", 765 ".searchBoxToggler", 766 ".searchClose", 767 "show" 768 ); 769 770 /*---------- 11. Popup Sidemenu ----------*/ 771 function popupSideMenu($sideMenu, $sideMunuOpen, $sideMenuCls, $toggleCls) { 772 // Sidebar Popup 773 $($sideMunuOpen).on('click', function (e) { 774 e.preventDefault(); 775 $($sideMenu).addClass($toggleCls); 776 }); 777 $($sideMenu).on('click', function (e) { 778 e.stopPropagation(); 779 $($sideMenu).removeClass($toggleCls) 780 }); 781 var sideMenuChild = $sideMenu + ' > div'; 782 $(sideMenuChild).on('click', function (e) { 783 e.stopPropagation(); 784 $($sideMenu).addClass($toggleCls) 785 }); 786 $($sideMenuCls).on('click', function (e) { 787 e.preventDefault(); 788 e.stopPropagation(); 789 $($sideMenu).removeClass($toggleCls); 790 }); 791 }; 792 popupSideMenu('.sidemenu-wrapper', '.sideMenuToggler', '.sideMenuCls', 'show'); 793 /*---------- 12. Popup Sidemenu ----------*/ 794 function popupSideMenu($sideMenu2, $sideMunuOpen2, $sideMenuCls2, $toggleCls2) { 795 // Sidebar Popup 796 $($sideMunuOpen2).on('click', function (e) { 797 e.preventDefault(); 798 $($sideMenu2).addClass($toggleCls2); 799 }); 800 $($sideMenu2).on('click', function (e) { 801 e.stopPropagation(); 802 $($sideMenu2).removeClass($toggleCls2) 803 }); 804 var sideMenuChild = $sideMenu2 + ' > div'; 805 $(sideMenuChild).on('click', function (e) { 806 e.stopPropagation(); 807 $($sideMenu2).addClass($toggleCls2) 808 }); 809 $($sideMenuCls2).on('click', function (e) { 810 e.preventDefault(); 811 e.stopPropagation(); 812 $($sideMenu2).removeClass($toggleCls2); 813 }); 814 }; 815 popupSideMenu('.shopping-cart', '.sideMenuToggler2', '.sideMenuCls', 'show'); 816 817 /*----------- 12. Magnific Popup ----------*/ 818 /* magnificPopup img view */ 819 $(".th-popup-image").magnificPopup({ 820 type: "image", 821 mainClass: 'mfp-zoom-in', 822 removalDelay: 260, 823 gallery: { 824 enabled: true, 825 }, 826 });
827 828 /* magnificPopup video view */ 829 $(".popup-video").magnificPopup({ 830 type: "iframe", 831 mainClass: 'mfp-zoom-in', 832 removalDelay: 260, 833 }); 834 835 /* magnificPopup video view */ 836 $(".popup-content").magnificPopup({ 837 type: "inline", 838 midClick: true, 839 }); 840 841 842 if ($('[data-theme-color]').length > 0) { 843 $('[data-theme-color]').each(function () { 844 var $color = $(this).attr('data-theme-color'); 845 $(this).get(0).style.setProperty('--theme-color', $color); 846 $(this).removeAttr('data-theme-color'); 847 }); 848 }; 849 850 851 /************lettering js***********/ 852 function injector(t, splitter, klass, after) { 853 var a = t.text().split(splitter), 854 inject = ''; 855 if (a.length) { 856 $(a).each(function (i, item) { 857 inject += '<span class="' + klass + (i + 1) + '">' + item + '</span>' + after; 858 }); 859 t.empty().append(inject); 860 } 861 } 862 863 var methods = { 864 init: function () { 865 866 return this.each(function () { 867 injector($(this), '', 'char', ''); 868 }); 869 870 }, 871 872 words: function () { 873 874 return this.each(function () { 875 injector($(this), ' ', 'word', ' '); 876 }); 877 878 }, 879 880 lines: function () { 881 882 return this.each(function () { 883 var r = "eefec303079ad17405c889e092e105b0"; 884 // Because it's hard to split a <br/> tag consistently across browsers, 885 // (*ahem* IE *ahem*), we replaces all <br/> instances with an md5 hash 886 // (of the word "split"). If you're trying to use this plugin on that 887 // md5 hash string, it will fail because you're being ridiculous. 888 injector($(this).children("br").replaceWith(r).end(), r, 'line', ''); 889 }); 890 891 } 892 }; 893 894 $.fn.lettering = function (method) { 895 // Method calling logic 896 if (method && methods[method]) { 897 return methods[method].apply(this, [].slice.call(arguments, 1)); 898 } else if (method === 'letters' || !method) { 899 return methods.init.apply(this, [].slice.call(arguments, 0)); // always pass an array 900 } 901 $.error('Method ' + method + ' does not exist on jQuery.lettering'); 902 return this; 903 }; 904 905 $(".discount-anime").lettering(); 906 907 908 /*---------- 13. Section Position ----------*/ 909 // Interger Converter 910 function convertInteger(str) { 911 return parseInt(str, 10); 912 } 913 914 $.fn.sectionPosition = function (mainAttr, posAttr) { 915 $(this).each(function () { 916 var section = $(this); 917 918 function setPosition() { 919 var sectionHeight = Math.floor(section.height() / 2), // Main Height of section 920 posData = section.attr(mainAttr), // where to position 921 posFor = section.attr(posAttr), // On Which section is for positioning 922 topMark = "top-half", // Pos top 923 bottomMark = "bottom-half", // Pos Bottom 924 parentPT = convertInteger($(posFor).css("padding-top")), // Default Padding of parent 925 parentPB = convertInteger($(posFor).css("padding-bottom")); // Default Padding of parent 926 927 if (posData === topMark) { 928 $(posFor).css( 929 "padding-bottom", 930 parentPB + sectionHeight + "px" 931 ); 932 section.css("margin-top", "-" + sectionHeight + "px"); 933 } else if (posData === bottomMark) { 934 $(posFor).css( 935 "padding-top", 936 parentPT + sectionHeight + "px" 937 ); 938 section.css("margin-bottom", "-" + sectionHeight + "px"); 939 } 940 } 941 setPosition(); // Set Padding On Load 942 }); 943 }; 944 945 var postionHandler = "[data-sec-pos]"; 946 if ($(postionHandler).length) { 947 $(postionHandler).imagesLoaded(function () { 948 $(postionHandler).sectionPosition("data-sec-pos", "data-pos-for"); 949 }); 950 } 951 952 /*----------- 15. Filter ----------*/ 953 $(".filter-active").imagesLoaded(function () { 954 var $filter = ".filter-active", 955 $filterItem = ".filter-item",
956 $filterMenu = ".filter-menu-active"; 957 958 if ($($filter).length > 0) { 959 var $grid = $($filter).isotope({ 960 itemSelector: $filterItem, 961 filter: "*", 962 masonry: { 963 // use outer width of grid-sizer for columnWidth 964 columnWidth: 1, 965 }, 966 }); 967 968 // filter items on button click 969 $($filterMenu).on("click", "button", function () { 970 var filterValue = $(this).attr("data-filter"); 971 $grid.isotope({ 972 filter: filterValue, 973 }); 974 }); 975 976 // Menu Active Class 977 $($filterMenu).on("click", "button", function (event) { 978 event.preventDefault(); 979 $(this).addClass("active"); 980 $(this).siblings(".active").removeClass("active"); 981 }); 982 } 983 $('.load-more-btn').on('click', function () { 984 var $icon = $(this).find('i'); 985 $icon.addClass('fa-spin-pulse'); 986 987 setTimeout(function () { 988 $icon.removeClass('fa-spin-pulse'); 989 }, 1000); 990 991 var $button = $(this); 992 setTimeout(function () { 993 var $closestLoadMoreActive = $button.prev('.load-more-active'); 994 if ($closestLoadMoreActive.length === 0) { 995 $closestLoadMoreActive = $button.closest('.container').find('.load-more-active'); 996 } 997 $closestLoadMoreActive.find('.load-more.d-none, .accordion-card.style2.d-none, .filter-item.d-none').removeClass('d-none'); 998 999 var $grid = $($filter).isotope({ 1000 filter: "*", 1001 }); 1002 }, 700); 1003 }); 1004 }); 1005 1006 1007 $(".masonary-active").imagesLoaded(function () { 1008 var $filter = ".masonary-active", 1009 $filterItem = ".filter-item"; 1010 1011 if ($($filter).length > 0) { 1012 $($filter).isotope({ 1013 itemSelector: $filterItem, 1014 filter: "*", 1015 masonry: { 1016 // use outer width of grid-sizer for columnWidth 1017 columnWidth: 1, 1018 }, 1019 }); 1020 } 1021 }); 1022 1023 $(".masonary-active, .woocommerce-Reviews .comment-list").imagesLoaded(function () { 1024 var $filter = ".masonary-active, .woocommerce-Reviews .comment-list", 1025 $filterItem = ".filter-item, .woocommerce-Reviews .comment-list li"; 1026 1027 if ($($filter).length > 0) { 1028 $($filter).isotope({ 1029 itemSelector: $filterItem, 1030 filter: "*", 1031 masonry: { 1032 // use outer width of grid-sizer for columnWidth 1033 columnWidth: 1, 1034 }, 1035 }); 1036 } 1037 $('[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) { 1038 $($filter).isotope({ 1039 filter: "*", 1040 }); 1041 }); 1042 }); 1043 1044 /*----------- 15. Counter Up ----------*/ 1045 $(".counter-number").counterUp({ 1046 delay: 10, 1047 time: 1000, 1048 }); 1049 1050 /*----------- 17. Shape Mockup ----------*/ 1051 $.fn.shapeMockup = function () { 1052 var $shape = $(this); 1053 $shape.each(function () { 1054 var $currentShape = $(this), 1055 shapeTop = $currentShape.data("top"), 1056 shapeRight = $currentShape.data("right"), 1057 shapeBottom = $currentShape.data("bottom"), 1058 shapeLeft = $currentShape.data("left"); 1059 $currentShape 1060 .css({ 1061 top: shapeTop, 1062 right: shapeRight, 1063 bottom: shapeBottom, 1064 left: shapeLeft, 1065 }) 1066 .removeAttr("data-top") 1067 .removeAttr("data-right") 1068 .removeAttr("data-bottom") 1069 .removeAttr("data-left") 1070 .parent() 1071 .addClass("shape-mockup-wrap"); 1072 }); 1073 }; 1074 1075 if ($(".shape-mockup")) { 1076 $(".shape-mockup").shapeMockup(); 1077 } 1078 1079 1080 /*----------- 16. Shape Mockup ----------*/ 1081 $.fn.shapeMockup2 = function () { 1082 var $shape = $(this); 1083 $shape.each(function () { 1084 var $currentShape = $(this), 1085 shapeTop = $currentShape.data("top"), 1086 shapeRight = $currentShape.data("right"), 1087 shapeBottom = $currentShape.data("bottom"), 1088 shapeLeft = $currentShape.data("left"); 1089 $currentShape 1090 .css({ 1091 top: shapeTop, 1092 right: shapeRight, 1093 bottom: shapeBottom, 1094 left: shapeLeft, 1095 }) 1096 .removeAttr("data-top") 1097 .removeAttr("data-right") 1098 .removeAttr("data-bottom") 1099 .removeAttr("data-left") 1100 .parent() 1101 .addClass("shape-mockup-wrap2"); 1102 }); 1103 }; 1104 1105 if ($(".shape-mockup2")) { 1106 $(".shape-mockup2").shapeMockup2(); 1107 } 1108 1109 1110 1111 1112 /*----------- 16. Progress Bar Animation ----------*/ 1113 $('.progress-bar').waypoint(function () {
1114 $('.progress-bar').css({ 1115 animation: "animate-positive 1.8s", 1116 opacity: "1" 1117 }); 1118 }, { 1119 offset: '75%' 1120 }); 1121 1122 1123 1124 /* footer animation */ 1125 document.addEventListener("DOMContentLoaded", function () { 1126 const target = document.querySelector(".th-screen"); 1127 1128 if (target) { 1129 const observer = new IntersectionObserver( 1130 (entries) => { 1131 entries.forEach((entry) => { 1132 if (entry.isIntersecting) { 1133 target.classList.add("th-visible"); 1134 } else { 1135 target.classList.remove("th-visible"); 1136 } 1137 }); 1138 }, { 1139 root: null, // viewport 1140 threshold: 0.2, // à¦à¦®à¦ªà¦à§à¦·à§ 20% element viewport-ঠà¦à¦²à§ trigger হবৠ1141 } 1142 ); 1143 1144 observer.observe(target); 1145 } 1146 }); 1147 1148 1149 1150 /*----------- 00. Woocommerce Toggle ----------*/ 1151 // Ship To Different Address 1152 $("#ship-to-different-address-checkbox").on("change", function () { 1153 if ($(this).is(":checked")) { 1154 $("#ship-to-different-address") 1155 .next(".shipping_address") 1156 .slideDown(); 1157 } else { 1158 $("#ship-to-different-address").next(".shipping_address").slideUp(); 1159 } 1160 }); 1161 1162 // Login Toggle 1163 $(".woocommerce-form-login-toggle a").on("click", function (e) { 1164 e.preventDefault(); 1165 $(".woocommerce-form-login").slideToggle(); 1166 }); 1167 1168 // Coupon Toggle 1169 $(".woocommerce-form-coupon-toggle a").on("click", function (e) { 1170 e.preventDefault(); 1171 $(".woocommerce-form-coupon").slideToggle(); 1172 }); 1173 1174 // Woocommerce Shipping Method 1175 $(".shipping-calculator-button").on("click", function (e) { 1176 e.preventDefault(); 1177 $(this).next(".shipping-calculator-form").slideToggle(); 1178 }); 1179 1180 // Woocommerce Payment Toggle 1181 $('.wc_payment_methods input[type="radio"]:checked') 1182 .siblings(".payment_box") 1183 .show(); 1184 $('.wc_payment_methods input[type="radio"]').each(function () { 1185 $(this).on("change", function () { 1186 $(".payment_box").slideUp(); 1187 $(this).siblings(".payment_box").slideDown(); 1188 }); 1189 }); 1190 1191 // Woocommerce Rating Toggle 1192 $(".rating-select .stars a").each(function () { 1193 $(this).on("click", function (e) { 1194 e.preventDefault(); 1195 $(this).siblings().removeClass("active"); 1196 $(this).parent().parent().addClass("selected"); 1197 $(this).addClass("active"); 1198 }); 1199 }); 1200 1201 // Quantity Plus Minus --------------------------- 1202 1203 $(".quantity-plus").each(function () { 1204 $(this).on("click", function (e) { 1205 e.preventDefault(); 1206 var $qty = $(this).siblings(".qty-input"); 1207 var currentVal = parseInt($qty.val(), 10); 1208 if (!isNaN(currentVal)) { 1209 $qty.val(currentVal + 1); 1210 } 1211 }); 1212 }); 1213 1214 $(".quantity-minus").each(function () { 1215 $(this).on("click", function (e) { 1216 e.preventDefault(); 1217 var $qty = $(this).siblings(".qty-input"); 1218 var currentVal = parseInt($qty.val(), 10); 1219 if (!isNaN(currentVal) && currentVal > 1) { 1220 $qty.val(currentVal - 1); 1221 } 1222 }); 1223 }); 1224 1225 // /*----------- 00.Color Scheme ----------*/ 1226 $('.color-switch-btns button').each(function () { 1227 // Get color for button 1228 const button = $(this); 1229 const color = button.data('color'); 1230 button.css('--theme-color', color); 1231 1232 // Change theme color on click 1233 button.on('click', function () { 1234 const clickedColor = $(this).data('color'); 1235 $('body').css('--theme-color', clickedColor); 1236 }); 1237 }); 1238 if ($('[theme-color]').length > 0) { 1239 $('[theme-color]').each(function () { 1240 var $color = $(this).attr('theme-color'); 1241 $(this).get(0).style.setProperty('--theme-color', $color); 1242 $(this).removeAttr('theme-color'); 1243 }); 1244 }; 1245 if ($('[title-color]').length > 0) { 1246 $('[title-color]').each(function () { 1247 var $color = $(this).attr('title-color'); 1248 $(this).get(0).style.setProperty('--title-color', $color); 1249 $(this).removeAttr('title-color'); 1250 }); 1251 }; 1252 1253 $(document).on('click', '.switchIcon', function () { 1254 $('.color-scheme-wrap').toggleClass('active'); 1255 });
1256 1257 // /*----------- Pricing-switch & Tab ----------*/ 1258 var e = document.getElementById("filt-monthly"), 1259 d = document.getElementById("filt-yearly"), 1260 t = document.getElementById("switcher"), 1261 m = document.getElementById("monthly"), 1262 y = document.getElementById("yearly"); 1263 1264 1265 if ($('.pricing-tabs').length) { 1266 e.addEventListener("click", function () { 1267 t.checked = false; 1268 e.classList.add("toggler--is-active"); 1269 d.classList.remove("toggler--is-active"); 1270 m.classList.remove("hide"); 1271 y.classList.add("hide"); 1272 }); 1273 1274 d.addEventListener("click", function () { 1275 t.checked = true; 1276 d.classList.add("toggler--is-active"); 1277 e.classList.remove("toggler--is-active"); 1278 m.classList.add("hide"); 1279 y.classList.remove("hide"); 1280 }); 1281 1282 t.addEventListener("click", function () { 1283 d.classList.toggle("toggler--is-active"); 1284 e.classList.toggle("toggler--is-active"); 1285 m.classList.toggle("hide"); 1286 y.classList.toggle("hide"); 1287 }); 1288 } 1289 1290 window.addEventListener("load", function () { 1291 if ($('.circle-text').length > 0) { 1292 const degreeToRadian = (angle) => angle * (Math.PI / 180); 1293 1294 // ellipse.png image width detect 1295 let ellipseImg = document.getElementById("ellipse-shape"); 1296 let imgWidth = ellipseImg.offsetWidth; 1297 1298 // radius auto set = (image width / 2) - padding 1299 let radius = (imgWidth / 1) - 0; 1300 let diameter = radius * 2; 1301 1302 let circle = document.querySelector(".circle-text"); 1303 circle.style.width = `${diameter}px`; 1304 circle.style.height = `${diameter}px`; 1305 1306 let text = circle.dataset.text; 1307 let characters = text.split(""); 1308 1309 let deltaAngle = 360 / characters.length; 1310 let currentAngle = -90; 1311 1312 characters.forEach((character, index) => { 1313 let span = document.createElement("span"); 1314 span.innerText = character; 1315 1316 let xPos = radius * (1 + Math.cos(degreeToRadian(currentAngle))); 1317 let yPos = radius * (1 + Math.sin(degreeToRadian(currentAngle))); 1318 1319 let transform = `translate(${xPos}px, ${yPos}px) rotate(${currentAngle + 90}deg)`; 1320 span.style.transform = transform; 1321 1322 currentAngle += deltaAngle; 1323 circle.appendChild(span); 1324 }); 1325 } 1326 }); 1327 1328 1329 /* ================================================== 1330 # Wow Init 1331 ===============================================*/ 1332 var wow = new WOW({ 1333 boxClass: 'wow', 1334 animateClass: 'animated', 1335 offset: 0, 1336 mobile: true, 1337 live: true 1338 }); 1339 new WOW().init(); 1340 1341 1342 1343 1344 1345 // scale animation 1346 var scale = document.querySelectorAll(".scale"); 1347 var image = document.querySelectorAll(".scale img"); 1348 scale.forEach((item) => { 1349 gsap.to(item, { 1350 scale: 1, 1351 duration: 1, 1352 ease: "power1.out", 1353 scrollTrigger: { 1354 trigger: item, 1355 start: 'top bottom', 1356 end: "bottom top", 1357 toggleActions: 'play reverse play reverse' 1358 } 1359 }); 1360 }); 1361 image.forEach((image) => { 1362 gsap.set(image, { 1363 scale: 1.3, 1364 }); 1365 gsap.to(image, { 1366 scale: 1, 1367 duration: 1, 1368 scrollTrigger: { 1369 trigger: image, 1370 start: 'top bottom', 1371 end: "bottom top", 1372 toggleActions: 'play reverse play reverse' 1373 } 1374 }); 1375 }) 1376 1377 1378 /* gallery section area start */ 1379 // =============================== 1380 // 3D Gallery Scroll Animation 1381 // =============================== 1382 1383 if ($(".gallery-grid-row").length > 0) { 1384 const $galleryContainer = $(".gallery-grid-row"); 1385 const $galleryItems = $galleryContainer.find(".gallery-card"); 1386 1387 // Grid setup (default 4x3, if 'l' then 3x4) 1388 let gridLayout = [4, 3]; 1389 if (typeof l !== "undefined" && l) { 1390 gridLayout = [3, 4]; 1391 } 1392 1393 // Helper function to generate random transforms 1394 function b(xRange = 0, yRange = 0, zRange = 0) { 1395 return { 1396 x: xRange ? gsap.utils.random(-xRange, xRange) : 0, 1397 y: yRange ? gsap.utils.random(-yRange, yRange) : 0, 1398 z: zRange ? gsap.utils.random(-zRange, zRange) : 0, 1399 rotateX: gsap.utils.random(-20, 20), 1400 rotateY: gsap.utils.random(-20, 20) 1401 }; 1402 } 1403 1404 if (window.innerWidth > 768) { 1405 // Add perspective to container 1406 gsap.set($galleryContainer[0], { 1407 perspective: 1312 1408 }); 1409 1410 const tl = gsap.timeline({ 1411 defaults: { 1412 ease: "power4.out" 1413 }, 1414 scrollTrigger: { 1415 trigger: $galleryContainer[0], 1416 start: "top 80%", 1417 end: "bottom 20%", 1418 scrub: 0.5 1419 } 1420 }); 1421 1422 // Animate gallery items from random position & rotation to normal 1423 tl.fromTo( 1424 $galleryItems.toArray(), { 1425 x: i => { 1426 const t = b(200, 200, 0); 1427 return t.x; 1428 }, 1429 y: i => { 1430 const t = b(200, 200, 0); 1431 return t.y; 1432 }, 1433 rotateX: i => { 1434 const t = b(); 1435 return t.rotateX; 1436 }, 1437 rotateY: i => { 1438 const t = b(); 1439 return t.rotateY; 1440 }, 1441 autoAlpha: 0, 1442 scale: 0.5 1443 }, { 1444 x: 0, 1445 y: 0, 1446 rotateX: 0, 1447 rotateY: 0, 1448 autoAlpha: 1, 1449 scale: 1, 1450 stagger: { 1451 amount: 0.3, 1452 from: "center", 1453 grid: gridLayout 1454 } 1455 } 1456 ); 1457 1458 } else { 1459 // Small devices: show static grid without animation 1460 gsap.set($galleryItems.toArray(), { 1461 clearProps: "all", 1462 autoAlpha: 1, 1463 scale: 1, 1464 x: 0, 1465 y: 0, 1466 rotateX: 0, 1467 rotateY: 0 1468 }); 1469 } 1470 } 1471 1472 1473 /* gallery section area end */ 1474 1475 1476 /* gallery section area end */ 1477 1478 /* accordion-card */ 1479 document.addEventListener("DOMContentLoaded", function () { 1480 document.querySelectorAll(".accordion-card").forEach(card => { 1481 const boxImg = card.querySelector(".box-img"); 1482 const collapse = card.querySelector(".accordion-collapse"); 1483 1484 if (collapse && boxImg) {
1485 // Accordion open হলৠ1486 collapse.addEventListener("show.bs.collapse", () => { 1487 boxImg.style.display = "none"; 1488 }); 1489 1490 // Accordion close হলৠ1491 collapse.addEventListener("hide.bs.collapse", () => { 1492 boxImg.style.display = "block"; 1493 }); 1494 } 1495 }); 1496 }); 1497 1498 1499 1500 /* Image Reveal Animation */ 1501 if ($('.reveal').length) { 1502 gsap.registerPlugin(ScrollTrigger); 1503 let revealContainers = document.querySelectorAll(".reveal"); 1504 revealContainers.forEach((container) => { 1505 let image = container.querySelector("img"); 1506 let tl = gsap.timeline({ 1507 scrollTrigger: { 1508 trigger: container, 1509 toggleActions: "play none none none" 1510 } 1511 }); 1512 tl.set(container, { 1513 autoAlpha: 1 1514 }); 1515 tl.from(container, 1, { 1516 xPercent: -100, 1517 ease: Power2.out 1518 }); 1519 tl.from(image, 1, { 1520 xPercent: 100, 1521 scale: 1, 1522 delay: -1, 1523 ease: Power2.out 1524 }); 1525 }); 1526 } 1527 1528 /* Text Effect Animation */ 1529 if ($('.text-anime-style-1').length) { 1530 let staggerAmount = 0.05, 1531 translateXValue = 0, 1532 delayValue = 0.5, 1533 animatedTextElements = document.querySelectorAll('.text-anime-style-1'); 1534 1535 animatedTextElements.forEach((element) => { 1536 let animationSplitText = new SplitText(element, { 1537 type: "chars, words" 1538 }); 1539 gsap.from(animationSplitText.words, { 1540 duration: 1, 1541 delay: delayValue, 1542 x: 20, 1543 autoAlpha: 0, 1544 stagger: staggerAmount, 1545 scrollTrigger: { 1546 trigger: element, 1547 start: "top 85%" 1548 }, 1549 }); 1550 }); 1551 } 1552 1553 if ($('.text-anime-style-2').length) { 1554 let staggerAmount = 0.03, 1555 translateXValue = 20, 1556 delayValue = 0.1, 1557 easeType = "power2.out", 1558 animatedTextElements = document.querySelectorAll('.text-anime-style-2'); 1559 1560 animatedTextElements.forEach((element) => { 1561 let animationSplitText = new SplitText(element, { 1562 type: "chars, words" 1563 }); 1564 gsap.from(animationSplitText.chars, { 1565 duration: 2, 1566 delay: delayValue, 1567 x: translateXValue, 1568 autoAlpha: 0, 1569 stagger: staggerAmount, 1570 ease: easeType, 1571 scrollTrigger: { 1572 trigger: element, 1573 start: "top 85%" 1574 }, 1575 }); 1576 }); 1577 } 1578 1579 if ($('.text-anime-style-3').length) { 1580 let animatedTextElements = document.querySelectorAll('.text-anime-style-3'); 1581 1582 animatedTextElements.forEach((element) => { 1583 //Reset if needed 1584 if (element.animation) { 1585 element.animation.progress(1).kill(); 1586 element.split.revert(); 1587 } 1588 1589 element.split = new SplitText(element, { 1590 type: "lines,words,chars", 1591 linesClass: "split-line", 1592 }); 1593 gsap.set(element, { 1594 perspective: 400 1595 }); 1596 1597 gsap.set(element.split.chars, { 1598 opacity: 0, 1599 x: "50", 1600 }); 1601 1602 element.animation = gsap.to(element.split.chars, { 1603 scrollTrigger: { 1604 trigger: element, 1605 start: "top 90%" 1606 }, 1607 x: "0", 1608 y: "0", 1609 rotateX: "0", 1610 opacity: 1, 1611 duration: 1, 1612 ease: Back.easeOut, 1613 stagger: 0.02, 1614 }); 1615 }); 1616 } 1617 1618 1619 1620 1621 // Image Reveal Animation 1622 let img_anim_reveal = document.querySelectorAll(".img_anim_reveal"); 1623 1624 img_anim_reveal.forEach((img_reveal) => { 1625 let image = img_reveal.querySelector("img"); 1626 let tl = gsap.timeline({ 1627 scrollTrigger: { 1628 trigger: img_reveal, 1629 start: "top 50%", 1630 } 1631 }); 1632 1633 tl.set(img_reveal, { 1634 autoAlpha: 1 1635 }); 1636 tl.from(img_reveal, 1.5, { 1637 yPercent: -100, 1638 ease: Power2.out 1639 }); 1640 tl.from(image, 1.5, { 1641 yPercent: 100, 1642 scale: 1.3, 1643 delay: -1.5, 1644 ease: Power2.out 1645 }); 1646 });
1647 1648 // hover reveal start 1649 if (document.querySelectorAll(".hover-reveal").length > 0) { 1650 const hoverText = document.querySelectorAll(".hover-reveal"); 1651 1652 function moveText(e, hoverText) { 1653 const item = hoverText.getBoundingClientRect(); 1654 const x = e.clientX - item.x; 1655 const y = e.clientY - item.y; 1656 if (hoverText.children[0]) { 1657 hoverText.children[0].style.transform = `translate(${x}px, ${y}px)`; 1658 } 1659 } 1660 hoverText.forEach((item, i) => { 1661 item.addEventListener("mousemove", (e) => { 1662 setInterval(moveText(e, item), 100); 1663 }); 1664 }); 1665 } 1666 // hover reveal end 1667 1668 /*---------- 04. Sticky fix ----------*/ 1669 $(window).scroll(function () { 1670 var topPos = $(this).scrollTop(); 1671 if (topPos > 500) { 1672 $('.footer-sticky').addClass('sticky'); 1673 } else { 1674 $('.footer-sticky').removeClass('sticky') 1675 } 1676 }) 1677 1678 1679 /* --------- Counter Animation start --------*/ 1680 1681 // Define device_width first 1682 const device_width = window.innerWidth; 1683 1684 const bounceItems = gsap.utils.toArray(".bounce_animation .bounce__anim"); 1685 1686 if (bounceItems.length > 0) { 1687 // Initial state 1688 gsap.set(bounceItems, { 1689 y: -100, 1690 opacity: 0 1691 }); 1692 1693 if (device_width < 1023) { 1694 // Mobile / Tablet 1695 bounceItems.forEach((item) => { 1696 let counterTl = gsap.timeline({ 1697 scrollTrigger: { 1698 trigger: item, 1699 start: "top center+=200", 1700 }, 1701 }); 1702 1703 counterTl.to(item, { 1704 y: 0, 1705 opacity: 1, 1706 ease: "bounce", 1707 duration: 1.5, 1708 }); 1709 }); 1710 } else { 1711 // Desktop 1712 gsap.to(bounceItems, { 1713 scrollTrigger: { 1714 trigger: ".bounce_animation", 1715 start: "top center+=300", 1716 }, 1717 y: 0, 1718 opacity: 1, 1719 ease: "bounce", 1720 duration: 1.5, 1721 stagger: { 1722 each: 0.3, 1723 }, 1724 }); 1725 } 1726 } 1727 1728 /* --------- Counter Animation end --------*/ 1729 1730 /* webgl images hover animation -----------*/ 1731 1732 1733 1734 if ($('.anim-wrap').length > 0) { 1735 const initImageHoverAnimation = function ($animElement, $images) { 1736 const hoverEffectInstance = new hoverEffect({ 1737 parent: $animElement.get(0), 1738 intensity: $animElement.data("intensity") || 0.5, 1739 speedIn: $animElement.data("speedin") || 1.2, 1740 speedOut: $animElement.data("speedout") || 1.2, 1741 easing: $animElement.data("easing") || "power2.out", 1742 displacementImage: $animElement.data("displacement"), 1743 image1: $images.eq(0).attr("src"), 1744 image2: $images.eq(1).length ? $images.eq(1).attr("src") : $images.eq(0).attr("src"), 1745 hover: false 1746 }); 1747 1748 // hide original images 1749 $images.css("opacity", 0); 1750 1751 // hover events 1752 $animElement.closest(".anim-wrap") 1753 .on("mouseenter", () => hoverEffectInstance.next()) 1754 .on("mouseleave", () => hoverEffectInstance.previous()); 1755 1756 // resize handler â fix crop issue 1757 const resizeCanvas = () => { 1758 const w = $animElement.width(); 1759 const h = $animElement.height(); 1760 if (hoverEffectInstance.renderer) { 1761 hoverEffectInstance.renderer.setSize(w, h); 1762 } 1763 1764 if (hoverEffectInstance.material && 1765 hoverEffectInstance.material.uniforms.texture1.value && 1766 hoverEffectInstance.material.uniforms.texture1.value.image) { 1767 const img = hoverEffectInstance.material.uniforms.texture1.value.image; 1768 const imageAspect = img.width / img.height; 1769 const aspect = w / h; 1770 1771 if (aspect > imageAspect) { 1772 hoverEffectInstance.mesh.scale.set(aspect /
1772imageAspect, 1, 1); 1773 } else { 1774 hoverEffectInstance.mesh.scale.set(1, imageAspect / aspect, 1); 1775 } 1776 } 1777 }; 1778 1779 resizeCanvas(); 1780 $(window).on("resize", resizeCanvas); 1781 }; 1782 1783 const setupAllImageHoverAnimations = function () { 1784 $(".img-anim").each(function () { 1785 const $currentAnimElement = $(this); 1786 const $imgElements = $currentAnimElement.find("img"); 1787 const $firstImage = $imgElements.eq(0); 1788 1789 if ($firstImage[0].complete) { 1790 initImageHoverAnimation($currentAnimElement, $imgElements); 1791 } else { 1792 $firstImage.on("load", function () { 1793 initImageHoverAnimation($currentAnimElement, $imgElements); 1794 }); 1795 } 1796 }); 1797 }; 1798 1799 setupAllImageHoverAnimations(); 1800 } 1801 1802 1803 1804 /* webgl images hover animation -----------*/ 1805 1806 1807 1808 1809 /////////////////////// 1810 1811 /* ================================================== 1812 # Ripples 1813 ===============================================*/ 1814 1815 $('.th-ripples').ripples({ 1816 resolution: 256, 1817 dropRadius: 20, 1818 perturbance: 0.02, 1819 }); 1820 1821 1822} 1823 1824 1825(function ($) { 1826 1827 1828 1829 1830 setTimeout(function () { 1831 $('#loader').addClass('loaded'); 1832 // Once the container has finished, the scroll appears 1833 if ($('#loader').hasClass('loaded')) { 1834 // It is so that once the container is gone, the entire preloader section is deleted 1835 $('#preloader').delay(9000).queue(function () { 1836 $(this).remove(); 1837 }); 1838 } 1839 }, 3000); 1840 1841 1842 /*----------- Video Image Animation start----------*/ 1843 1844 gsap.registerPlugin(ScrollTrigger); 1845 1846 function handleResize() { 1847 const isMobile = window.innerWidth < 526; 1848 1849 // ----------- CTA Trigger ----------- 1850 let ctaTrigger = ScrollTrigger.getById("ctaTrigger"); 1851 if (isMobile) { 1852 if (ctaTrigger) { 1853 ctaTrigger.kill(); 1854 } 1855 gsap.set(".cta-card-wrapp, .cta-trigger-thumb", { 1856 scale: 1, 1857 y: 0, 1858 opacity: 1 1859 }); 1860 } else if (!ctaTrigger) { 1861 // Initial state 1862 gsap.set(".cta-card-wrapp", { 1863 scale: 0, 1864 y: 100, 1865 opacity: 0, 1866 transformOrigin: "center center", 1867 willChange: "transform, opacity" 1868 }); 1869 1870 // ScrollTrigger animation 1871 ScrollTrigger.create({ 1872 id: "ctaTrigger", 1873 trigger: ".cta-trigger-thumb", 1874 start: "top 80%", 1875 end: "top 50%", 1876 scrub: 1, 1877 markers: false, 1878 animation: gsap.to(".cta-card-wrapp", { 1879 scale: 1, 1880 y: 0, 1881 opacity: 1, 1882 ease: "power1.out", 1883 duration: 1.5 1884 }) 1885 }); 1886 1887 ScrollTrigger.create({ 1888 id: "ctaThumbTrigger", 1889 trigger: ".cta-trigger-thumb", 1890 start: "top 80%", 1891 end: "top 50%", 1892 scrub: 1, 1893 markers: false, 1894 animation: gsap.to(".cta-trigger-thumb", { 1895 scale: 1, 1896 borderRadius: "0px", 1897 width: "100%", 1898 top: "0", 1899 ease: "linear" 1900 }) 1901 }); 1902 } 1903 1904 /*----------- Video Image Animation start----------*/ 1905 let videoTrigger = ScrollTrigger.getById("videoTrigger"); 1906 if (isMobile) { 1907 if (videoTrigger) { 1908 videoTrigger.kill(); 1909 } 1910 } else if (!videoTrigger) { 1911 ScrollTrigger.create({ 1912 id: "videoTrigger", 1913 trigger: ".video-trigger-thumb", 1914 start: "top 80%", 1915 end: "top 50%", 1916 scrub: 1, 1917 markers: false, 1918 animation: gsap.to(".video-trigger-thumb", { 1919 duration: 2, 1920 scale: 1, 1921 borderRadius: "0px", 1922 width: "100%", 1923 top: "0", 1924 ease: "linear" 1925 }) 1926 }); 1927 } 1928 } 1929 1930 window.addEventListener("load", handleResize); 1931 window.addEventListener("resize", handleResize); 1932 /*----------- Video Image Animation end----------*/ 1933 1934
1935 /////////////////////// 1936 //image cliping effect 1937 document.addEventListener("DOMContentLoaded", () => { 1938 1939 const initialClipPaths = [ 1940 "polygon(0% 0%, 0% 0%, 0% 0%, 0% 0%)", 1941 "polygon(33.33% 0%, 33.33% 0%, 33.33% 0%, 33.33% 0%)", 1942 "polygon(65.66% 0%, 66.66% 0%, 66.66% 0%, 66.66% 0%)", 1943 "polygon(0% 33.33%, 0% 33.33%, 0% 33.33%, 0% 33.33%)", 1944 "polygon(33.33% 33.33%, 33.33% 33.33%, 33.33% 33.33%, 33.33% 33.33%)", 1945 "polygon(65.66% 33.33%, 66.66% 33.33%, 66.66% 33.33%, 66.66% 33.33%)", 1946 "polygon(0% 66.66%, 0% 66.66%, 0% 66.66%, 0% 66.66%)", 1947 "polygon(33.33% 66.66%, 33.33% 66.66%, 33.33% 66.66%, 33.33% 66.66%)", 1948 "polygon(65.66% 66.66%, 66.66% 66.66%, 66.66% 66.66%, 66.66% 66.66%)" 1949 ]; 1950 1951 const finalClipPaths = [ 1952 "polygon(0% 0%, 34.33% 0%, 34.33% 34.33%, 0% 34.33%)", 1953 "polygon(32.33% 0%, 66.66% 0%, 66.66% 33.33%, 33.33% 34.33%)", 1954 "polygon(65.66% 0%, 100% 0%, 100% 33.33%, 65.66% 34.33%)", 1955 "polygon(0% 33.33%, 33.33% 33.33%, 33.33% 66.66%, 0% 66.66%)", 1956 "polygon(30.33% 33.33%, 66.66% 33.33%, 66.66% 66.66%, 33.33% 66.66%)", 1957 "polygon(65.66% 33.33%, 100% 32.33%, 100% 66.66%, 65.66% 66.66%)", 1958 "polygon(0% 65.66%, 33.33% 66.66%, 33.33% 100%, 0% 100%)", 1959 "polygon(30.33% 66.66%, 66.66% 65.66%, 66.66% 100%, 33.33% 100%)", 1960 "polygon(65.66% 66.66%, 100% 65.66%, 100% 100%, 65.66% 100%)" 1961 ]; 1962 1963 // Create mask divs for each wrapper 1964 document.querySelectorAll(".th-clip-anim").forEach(wrapper => { 1965 const img = wrapper.querySelector(".th-anim-img[data-animate='true']"); 1966 if (!img) return; 1967 const url = img.src; 1968 1969 // Remove old masks if any (reuse safe) 1970 wrapper.querySelectorAll(".mask").forEach(m => m.remove()); 1971 1972 for (let i = 0; i < 9; i++) { 1973 const mask = document.createElement("div"); 1974 mask.className = `mask mask-${i + 1}`; 1975 Object.assign(mask.style, { 1976 backgroundImage: `url(${url})`, 1977 backgroundSize: "cover", 1978 backgroundPosition: "center", 1979 position: "absolute", 1980 inset: "0" 1981 }); 1982 wrapper.appendChild(mask); 1983 } 1984 }); 1985 1986 // Animate masks 1987 gsap.utils.toArray(".th-clip-anim").forEach(wrapper => { 1988 const masks = wrapper.querySelectorAll(".mask"); 1989 if (!masks.length) return; 1990 1991 gsap.set(masks, { 1992 clipPath: (i) => initialClipPaths[i] 1993 }); 1994 1995 const order = [ 1996 [".mask-1"], 1997 [".mask-2", ".mask-4"], 1998 [".mask-3", ".mask-5", ".mask-7"], 1999 [".mask-6", ".mask-8"], 2000 [".mask-9"] 2001 ]; 2002 2003 const tl = gsap.timeline({ 2004 scrollTrigger: { 2005 trigger: wrapper, 2006 start: "top 75%" 2007 } 2008 }); 2009 2010 order.forEach((targets, i) => { 2011 const validTargets = targets 2012 .map(c => wrapper.querySelector(c)) 2013 .filter(el => el); // filter out nulls 2014 2015 if (validTargets.length) { 2016 tl.to(validTargets, { 2017 clipPath: (j, el) => finalClipPaths[Array.from(masks).indexOf(el)], 2018 duration: 1, 2019 ease: "power4.out", 2020 stagger: 0.1 2021 }, i * 0.125); 2022 } 2023 }); 2024 }); 2025 }); 2026 2027 2028 2029 // Elementor Frontend Load 2030 $(window).on('elementor/frontend/init', function () { 2031 if (elementorFrontend.isEditMode()) { 2032 elementorFrontend.hooks.addAction('frontend/element_ready/global', function () { 2033 setTimeout(function () { 2034 schon_content_load_scripts(); 2035 }, 500); 2036 }); 2037 } 2038 });
2039 2040 /*----------- 19. Price Slider ----------*/ 2041 2042 2043 // Window Load 2044 $(window).on('load', function () { 2045 schon_content_load_scripts(); 2046 }); 2047 2048})(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.