PageSourceSearch

https://maiteperroni.world/wp-content/themes/mouno/elements/assets/js/effects.js?ver=1.0.1

js maiteperroni.world collected 2026-10-02 22:56:06 UTC 34,147 bytes, 868 lines download raw bytes

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.