Image Viewer

inject this script into any page, and right-click on the image you want to view full-size

目前为 2020-03-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Image Viewer
  3. // @namespace https://gist.github.com/bradenbest/04bd0fc2d57ec650449f
  4. // @version 1.6.1
  5. // @description inject this script into any page, and right-click on the image you want to view full-size
  6. // @copyright 2014 - 2017, Braden Best
  7. //
  8. // @match *
  9. // ==/UserScript==
  10.  
  11. const firefox = /Firefox/i.test(navigator.userAgent);
  12.  
  13. function mk_node({
  14. name = "span",
  15. props = [],
  16. styles = [],
  17. events = [],
  18. extra = null
  19. } = {}){
  20. let el = document.createElement(name);
  21.  
  22. props.forEach(function([name, value]){
  23. el[name] = value;
  24. });
  25.  
  26. styles.forEach(function([name, value]){
  27. el.style[name] = value;
  28. });
  29.  
  30. events.forEach(function([name, callback]){
  31. el.addEventListener(name, function(ev){
  32. callback(ev, el);
  33. });
  34. });
  35.  
  36. if(extra)
  37. extra(el);
  38.  
  39. return el;
  40. }
  41.  
  42. function mk_img(url){
  43. return mk_node({
  44. name: "img",
  45. props: [
  46. ["src", url],
  47. ["className", "img_viewer"],
  48. ["draggable", "false"],
  49. ["dragging", 0],
  50. ["mousepos", [0,0]],
  51. ["tabIndex", 0]
  52. ],
  53. styles: [
  54. ["position", "absolute"],
  55. ["left", "0px"],
  56. ["top", (80 + document.body.scrollTop) + "px"],
  57. ["zIndex", "2147483647"]
  58. ],
  59. events: [
  60. ["mousedown", function(ev, self){
  61. self.dragging = firefox
  62. ? !self.dragging
  63. : 1;
  64.  
  65. self.mousepos[0] = (ev.clientX || ev.pageX);
  66. self.mousepos[1] = (ev.clientY || ev.pageY);
  67. }],
  68. ["mouseup", function(unused, self){
  69. if(firefox)
  70. return false;
  71.  
  72. self.dragging = 0;
  73. }],
  74. ["mousemove", function(ev, self){
  75. let curX = (ev.clientX || ev.pageX);
  76. let curY = (ev.clientY || ev.pageY);
  77. let diffX = curX - self.mousepos[0];
  78. let diffY = curY - self.mousepos[1];
  79.  
  80. if(!self.dragging || (!diffX && !diffY))
  81. return false;
  82.  
  83. self.mousepos = [curX, curY];
  84. self.style.left = parseInt(self.style.left) + diffX + "px";
  85. self.style.top = parseInt(self.style.top) + diffY + "px";
  86. }],
  87. ["keydown", function(ev, self){
  88. let dispatch = ({
  89. "ArrowUp": ["height", -10],
  90. "ArrowDown": ["height", +10],
  91. "ArrowLeft": ["width", -10],
  92. "ArrowRight": ["width", +10]
  93. })[ev.key] || ["width", 0];
  94.  
  95. self[dispatch[0]] = +self[dispatch[0]] + dispatch[1];
  96. }]
  97. ]
  98. });
  99. }
  100.  
  101. function mk_img_helper({img, img_helper_link}){
  102. let el = mk_node({
  103. name: "div",
  104. props: [
  105. ["innerHTML", "Click here to close image"],
  106. ["className", "img_viewer"]
  107. ],
  108. styles: [
  109. ["position", "fixed"],
  110. ["left", "0px"],
  111. ["top", "0px"],
  112. ["margin", "0"],
  113. ["padding", "5px 0"],
  114. ["width", "100%"],
  115. ["height", "50px"],
  116. ["background", "#fff"],
  117. ["borderBottom", "1px solid #ccc"],
  118. ["color", "#000"],
  119. ["fontSize", "12px"],
  120. ["textAlign", "center"],
  121. ["zIndex", "2147483647"]
  122. ],
  123. events: [
  124. ["click", function(unused, unused2){
  125. document.body.removeChild(img);
  126. document.body.removeChild(el);
  127. document.body.removeChild(img_helper_link);
  128. }]
  129. ]
  130. });
  131.  
  132. return el;
  133. }
  134.  
  135. function mk_img_helper_link(url){
  136. return mk_node({
  137. name: "a",
  138. props: [
  139. ["innerHTML", "Direct URL"],
  140. ["href", url],
  141. ["target", "_blank"],
  142. ["className", "img_viewer"]
  143. ],
  144. styles: [
  145. ["margin", "0"],
  146. ["padding", "0"],
  147. ["background", "#fff"],
  148. ["borderBottom", "1px solid #ccc"],
  149. ["display", "block"],
  150. ["width", "100%"],
  151. ["height", "20px"],
  152. ["position", "fixed"],
  153. ["left", "0"],
  154. ["top", "50px"],
  155. ["fontSize", "12px"],
  156. ["textAlign", "center"],
  157. ["zIndex", "2147483647"]
  158. ]
  159. });
  160. }
  161.  
  162. function mk_img_group(url){
  163. let img = mk_img(url);
  164. let img_helper_link = mk_img_helper_link(url);
  165. let img_helper = mk_img_helper({img, img_helper_link});
  166.  
  167. [img, img_helper, img_helper_link].forEach(function(node){
  168. document.body.appendChild(node);
  169. });
  170.  
  171. return { img, img_helper, img_helper_link };
  172. }
  173.  
  174. function clear(){
  175. [...document.querySelectorAll(".img_viewer")]
  176. .forEach(function(viewer){
  177. document.body.removeChild(viewer);
  178. });
  179. }
  180.  
  181. function init(){
  182. [...document.querySelectorAll("img")].forEach(function(img){
  183. img.addEventListener("contextmenu", function(ev){
  184. mk_img_group(img.src);
  185. ev.preventDefault();
  186. });
  187. });
  188.  
  189. document.body.addEventListener("mouseup", function(ev){
  190. if(firefox)
  191. return false;
  192.  
  193. [...document.querySelectorAll(".img_viewer")]
  194. .forEach(function(viewer){
  195. viewer.dragging = 0;
  196. });
  197. });
  198.  
  199. document.body.addEventListener("keydown", function(ev){
  200. let dispatch = ({
  201. "Escape": clear,
  202. "Control": init
  203. })[ev.key] || (()=>null);
  204.  
  205. dispatch();
  206. });
  207. }
  208.  
  209. init();
  210. console.log("Image Viewer started up.");
  211. console.log("Try right-clicking an image");