PageSourceSearch

https://jovaki.com/wp-content/themes/agron/elements/assets/js/effects.js?ver=1.0.0

js jovaki.com collected 2026-10-07 10:50:51 UTC 7,953 bytes, 200 lines download raw bytes

1( function( $ ) {
2
3    function hoverScaleSpotlight( $scope ) {
4        let els = $scope.find('.hover-spotlight-scale');
5        if(!els.length) return;
6        const update = (e, isMouseenter) => {
7            let item = $(e.currentTarget).find('.item-spotlight').first();
8            if (isMouseenter && !item.length) {
9                item = $('<span class="item-spotlight"></span>');
10                $(e.currentTarget).prepend(item);
11            }
12            const { left, top, width, height } = e.currentTarget.getBoundingClientRect();
13            const mouseX = e.clientX - left;
14            const mouseY = e.clientY - top;
15            const distToCorners = [
16                Math.hypot(mouseX, mouseY), 
17                Math.hypot(mouseX - width, mouseY), 
18                Math.hypot(mouseX, mouseY - height),
19                Math.hypot(mouseX - width, mouseY - height) 
20            ];
21            const maxRadius = Math.max(...distToCorners);
22    
23            gsap.to(item, {
24                x: mouseX,
25                y: mouseY,
26                ease: "none",
27                duration: 0.3,
28                scale: isMouseenter ? (maxRadius / 10) + 0.2 : 0, 
29            });
30        };
31        els.each(function(i, el) {
32            $(el).on('mouseenter', (e) => update(e, true));
33            $(el).on('mouseleave', (e) => update(e, false));
34        })
35    }
36
37    function onHoverCatter($scope) {
38        let els = $scope.find('.grid.pxl-team-layout1 .pxl-post-socials');
39        if (els.length === 0) return;
40        els.each(function (i, el) {
41            const $el = $(el);
42            const $socialItems = $el.find('.pxl-social-item');
43            const $socialIcon = $el.find('.pxl-social-icon');
44
45            const iconOffset = $socialIcon.offset();
46            const iconWidth  = $socialIcon.outerWidth();
47            const iconHeight = $socialIcon.outerHeight();
48
49            let hideTimeout;
50
51            $socialItems.each(function (j, item) {
52                const $item = $(item);
53                const itemOffset = $item.offset();
54                const itemWidth = $item.outerWidth();
55                const itemHeight = $item.outerHeight();
56
57                const dx = (iconOffset.left + iconWidth / 2) - (itemOffset.left + itemWidth / 2);
58                const dy = (iconOffset.top + iconHeight / 2) - (itemOffset.top + itemHeight / 2);
59
60                gsap.set(item, {
61                    x: dx,
62                    y: dy,
63                    opacity: 0,
64                });
65            });
66
67            $el.on('mouseenter', function () {
68                clearTimeout(hideTimeout);
69                $el.css({'pointer-events': 'visible'});
70                $socialItems.each(function (j, item) {
71                    gsap.to(item, {
72                        x: 0,
73                        y: 0,
74                        opacity: 1,
75                        duration: 0.4,
76                        ease: "power2.out",
77                    });
78                });
79            });
80
81            $el.on('mouseleave', function (e) {
82                const toEl = e.relatedTarget;
83                if ($(toEl).closest('.pxl-social-item').length > 0) return;
84                hideTimeout = setTimeout(() => {
85                    $el.css({'pointer-events': 'none'});
86                    $socialItems.each(function (j, item) {
87                        const $item = $(item);
88                        const itemOffset = $item.offset();
89                        const itemWidth = $item.outerWidth();
90                        const itemHeight = $item.outerHeight();
91
92                        const dx = (iconOffset.left + iconWidth / 2) - (itemOffset.left + itemWidth / 2);
93                        const dy = (iconOffset.top + iconHeight / 2) - (itemOffset.top + itemHeight / 2);
94
95                        gsap.to(item, {
96                            x: dx,
97                            y: dy,
98                            opacity: 0,
99                            duration: 0.4,
100                            ease: "power2.in",
101                        });
102                    });
103                }, 50); 
104            });
105
106            // Thêm sự kiện mouseleave cho social item để ẩn khi rời luôn
107            $socialItems.on('mouseleave', function () {
108                hideTimeout = setTimeout(() => {
109                    $socialItems.each(function (j, item) {
110                        const $item = $(item);
111                        const itemOffset = $item.offset();
112                        const itemWidth = $item.outerWidth();
113                        const itemHeight = $item.outerHeight();
114
115                        const dx = (iconOffset.left + iconWidth / 2) - (itemOffset.left + itemWidth / 2);
116                        const dy = (iconOffset.top + iconHeight / 2) - (itemOffset.top + itemHeight / 2);
117
118                        gsap.to(item, {
119                            x: dx,
120                            y: dy,
121                            opacity: 0,
122                            duration: 0.4,
123                            ease: "power2.in",
124                        });
125                    });
126                }, 50);
127            });
128
129            // Nếu chuột quay lại icon nhanh thì huỷ ẩn
130            $socialItems.on('mouseenter', function () {
131                clearTimeout(hideTimeout);
132            });
133        });
134
135    }
136    
137    function hoverTilt($scope) {
138        const els = $scope.find(".hover-tilt");
139        if(!els.length) return;
140        const tilt = $(els).tilt({
141            reverse: false,
142            max: 10,
143            speed: 250,
144            perspective: 1000,
145            transition: true,
146            gyroscope: true,
147            gyroscopeMinAngleX: -15,
148            gyroscopeMaxAngleX: 15,
149            gyroscopeMinAngleY: -15,
150            gyroscopeMaxAngleY: 15,
151            easing: "cubic-bezier(.03,.98,.52,.99)",    
152        });
153
154        tilt.on('change', function(e, transforms) {
155            let tiltX = transforms.tiltX;
156            let tiltY = transforms.tiltY;
157            let tiltItems = $(this).find('.tilt-item');
158            tiltItems.each(function() {
159                let depth = 50;
160                $(this).css({
161                    'transform' : `translateZ(${depth}px) translateX(${tiltX * (depth / 50)}px) translateY(${tiltY * (depth / 50)}px)`,
162                })
163            }) 
164        }); 
165    }
166
167    function hoverImageDistortionTransition( $scope ) {
168        let els = $scope.find('.hover-image-distortion-transition');
169        if(!els.length) return;
170        els.each(function() {
171            const img = $(this).find('img')
172            let src = $(img).attr('src');
173            let currentEl = $(this);
174            let width = parseInt($(img).attr('width')) ?? 1;
175            let height = parseInt($(img).attr('height')) ?? 1;
176            let myAnimation = new hoverEffect({
177                parent: $(this)[0],
178                intensity: 0.3,
179                image1: src,
180                image2: src,
181                displacementImage: currentEl.attr('data-displacement') ?? 'http://agron.local/wp-content/uploads/2025/01/displacement-1.webp',
182                imagesRatio: height/width,
183            });
184        })
185    }
186
187    
188    $( window ).on( 'elementor/frontend/init', function() {
189        elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_button.default`, function( $scope ) {
190            hoverScaleSpotlight($scope);
191        });
192        elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_button_play.default`, function( $scope ) {
193            hoverScaleSpotlight($scope);
194        });
195        elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_team.default`, function($scope) {
196            onHoverCatter($scope);
197        });
198    });
199} )( jQuery );
200

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.