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.