Zoom on Hover

Zoom on Hover enlarges images when you hover over them.

目前为 2024-11-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Zoom on Hover
  3. // @name:es Zoom on Hover
  4. // @version 1.1
  5. // @description Zoom on Hover enlarges images when you hover over them.
  6. // @description:es Zoom on Hover amplía las imágenes cuando pasas el cursor sobre ellas.
  7. // @author Adam Jensen
  8. // @match *://*/*
  9. // @grant GM_addStyle
  10. // @license MIT
  11. // @namespace https://greasyfork.org/users/1398884
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. // Configuration options (you can adjust these values)
  18. const MAX_WIDTH = 500; // Maximum width of the enlarged image
  19. const MAX_HEIGHT = 600; // Maximum height of the enlarged image
  20. const ZOOM_FACTOR = 2; // Zoom factor (1x, 1.5x, 2x, 3x)
  21.  
  22. // Styles
  23. GM_addStyle(`
  24. .ampliar-img-flotante {
  25. position: absolute;
  26. z-index: 9999;
  27. border: 3px solid #ccc;
  28. background: rgba(255, 255, 255, 0.9);
  29. box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
  30. display: none;
  31. padding: 0px;
  32. pointer-events: none;
  33. height: auto;
  34. width: auto;
  35. box-sizing: border-box;
  36. }
  37. .ampliar-img-flotante img {
  38. width: 100%;
  39. height: 100%;
  40. object-fit: contain;
  41. display: block;
  42. margin: 1px;
  43. }
  44. `);
  45.  
  46. // Create the floating window
  47. const ventanaFlotante = document.createElement('div');
  48. ventanaFlotante.classList.add('ampliar-img-flotante');
  49. const imagenFlotante = document.createElement('img');
  50. ventanaFlotante.appendChild(imagenFlotante);
  51. document.body.appendChild(ventanaFlotante);
  52.  
  53. // Function to enlarge the image with the zoom factor
  54. const ampliarImagen = (event) => {
  55. const target = event.target;
  56.  
  57. let imgSrc = '';
  58.  
  59. if (target.tagName === 'IMG') {
  60. // If the element is an <img>, use the src attribute
  61. imgSrc = target.src;
  62. } else if (target.style.backgroundImage) {
  63. // If the element has a background image, extract the URL
  64. imgSrc = target.style.backgroundImage.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
  65. }
  66.  
  67. // Skip if the image source is not found or is an unwanted source
  68. if (!imgSrc || imgSrc.includes('youtube.com') || imgSrc.includes('gstatic.com')) {
  69. return;
  70. }
  71.  
  72. // For background images, we just scale the element's background size to simulate zoom
  73. const img = new Image();
  74. img.onload = () => {
  75. const widthWithZoom = img.width * ZOOM_FACTOR;
  76. const heightWithZoom = img.height * ZOOM_FACTOR;
  77.  
  78. let finalWidth, finalHeight;
  79.  
  80. if (img.width > img.height) {
  81. finalWidth = Math.min(widthWithZoom, MAX_WIDTH);
  82. finalHeight = (img.height * finalWidth) / img.width;
  83. if (finalHeight > MAX_HEIGHT) {
  84. finalHeight = MAX_HEIGHT;
  85. finalWidth = (img.width * finalHeight) / img.height;
  86. }
  87. } else {
  88. finalHeight = Math.min(heightWithZoom, MAX_HEIGHT);
  89. finalWidth = (img.width * finalHeight) / img.height;
  90. if (finalWidth > MAX_WIDTH) {
  91. finalWidth = MAX_WIDTH;
  92. finalHeight = (img.height * finalWidth) / img.width;
  93. }
  94. }
  95.  
  96. imagenFlotante.src = imgSrc;
  97. ventanaFlotante.style.display = 'block';
  98. ventanaFlotante.style.width = `${finalWidth}px`;
  99. ventanaFlotante.style.height = `${finalHeight}px`;
  100.  
  101. // Calculate the position of the floating window
  102. const { top, left, width, height } = target.getBoundingClientRect();
  103. let newTop = top + window.scrollY;
  104. let newLeft = left + width + window.scrollX;
  105.  
  106. const viewportWidth = window.innerWidth;
  107. const viewportHeight = window.innerHeight;
  108.  
  109. // Adjust the position so it doesn't overflow to the right
  110. if (newLeft + ventanaFlotante.offsetWidth > viewportWidth) {
  111. newLeft = left - ventanaFlotante.offsetWidth + window.scrollX;
  112. }
  113.  
  114. // Adjust the position so it doesn't overflow to the bottom
  115. if (newTop + ventanaFlotante.offsetHeight > viewportHeight + window.scrollY) {
  116. newTop = top + height + window.scrollY - ventanaFlotante.offsetHeight;
  117. }
  118.  
  119. // Adjust the position so it doesn't overflow to the top
  120. if (newTop < window.scrollY) {
  121. newTop = window.scrollY;
  122. }
  123.  
  124. // Adjust the position so it doesn't overflow to the bottom if it's too close
  125. if (newTop + ventanaFlotante.offsetHeight > viewportHeight + window.scrollY) {
  126. newTop = viewportHeight + window.scrollY - ventanaFlotante.offsetHeight;
  127. }
  128.  
  129. ventanaFlotante.style.top = `${newTop}px`;
  130. ventanaFlotante.style.left = `${newLeft}px`;
  131. };
  132. img.src = imgSrc;
  133. };
  134.  
  135. // Hide the floating window
  136. const ocultarVentanaFlotante = () => {
  137. ventanaFlotante.style.display = 'none';
  138. };
  139.  
  140. // Detect images
  141. const detectarImagenes = () => {
  142. const elements = document.querySelectorAll('img, [style*="background-image"]');
  143. elements.forEach((target) => {
  144. if (target.tagName === 'IMG') {
  145. target.addEventListener('mouseenter', ampliarImagen);
  146. target.addEventListener('mouseleave', ocultarVentanaFlotante);
  147. } else if (target.style.backgroundImage) {
  148. target.addEventListener('mouseenter', ampliarImagen);
  149. target.addEventListener('mouseleave', ocultarVentanaFlotante);
  150. }
  151. });
  152. };
  153.  
  154. // Call the function to detect images
  155. detectarImagenes();
  156.  
  157. // Add a mutation observer to detect dynamically added images or background elements
  158. const observer = new MutationObserver(detectarImagenes);
  159. observer.observe(document.body, { childList: true, subtree: true });
  160. })();