Greasy Fork 还支持 简体中文。

Image Map Fixer

Finds image maps where the image fails to load and add colored blocks to make them more visible.

  1. // ==UserScript==
  2. // @name Image Map Fixer
  3. // @namespace DoomTay
  4. // @description Finds image maps where the image fails to load and add colored blocks to make them more visible.
  5. // @include *
  6. // @version 1.1.1
  7. // @grant none
  8.  
  9. // ==/UserScript==
  10.  
  11. var pics = document.querySelectorAll("img[usemap]");
  12.  
  13. for(var i = 0; i < pics.length; i++)
  14. {
  15. evaluateImage(pics[i]);
  16. }
  17.  
  18. function evaluateImage(pic)
  19. {
  20. pic.addEventListener("error", fixMap, true);
  21.  
  22. if(pic.complete && pic.naturalWidth == 0) fixMap();
  23.  
  24. function fixMap()
  25. {
  26. var picOffset = getOffset(pic)
  27. var map = document.querySelector("map[name = " + pic.useMap.substring(1) + "]");
  28. if(map)
  29. {
  30. var svgNs = "http://www.w3.org/2000/svg";
  31. var newSVG = document.createElementNS(svgNs, "svg");
  32. newSVG.setAttribute("class", "patchedMap " + map.name);
  33. newSVG.setAttributeNS(null, "width", pic.width);
  34. newSVG.setAttributeNS(null, "height", pic.height);
  35. newSVG.style.position = "absolute";
  36. newSVG.style.pointerEvents = "none";
  37. newSVG.style.left = Math.round(picOffset.left) + "px";
  38. newSVG.style.top = Math.round(picOffset.top) + "px";
  39. pic.parentNode.insertBefore(newSVG, pic.nextSibling);
  40. for(var a = 0; a < map.areas.length; a++)
  41. {
  42. if(map.areas[a].getAttribute("shape").toLowerCase() == "default") continue;
  43. if(map.areas[a].getAttribute("shape"))
  44. {
  45. var parsedCoords = map.areas[a].getAttribute("coords").split(",");
  46.  
  47. switch(map.areas[a].getAttribute("shape").toLowerCase())
  48. {
  49. case "rect":
  50. var coords = {x: parseInt(parsedCoords[0]), y: parseInt(parsedCoords[1])};
  51. coords.width = parseInt(parsedCoords[2]) - coords.x;
  52. coords.height = parseInt(parsedCoords[3]) - coords.y;
  53.  
  54. var rect = document.createElementNS(svgNs, "rect");
  55. rect.setAttributeNS(null, "x", coords.x);
  56. rect.setAttributeNS(null, "y", coords.y);
  57. rect.setAttributeNS(null, "width", coords.width);
  58. rect.setAttributeNS(null, "height", coords.height);
  59. rect.setAttributeNS(null, "fill", randomColor());
  60.  
  61. newSVG.appendChild(rect);
  62. break;
  63. case "circle":
  64. var coords = {x: parseInt(parsedCoords[0]), y: parseInt(parsedCoords[1]), radius: parseInt(parsedCoords[2])};
  65.  
  66. var circle = document.createElementNS(svgNs, "circle");
  67. circle.setAttributeNS(null, "cx", coords.x);
  68. circle.setAttributeNS(null, "cy", coords.y);
  69. circle.setAttributeNS(null, "r", coords.radius);
  70. circle.setAttributeNS(null, "fill", randomColor());
  71.  
  72. newSVG.appendChild(circle);
  73. break;
  74. case "poly":
  75. var coords = "";
  76. for(var c = 0; c < parsedCoords.length; c += 2)
  77. {
  78. coords += parsedCoords[c] + "," + parsedCoords[c + 1] + " ";
  79. }
  80.  
  81. var poly = document.createElementNS(svgNs, "polygon");
  82. poly.setAttributeNS(null, "points", coords);
  83. poly.setAttributeNS(null, "fill", randomColor());
  84.  
  85. newSVG.appendChild(poly);
  86. break;
  87. default:
  88. break;
  89. }
  90. }
  91. else
  92. {
  93. var coords = {x: parseInt(parsedCoords[0]), y: parseInt(parsedCoords[1])};
  94. coords.width = parseInt(parsedCoords[2]) - coords.x;
  95. coords.height = parseInt(parsedCoords[3]) - coords.y;
  96.  
  97. var rect = document.createElementNS(svgNs, "rect");
  98. rect.setAttributeNS(null, "x", coords.x);
  99. rect.setAttributeNS(null, "y", coords.y);
  100. rect.setAttributeNS(null, "width", coords.width);
  101. rect.setAttributeNS(null, "height", coords.height);
  102. rect.setAttributeNS(null, "fill", randomColor());
  103.  
  104. newSVG.appendChild(rect);
  105. }
  106. }
  107. }
  108. }
  109.  
  110. function randomColor() {
  111. var color = "rgb(";
  112. var colorValues = [];
  113. for(var c = 0; c < 3; c++)
  114. {
  115. colorValues.push(Math.floor(Math.random()*256));
  116. }
  117. color += colorValues + ")";
  118. return color;
  119. }
  120. }
  121.  
  122. function getOffset(element)
  123. {
  124. var elementCoords = element.getBoundingClientRect();
  125. var positioningParent = getPositioningElement(element);
  126. if(positioningParent != null)
  127. {
  128. var parentCoords = positioningParent.getBoundingClientRect();
  129. var left = elementCoords.left - parentCoords.left;
  130. var top = elementCoords.top - parentCoords.top;
  131. }
  132. else
  133. {
  134. var left = elementCoords.left + window.scrollX;
  135. var top = elementCoords.top + window.scrollY;
  136. }
  137. return {left:left, top:top};
  138. }
  139.  
  140. function getPositioningElement(start)
  141. {
  142. var startingPoint = start.parentNode;
  143. while(startingPoint != document.body)
  144. {
  145. if(window.getComputedStyle(startingPoint).position == "relative" && window.getComputedStyle(startingPoint).position != "absolute") return startingPoint;
  146. startingPoint = startingPoint.parentNode;
  147. }
  148. return null;
  149. }
  150.  
  151. var observer = new MutationObserver(function(mutations) {
  152. mutations.forEach(function(mutation) {
  153. var patchMaps = document.querySelectorAll(".patchedMap");
  154. observer.disconnect();
  155. Array.prototype.forEach.call(patchMaps,
  156. map => {
  157. var offset = getOffset(map.parentNode.querySelector("img"));
  158. map.style.left = Math.round(offset.left) + "px";
  159. map.style.top = Math.round(offset.top) + "px";
  160. }
  161. );
  162. observer.observe(document.body, config);
  163. if(mutation.target.nodeName == "IMG" && mutation.target.useMap && mutation.target.parentNode.querySelector(".patchedMap"))
  164. {
  165. if(mutation.type == "attributes" && mutation.attributeName == "src") mutation.target.parentNode.removeChild(mutation.target.parentNode.querySelector(".patchedMap"));
  166. }
  167. });
  168. });
  169.  
  170. var config = { attributes: true, subtree: true };
  171. observer.observe(document.body, config);