1( function( $ ) { 2 function hoverTransformDirectionAnimation( $scope ) { 3 let els = $scope.find('.hover-rotate3d-direction, .hover-translate3d-direction'); 4 if(!els.length) return; 5 const directions = { 0: 'top', 1: 'right', 2: 'bottom', 3: 'left' }; 6 const getDirectionKey = (ev, $node) => { 7 const offset = $node.offset(); 8 const width = $node.outerWidth(); 9 const height = $node.outerHeight(); 10 const l = ev.pageX - offset.left; 11 const t = ev.pageY - offset.top; 12 const x = (l - (width / 2) * (width > height ? (height / width) : 1)); 13 const y = (t - (height / 2) * (height > width ? (width / height) : 1)); 14 return Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; 15 }; 16 17 const getHorizontalKey = (ev, $node) => { 18 const offset = $node.offset(); 19 const width = $node.outerWidth(); 20 const l = ev.pageX - offset.left; 21 const x = l - width / 2; 22 return x < 0 ? 3 : 1; 23 }; 24 25 const getVerticalKey = (ev, $node) => { 26 const offset = $node.offset(); 27 const height = $node.outerHeight(); 28 const t = ev.pageY - offset.top; 29 const y = t - height / 2; 30 return y < 0 ? 0 : 2; 31 }; 32 33 class Item { 34 constructor($element) { 35 this.$element = $element; 36 this.activeClass = ''; 37 38 const parent = this.$element.parent('.menu-item'); 39 if(parent.length) { 40 parent.on('mouseenter', (ev) => this.update(ev, 'in')); 41 parent.on('mouseleave', (ev) => this.update(ev, 'out')); 42 }else { 43 this.$element.on('mouseenter', (ev) => this.update(ev, 'in')); 44 this.$element.on('mouseleave', (ev) => this.update(ev, 'out')) 45 }; 46 } 47 update(ev, prefix) { 48 let itemHover = this.$element.find('.direction-item').first(); 49 if(!itemHover.length) { 50 itemHover = $('<span class="direction-item"></span>'); 51 this.$element.prepend(itemHover); 52 } 53 const effectType = this.$element.hasClass('hover-rotate3d-direction') ? 'rotate3d' : 54 this.$element.hasClass('hover-translate3d-direction') ? 'translate3d' : ''; 55 if (!effectType) return; 56 let direction = this.$element.data().direction; 57 let directionClass = `${effectType}-${prefix}-${directions[getDirectionKey(ev, this.$element)]}`; 58 if(direction === 'horizontal') { 59 directionClass = `${effectType}-${prefix}-${directions[getHorizontalKey(ev, this.$element)]}` 60 } 61 if(direction === 'vertical') { 62 directionClass = `${effectType}-${prefix}-${directions[getVerticalKey(ev, this.$element)]}` 63 } 64 65 if (this.activeClass) { 66 this.$element.removeClass(this.activeClass); 67 } 68 this.activeClass = directionClass; 69 this.$element.addClass(this.activeClass); 70 } 71 } 72 73 $(els).each(function () { 74 new Item($(this)); 75 }); 76 } 77 78 function hoverScaleSpotlight( $scope ) { 79 let els = $scope.find('.hover-spotlight-scale'); 80 if(!els.length) return; 81 const update = (e, isMouseenter) => { 82 let item = $(e.currentTarget).find('.item-spotlight').first(); 83 if (isMouseenter && !item.length) { 84 item = $('<span class="item-spotlight"></span>'); 85 $(e.currentTarget).prepend(item); 86 } 87 const { left, top, width, height } = e.currentTarget.getBoundingClientRect(); 88 const mouseX = e.clientX - left; 89 const mouseY = e.clientY - top; 90 const distToCorners = [ 91 Math.hypot(mouseX, mouseY), 92 Math.hypot(mouseX - width, mouseY),
93 Math.hypot(mouseX, mouseY - height), 94 Math.hypot(mouseX - width, mouseY - height) 95 ]; 96 const maxRadius = Math.max(...distToCorners); 97 98 gsap.to(item, { 99 x: mouseX, 100 y: mouseY, 101 ease: "none", 102 duration: 0.3, 103 scale: isMouseenter ? (maxRadius / 10) + 0.2 : 0, 104 }); 105 }; 106 els.each(function(i, el) { 107 $(el).on('mouseenter', (e) => update(e, true)); 108 $(el).on('mouseleave', (e) => update(e, false)); 109 }) 110 111 } 112 113 114 function hoverImageShow($scope) { 115 let els = $scope.find('.hover-image-show'); 116 if(!els.length) return; 117 const update = (e, isMousemove) => { 118 const imgUrl = $(e.currentTarget).attr('data-image-url'); 119 let item = $(e.currentTarget).find('.item-image').first(); 120 if (isMousemove && !item.length) { 121 item = $('<span class="item-image"></span>'); 122 $(e.currentTarget).prepend(item); 123 } 124 $(item).css('background-image', `url(${imgUrl})`); 125 const { left, top } = e.currentTarget.getBoundingClientRect(); 126 const mouseX = e.clientX - left; 127 const mouseY = e.clientY - top; 128 const imageWidth = $(item).outerWidth() / 2; 129 const imageHeight = $(item).outerHeight() / 2; 130 gsap.to(item, { 131 x: mouseX - imageWidth, 132 y: mouseY - imageHeight, 133 ease: "power1.out", 134 duration: 0.25, 135 delay: 0.15, 136 opacity: isMousemove ? 1 : 0, 137 scale: isMousemove ? 1 : 0, 138 }); 139 }; 140 els.each(function(i, el) { 141 $(el).on('mousemove', (e) => update(e, true)); 142 $(el).on('mouseleave', (e) => update(e, false)); 143 }) 144 } 145 146 function textEffects( $scope ) { 147 const els = $scope.find('.split-text'); 148 if (!els.length) return; 149 150 // Rotate In 151 const effectRoateIn = (el, splitType, settings, elClass) => { 152 let rotateX = 0; 153 let rotateY = 0; 154 let transformOrigin = 'top center -90'; 155 if(elClass.includes('rotate-y')) { 156 rotateX = -90; 157 }else { 158 rotateY = -90; 159 transformOrigin = 'center center' 160 } 161 gsap.set(el, { 162 perspective: 800, 163 }) 164 gsap.from(splitType, { 165 duration: settings['duration'], 166 opacity: 0, 167 rotationX: rotateX, 168 rotationY: rotateY, 169 scaleY: 0.8, 170 force3D: true, 171 transformOrigin: transformOrigin, 172 stagger: settings['stagger'], 173 delay: settings['delay'], 174 scrollTrigger: { 175 trigger: el, 176 start: "top 90%", 177 toggleActions: "play none none none", 178 once: true, 179 }, 180 }); 181 } 182 // Fade In 183 const effectFadeIn = (el, splitType, settings, elClass) => { 184 let x = 0 185 let y = 0 186 if(elClass.includes('fade-in-top')) { 187 y = 50 188 }else if(elClass.includes('fade-in-bottom')) { 189 y = -50 190 }else if(elClass.includes('fade-in-left')) { 191 x = -50 192 }else if(elClass.includes('fade-in-right')) { 193 x = 50 194 } 195 gsap.from(splitType, { 196 duration: settings['duration'] , 197 x: x, 198 y: y, 199 opacity: 0, 200 force3D: true, 201 stagger: settings['stagger'], 202 delay: settings['delay'], 203 scrollTrigger: { 204 trigger: el, 205 start: "top 90%", 206 toggleActions: "play none none none", 207 }, 208 }); 209 } 210 // Slide In 211 const effectSlideIn = (el,splitType, settings, elClass) => { 212 let y = 0; 213 let x = 0; 214 if(elClass.includes('btt')) { 215 y = '110%'; 216 }else if(elClass.includes('ttb')) { 217 y = '-110%'; 218 }else if(elClass.includes('ltr')) { 219 x = '110%'; 220 }else if(elClass.includes('rtl')) { 221 x = '-110%'; 222 } 223 gsap.from(splitType, { 224 duration: settings['duration'], 225 force3D: true, 226 stagger: settings['stagger'], 227 delay: settings['delay'], 228 y: y, 229 x: x, 230 scrollTrigger: { 231 trigger: el, 232 start: "top 90%", 233 toggleActions: "play none none none", 234 }, 235 }); 236 } 237 238 // Reveal 239 const effectReveal = (el, splitType, settings) => { 240 gsap.from(splitType, { 241 duration: settings['duration'], 242 opacity: 0.05, 243 // x: 100, 244 force3D: true, 245 stagger: settings['stagger'], 246 delay: settings['delay'], 247 scrollTrigger: { 248 trigger: el, 249 start: "top 90%", 250 toggleActions: "play none reverse none", 251 scrub: true, 252 }, 253 }); 254 } 255 256 const applyEffects = (el) => { 257 let settings = $(el).data().gsap; 258 259 let elClass = $(el).attr('class'); 260 let attrs = { 261 type: 'lines', 262 linesClass: 'pxl-line', 263 }; 264 let type = 'lines'; 265 266 if (elClass.includes('split-into-word')) { 267 attrs = { ...attrs, type: 'words', wordsClass: 'pxl-word' }; 268 type = 'words'; 269 } else if (elClass.includes('split-into-char')) { 270 attrs = { ...attrs, type: 'words, chars', charsClass: 'pxl-char', wordsClass: 'pxl-word' }; 271 type = 'chars'; 272 } 273 274 $(el).removeClass('visibility-hidden'); 275 276 if (el.splitTextInstance) { 277 el.splitTextInstance.revert(); 278 } 279 280 let splitText = null; 281 if ($(el).hasClass('pxl-text-editor-wrapper')) { 282 const elP = $(el).find('> p'); 283 splitText = new SplitText(elP, attrs); 284 }else { 285 splitText = new SplitText(el, attrs); 286 } 287 el.splitTextInstance = splitText; 288 289 // Apply effects 290 if (elClass.includes('text-effect-rotate-in')) { 291 effectRoateIn(el, splitText[type], settings, elClass); 292 } else if (elClass.includes('text-effect-fade-in')) { 293 effectFadeIn(el, splitText[type], settings, elClass); 294 } else if (elClass.includes('text-effect-slide-in')) { 295 const splitText2 = new SplitText(el, attrs); 296 el.splitTextInstance2 = splitText2; 297 if(type === 'lines') { 298 effectSlideIn(el, splitText[type], settings, elClass); 299 } 300 effectSlideIn(el, splitText2[type], settings, elClass); 301 }else if (elClass.includes('text-effect-reveal')) { 302 effectReveal(el, splitText[type], settings) 303 } 304 }; 305 306 els.each(function (i, el) { 307 applyEffects(el); 308 }); 309 310 let resizeTimeout; 311 $(window).on('resize', function () { 312 clearTimeout(resizeTimeout); 313 resizeTimeout = setTimeout(function () { 314 els.each(function (i, el) { 315 applyEffects(el); 316 }); 317 }, 300); 318 }); 319 } 320 321 function serviceScrollEffects($scope) { 322 let el = $scope.find('.scroll-pin-toggle'); 323 let items = $(el).find('.pxl-grid-item'); 324 if(!el.length || !items.length) return; 325 let prevIndex = -1; 326 ScrollTrigger.create({ 327 trigger: el, 328 start: 'top-=30px top', 329 end: 'bottom 0px', 330 scrub: 1, 331 pin: true, 332 pinSpacing: true, 333 onUpdate: (self) => { 334 let itemIndex = Math.floor(self.progress * items.length); 335 itemIndex = Math.min(itemIndex, items.length - 1); 336 items.each(function(i, el){ 337 if(i !== itemIndex) { 338 $(el).removeClass('active').find('.pxl-accordion-content').slideUp(250);; 339 }else { 340 $(items[i]).addClass('active').find('.pxl-accordion-content').slideDown(250); 341 } 342 })
343 } 344 }) 345 } 346 347 function hoverShowSocialRadial($scope) { 348 let els = $scope.find('.show-social-radial'); 349 if (els.length === 0) return; 350 351 const randomPosition = () => { 352 const directions = [ 353 { xPercent: -100, yPercent: 0 }, 354 { xPercent: 100, yPercent: 0 }, 355 { xPercent: 0, yPercent: -100 }, 356 { xPercent: 0, yPercent: 100 } 357 ]; 358 return directions[Math.floor(Math.random() * directions.length)]; 359 }; 360 361 els.each(function (i, el) { 362 const parent = $(el).closest('.pxl-post-item'); 363 let icons = $(el).find('.pxl-social-link'); 364 365 icons.each(function (i, icon) { 366 gsap.set(icon, { ...randomPosition(), opacity: 0 }); 367 }); 368 369 $(parent).on({ 370 mouseenter() { 371 gsap.to(icons, { 372 xPercent: 0, 373 yPercent: 0, 374 opacity: 1, 375 duration: 0.25, 376 ease: "power1.out", 377 }); 378 }, 379 mouseleave() { 380 icons.each(function (i, icon) { 381 let newRandomPos = randomPosition(); // Random từ má»t hưá»ng cá» Äá»nh 382 gsap.to(icon, { ...newRandomPos, opacity: 0, duration: 0.25 }); 383 }); 384 }, 385 }); 386 }); 387 388 389 } 390 391 function hoverTilt($scope) { 392 const els = $scope.find(".hover-tilt"); 393 if(!els.length) return; 394 const tilt = $(els).tilt({ 395 reverse: false, 396 max: 10, 397 speed: 250, 398 perspective: 1000, 399 transition: true, 400 gyroscope: true, 401 gyroscopeMinAngleX: -15, 402 gyroscopeMaxAngleX: 15, 403 gyroscopeMinAngleY: -15, 404 gyroscopeMaxAngleY: 15, 405 easing: "cubic-bezier(.03,.98,.52,.99)", 406 }); 407 408 tilt.on('change', function(e, transforms) { 409 let tiltX = transforms.tiltX; 410 let tiltY = transforms.tiltY; 411 let tiltItems = $(this).find('.tilt-item'); 412 tiltItems.each(function() { 413 let depth = 50; 414 $(this).css({ 415 'transform' : `translateZ(${depth}px) translateX(${tiltX * (depth / 50)}px) translateY(${tiltY * (depth / 50)}px)`, 416 }) 417 }) 418 }); 419 } 420 421 function hoverImageDistortionWarp($scope) { 422 const els = $scope.find('.hover-image-distortion-warp'); 423 if(!els.length) return; 424 const vs = `#ifdef GL_ES 425 precision mediump float; 426 #endif 427 428 // those are the mandatory attributes that the lib sets 429 attribute vec3 aVertexPosition; 430 attribute vec2 aTextureCoord; 431 432 // those are mandatory uniforms that the lib sets and that contain our model view and projection matrix 433 uniform mat4 uMVMatrix; 434 uniform mat4 uPMatrix; 435 436 uniform mat4 texture0Matrix; 437 438 // if you want to pass your vertex and texture coords to the fragment shader 439 varying vec3 vVertexPosition; 440 varying vec2 vTextureCoord; 441 442 void main() { 443 vec3 vertexPosition = aVertexPosition; 444 445 gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0
445); 446 447 // set the varyings 448 vTextureCoord = (texture0Matrix * vec4(aTextureCoord, 0., 1.)).xy; 449 vVertexPosition = vertexPosition; 450 }` 451 const fs = `#ifdef GL_ES 452 precision mediump float; 453 #endif 454 455 #define PI2 6.28318530718 456 #define PI 3.14159265359 457 #define S(a,b,n) smoothstep(a,b,n) 458 459 uniform float uTime; 460 uniform float uProgress; 461 uniform vec2 uReso; 462 uniform vec2 uMouse; 463 464 // get our varyings 465 varying vec3 vVertexPosition; 466 varying vec2 vTextureCoord; 467 468 // the uniform we declared inside our javascript 469 470 // our texture sampler (default name, to use a different name please refer to the documentation) 471 uniform sampler2D texture0; 472 473 // http://www.flong.com/texts/code/shapers_exp/ 474 float exponentialEasing (float x, float a){ 475 476 float epsilon = 0.00001; 477 float min_param_a = 0.0 + epsilon; 478 float max_param_a = 1.0 - epsilon; 479 a = max(min_param_a, min(max_param_a, a)); 480 481 if (a < 0.5){ 482 // emphasis 483 a = 2.0 * a; 484 float y = pow(x, a); 485 return y; 486 } else { 487 // de-emphasis 488 a = 2.0 * (a-0.5); 489 float y = pow(x, 1.0 / (1.-a)); 490 return y; 491 } 492 } 493 494 void main(){ 495 vec2 uv = vTextureCoord; 496 497 float progress = uProgress; 498 499 float d = exponentialEasing(length( uv - .5 ), progress) - 1.0 + progress * 0.75; 500 501 vec2 centerInterp = (uv - 0.5) * d; 502 503 vec2 r = centerInterp * (progress * 0.6 + 0.4) + uv; 504 vec2 g = centerInterp * (progress * 0.9 + 0.1) + uv; 505 vec2 b = centerInterp * (progress * 0.9 + 0.1) + uv; 506 507 vec4 color = vec4( texture2D( texture0, r).r , texture2D( texture0, g ).g, texture2D( texture0, b).b , 1.); 508 509 gl_FragColor = color; 510 }`; 511 class WEBGL { 512 constructor(set) { 513 this.webGLCurtain = new Curtains({ 514 container: set.canvas , 515 watchScroll: false 516 }); 517 this.planeElement = set.planeElement; 518 this.mouse = { 519 x: 0, 520 y: 0 521 }; 522 this.params = { 523 vertexShader: vs, // our vertex shader ID 524 fragmentShader: fs, // our fragment shader ID 525 uniforms: { 526 time: { 527 name: "uTime", // uniform name that will be passed to our shaders 528 type: "1f", // this means our uniform is a float 529 value: 0 530 }, 531 mousepos: { 532 name: "uMouse", 533 type: "2f", 534 value: [0, 0] 535 }, 536 resolution: { 537 name: "uReso", 538 type: "2f", 539 value: [1, 1] // Initial value, will be updated later 540 }, 541 progress: { 542 name: "uProgress", 543 type: "1f", 544 value: 0 545 } 546 } 547 }; 548 } 549 initPlane() { 550 // create our plane mesh 551 this.plane = this.webGLCurtain.addPlane(this.planeElement, this.params); 552 if (this.plane) { 553 this.plane.onReady(() => { 554 this.update(); 555 this.initEvent(); 556 }); 557 } 558 } 559 update() { 560 this.plane.onRender(() => { 561 this.plane.uniforms.time.value += 0.01; 562 let bounding = this.planeElement.getBoundingClientRect(); 563 this.plane.uniforms.resolution.value = [boun
563ding.width, bounding.height]; 564 }); 565 } 566 initEvent() { 567 this.planeElement.addEventListener("mouseenter", () => { 568 gsap.to(this.plane.uniforms.progress, 1, { 569 value: 1, 570 ease: "expo.inOut" 571 }); 572 }); 573 574 this.planeElement.addEventListener("mouseout", () => { 575 gsap.to(this.plane.uniforms.progress, 1, { 576 value: 0, 577 ease: "expo.inOut" 578 }); 579 }); 580 } 581 } 582 els.each(function() { 583 const webgl = new WEBGL({ 584 canvas: $(this)[0], 585 planeElement: $(this)[0] 586 }); 587 webgl.initPlane(); 588 }) 589 } 590 591 function hoverImageDistortionTransition( $scope ) { 592 let els = $scope.find('.hover-image-distortion-transition'); 593 if(!els.length) return; 594 els.each(function(i, el) { 595 const img = $(el).find('img'); 596 if(!img.length) return; 597 598 img.on('load', function() { 599 requestAnimationFrame(() => { 600 setTimeout(() => { 601 const width = parseInt(img.attr('width')) || 1; 602 const height = parseInt(img.attr('height')) || 1; 603 new hoverEffect({ 604 parent: el, 605 intensity: 0.3, 606 image1: img.attr('src'), 607 image2: img.attr('src'), 608 displacementImage: $(el).attr('data-displacement') || 'http://mouno.local/wp-content/uploads/2025/01/displacement-1.webp', 609 imagesRatio: height / width, 610 }); 611 }, 50); 612 }); 613 }); 614 615 if (img[0].complete) { 616 img.trigger('load'); 617 } 618 }); 619 620 621 } 622 623 function hoverImageDistortionWave( $scope ) { 624 let els = $scope.find('.hover-image-distortion-wave'); 625 if(!els.length) return; 626 const vSheder = ` precision mediump float; 627 // default mandatory variables 628 attribute vec3 aVertexPosition; 629 attribute vec2 aTextureCoord; 630 uniform mat4 uMVMatrix; 631 uniform mat4 uPMatrix; 632 // custom variables 633 varying vec3 vVertexPosition; 634 varying vec2 vTextureCoord; 635 uniform float uTime; 636 637 void main() { 638 vec3 vertexPosition = aVertexPosition; 639 640 // a float varying from -1.5 to 1.5 641 float waveCoords = ((uTime / 45.0) * 3.5) - 1.75; 642 643 // distance from the waveCoords to the vertex coordinates 644 float distanceToWave = distance(vec2(vertexPosition.x, 0.0), vec2(waveCoords, 0.0)); 645 646 // Modify z position only for wave effect 647 vertexPosition.z -= (cos(clamp(distanceToWave, 0.0, 0.75) * 3.141592) - cos(0.75 * 3.141592) + (2.0 * sin(3.141592 * uTime / 90.0))) * 0.025; 648 649 // Ensure the scaling of the canvas is not impacted 650 gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0
650); 651 652 // varyings 653 vTextureCoord = aTextureCoord; 654 vVertexPosition = vertexPosition; 655 } 656 `; 657 658 const fSheder = `precision mediump float; 659 uniform float uTime; 660 varying vec3 vVertexPosition; 661 varying vec2 vTextureCoord; 662 uniform sampler2D uExample; 663 void main() { 664 // get our texture coords 665 vec2 textureCoords = vec2(vTextureCoord.x, vTextureCoord.y); 666 vec4 finalColor = texture2D(uExample, textureCoords); 667 668 gl_FragColor = finalColor; 669 }`; 670 class DistortionWave { 671 constructor(set) { 672 this.webGLCurtain = new Curtains({ 673 container: set.canvas, 674 watchScroll: false 675 }); 676 this.planeElement = set.planeElement; 677 this.mouse = { 678 x: 0, 679 y: 0 680 }; 681 this.params = { 682 vertexShader: vSheder, 683 fragmentShader: fSheder, 684 widthSegments: 20, 685 heightSegments: 1, 686 texturesOptions: { 687 minFilter: this.webGLCurtain.gl.LINEAR_MIPMAP_NEAREST 688 }, 689 uniforms: { 690 time: { 691 name: "uTime", 692 type: "1f", 693 value: 0, 694 }, 695 }, 696 }; 697 } 698 initPlane() { 699 this.plane = this.webGLCurtain.addPlane(this.planeElement, this.params); 700 if (this.plane) { 701 this.plane.onReady(() => { 702 this.initEvent(); 703 }); 704 } 705 } 706 initEvent() { 707 this.planeElement.addEventListener("mouseenter", () => { 708 this.isAnimating = true; 709 gsap.to(this.plane.uniforms.time, { 710 value: 45, 711 duration: 0.75, 712 ease: "none", 713 }); 714 }); 715 this.planeElement.addEventListener("mouseout", () => { 716 this.isAnimating = true; 717 gsap.to(this.plane.uniforms.time, { 718 value: 0, 719 duration: 0.75, 720 ease: "none", 721 }); 722 }); 723 } 724 } 725 726 els.each(function() { 727 const curtain = new DistortionWave({ 728 canvas: $(this)[0], 729 planeElement: $(this)[0] 730 }); 731 curtain.initPlane() 732 }) 733 } 734 735 736 $( window ).on( 'elementor/frontend/init', function() { 737 738 // elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_test.default`, hoverImageDistortionWarp()); 739 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_service.default`, function( $scope ) { 740 setTimeout(function() { 741 hoverTransformDirectionAnimation($scope); 742 }, 250) 743 }); 744 elementorFrontend.hooks.addAction( 'frontend/element_ready/pxl_link_box.default', function( $scope ) { 745 hoverScaleSpotlight($scope) 746 }); 747 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_popup_button.default`, function( $scope ) { 748 hoverScaleSpotlight($scope); 749 }); 750 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_button.default`, function( $scope ) { 751 hoverScaleSpotlight($scope); 752 }); 753 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_cta_button.default`, function( $scope ) { 754 hoverScaleSpotlight($scope); 755 }); 756 elementorFrontend.hooks.addAction( 'frontend/element_ready/pxl_link_box.default', function($scope) { 757 hoverImageShow($scope); 758 } ); 759 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_icon.default`, function( $scope ) { 760 // effectPulseLight($scope); 761 }); 762 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_portfolio.default`, function($scope) { 763 hoverTilt($scope); 764 hoverImageDistortionTransition($scope) 765 hoverImageDistortionWarp($scope) 766 hoverImageDistortionWave($scope) 767 function cursorButton() { 768 let layout = $scope.find('.pxl-layout-portfolio4'); 769 if(!layout.length) return; 770 let items = $(layout).find('.pxl-post-item'); 771 let cursor = $(layout).find('.cursor-btn'); 772 gsap.set($(cursor)[0], {opacity: 0, scale: 0}) 773 $(items).mousemove(function(e) { 774 let offset = $(layout).offset(); 775 let relX = e.pageX - offset.left; 776 let relY = e.pageY - offset.top; 777 778 gsap.to($(cursor)[0], { 779 left: relX, 780 top: relY, 781 scale: 1, 782 opacity: 1, 783 duration: .25, 784 ease: 'none', 785 }) 786 }) 787 $(items).mouseout(function(e) { 788 gsap.to($(cursor)[0], { 789 scale: 0, 790 opacity: 0, 791 duration: .25, 792 ease: 'none', 793 }) 794 }) 795 } 796 cursorButton(); 797 function boxContentFollowCursor() { 798 let layout = $scope.find('.pxl-layout-portfolio1, .pxl-layout-portfolio5'); 799 if (!layout.length) return; 800 let items = $(layout).find('.pxl-post-item'); 801 802 $(items).mousemove(function (e) { 803 let offset = $(this).offset(); 804 let thisWidth = $(this).width(); 805 let thisHeight = $(this).height(); 806 807 let boxContent = $(this).find('.follow-cursor'); 808 let boxWidth = $(boxContent).outerWidth(); 809 let boxHeight = $(boxContent).outerHeight(); 810 811 let mouseX = e.pageX - offset.left; 812 let mouseY = e.pageY - offset.top; 813 814 let newX = Math.min(Math.max(mouseX, boxWidth / 2), thisWidth - boxWidth / 2); 815 let newY = Math.min(Math.max(mouseY, boxHeight / 2), thisHeight - boxHeight / 2); 816 817 gsap.to($(boxContent)[0], { 818 left: newX, 819 top: newY, 820 scale: 1, 821 opacity: 1, 822 duration: 0.25, 823 ease: 'none', 824 }); 825 }); 826 827 $(items).mouseout(function () { 828 let boxContent = $(this).find('.follow-cursor'); 829 gsap.to($(boxContent)[0], { 830 scale: 0, 831 opacity: 0, 832 duration: 0.25, 833 ease: 'none', 834 }); 835 }); 836 } 837 838 boxContentFollowCursor() 839 }); 840 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_post.default`, function($scope) { 841 hoverScaleSpotlight($scope); 842 hoverTilt($scope); 843 hoverImageDistortionTransition($scope) 844 hoverImageDistortionWarp($scope) 845 hoverImageDistortionWave($scope) 846 }); 847 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_service.default`, function($scope) { 848 serviceScrollEffects($scope) 849 }); 850 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_team.default`, function($scope) { 851 hoverShowSocialRadial($scope); 852 hoverTilt($scope) 853 }); 854 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_show_case.default`, function($scope) { 855 hoverTilt($scope) 856 }); 857 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_heading.default`, function( $scope ) {
858 textEffects($scope); 859 }); 860 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_text_editor.default`, function( $scope ) { 861 textEffects($scope); 862 }); 863 elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_navigation_menu.default`, function( $scope ) { 864 hoverTransformDirectionAnimation($scope); 865 }); 866 }); 867} )( jQuery ); 868
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.