Center Image

Centers images with hotkeys

目前为 2014-03-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Center Image
  3. // @namespace CenterImage
  4. // @author Owyn
  5. // @version 1.4
  6. // @homepage https://userscripts.org/scripts/show/177505
  7. // @description Centers images with hotkeys
  8. // @run-at document-start
  9. // @noframes
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_registerMenuCommand
  13. // @match http://*/*
  14. // @match https://*/*
  15. // @match file://*/*
  16. // ==/UserScript==
  17.  
  18. if (typeof GM_registerMenuCommand !== "undefined")
  19. {
  20. GM_registerMenuCommand("Center Image Configuration", cfg, "n");
  21. }
  22.  
  23. var images = document.images;
  24. if (!images || images.length !== 1 || images[0].src !== location.href)
  25. {
  26. return false;
  27. }
  28.  
  29. var rescaled = false;
  30. var iot = 0, iol = 0;
  31. var img = images[0];
  32.  
  33. function makeimage()
  34. {
  35. if(cfg_bgclr)
  36. {
  37. document.body.bgColor = cfg_bgclr;
  38. if(document.head){document.head.innerHTML = "";} // remove FireFox background
  39. }
  40. document.body.innerHTML = "<style>img { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }</style>"; // center image
  41. img.id = "resizing";
  42. img.style.margin = "auto"; // center image
  43. document.body.style.margin = "0px";
  44. document.body.appendChild(img);
  45. img.addEventListener("mousedown", onmousedown, true);
  46. img.addEventListener("click", rescale, true);
  47. window.addEventListener("keydown", onkeydown, true);
  48. window.addEventListener("resize", onresize, true);
  49. autoresize();
  50. }
  51.  
  52. function onresize()
  53. {
  54. if(rescaled)
  55. {
  56. rescaled = false;
  57. rescale();
  58. }
  59. }
  60.  
  61. function changecursor()
  62. {
  63. img.style.margin = "auto";
  64. var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
  65. var CH = root.clientHeight;
  66. if(CH == 0){CH = document.compatMode=='BackCompat'? document.documentElement.clientHeight : document.body.clientHeight;} // StupidFox
  67. if(!rescaled && ((img.naturalHeight == CH) || (img.naturalWidth == root.clientWidth)) && ((CH == root.scrollHeight) && (root.clientWidth == root.scrollWidth)) ) // no scrollbars and one img dimension is equal to screen
  68. {
  69. img.style.cursor = "";
  70. }
  71. else if((img.naturalHeight > CH) || (img.naturalWidth > root.clientWidth))
  72. {
  73. if(rescaled)
  74. {
  75. img.style.cursor = "-moz-zoom-in";
  76. img.style.cursor = "-webkit-zoom-in";
  77. }
  78. else
  79. {
  80. img.style.cursor = "-moz-zoom-out";
  81. img.style.cursor = "-webkit-zoom-out";
  82. if(img.naturalHeight > CH) // chrome bug fuuuuu
  83. {
  84. img.style.margin = "0px auto";
  85. }
  86. }
  87. }
  88. else
  89. {
  90. if(rescaled)
  91. {
  92. img.style.cursor = "-moz-zoom-out";
  93. img.style.cursor = "-webkit-zoom-out";
  94. }
  95. else
  96. {
  97. img.style.cursor = "-moz-zoom-in";
  98. img.style.cursor = "-webkit-zoom-in";
  99. }
  100. }
  101. }
  102.  
  103. function onmousedown(event)
  104. {
  105. if(img.offsetLeft > 0){iol = img.offsetLeft;}
  106. if(img.offsetTop > 0){iot = img.offsetTop;}
  107. }
  108.  
  109. function rescale(event)
  110. {
  111. if(rescaled)
  112. {
  113. rescaled = false;
  114. var scale;
  115. if(event != 0)
  116. {
  117. if (typeof event.y === "undefined") // Firefox
  118. {
  119. ex = event.clientX;
  120. ey = event.clientY;
  121. }
  122. else
  123. {
  124. ex = event.x;
  125. ey = event.y;
  126. }
  127. ex -= iol;
  128. ey -= iot;
  129. scale = Math.min((window.innerWidth / img.naturalWidth), (window.innerHeight / img.naturalHeight));
  130. }
  131. img.removeAttribute("style");
  132. img.removeAttribute("width");
  133. img.removeAttribute("height");
  134. changecursor();
  135. if(event != 0)
  136. {
  137. window.scrollTo(ex / scale - window.innerWidth / 2, ey / scale - window.innerHeight / 2);
  138. }
  139. }
  140. else
  141. {
  142. img.removeAttribute("width");
  143. img.removeAttribute("height");
  144. img.removeAttribute("style");
  145. if(img.naturalWidth != window.innerWidth)
  146. {
  147. img.style.width = window.innerWidth + "px";
  148. rescaled = true;
  149. }
  150. var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
  151. if((root.scrollHeight != root.clientHeight) || (root.scrollWidth != root.clientWidth))
  152. {
  153. img.removeAttribute("style");
  154. if(img.naturalHeight != window.innerHeight)
  155. {
  156. img.style.height = window.innerHeight + "px";
  157. rescaled = true;
  158. }
  159. }
  160. changecursor();
  161. }
  162. }
  163.  
  164. function autoresize()
  165. {
  166. if(img.naturalWidth != 0) // stupidfox
  167. {
  168. if(!document.head) // Chrome detected
  169. {
  170. document.lastChild.insertBefore(document.createElement("head"), document.body);
  171. var link = document.createElement('link');
  172. link.type = 'image/x-icon';
  173. link.rel = 'shortcut icon';
  174. link.href = img.src;
  175. document.head.appendChild(link);
  176. }
  177. var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
  178. if(img.naturalHeight > root.clientHeight && img.naturalWidth > root.clientWidth) // both scrollbars
  179. {
  180. rescaled = true;
  181. if(!cfg_fitWH)
  182. {
  183. rescale(0);
  184. }
  185. else
  186. {
  187. changecursor();
  188. }
  189. }
  190. else if(img.naturalHeight > root.clientHeight || img.naturalWidth > root.clientWidth) // one scrollbar
  191. {
  192. rescaled = true;
  193. if(!cfg_fitB)
  194. {
  195. rescale(0);
  196. }
  197. else
  198. {
  199. changecursor();
  200. }
  201. }
  202. else // no scrollbars
  203. {
  204. if(cfg_fitS)
  205. {
  206. rescale(0);
  207. }
  208. else
  209. {
  210. changecursor();
  211. }
  212. }
  213. if(cfg_js){eval(cfg_js);}
  214. }
  215. else
  216. {
  217. setTimeout(function() { autoresize(); }, 10);
  218. }
  219. }
  220.  
  221. // hotkeys
  222. if (typeof KeyEvent === "undefined")
  223. {
  224. var KeyEvent = {
  225. DOM_VK_SPACE: 32,
  226. DOM_VK_LEFT: 37,
  227. DOM_VK_UP: 38,
  228. DOM_VK_RIGHT: 39,
  229. DOM_VK_DOWN: 40,
  230. DOM_VK_A: 65,
  231. DOM_VK_D: 68,
  232. DOM_VK_P: 80,
  233. DOM_VK_Q: 81,
  234. DOM_VK_S: 83,
  235. DOM_VK_W: 87,
  236. DOM_VK_NUMPAD2: 98,
  237. DOM_VK_NUMPAD4: 100,
  238. DOM_VK_NUMPAD5: 101,
  239. DOM_VK_NUMPAD6: 102,
  240. DOM_VK_NUMPAD8: 104
  241. };
  242. }
  243.  
  244. function cancelEvent(a)
  245. {
  246. a = a ? a : window.event;
  247. if (a.stopPropagation)
  248. {
  249. a.stopPropagation();
  250. }
  251. if (a.preventDefault)
  252. {
  253. a.preventDefault();
  254. }
  255. a.cancelBubble = true;
  256. a.cancel = true;
  257. a.returnValue = false;
  258. return false;
  259. }
  260.  
  261. function scroll_space(a, b)
  262. {
  263. var by = Math.round((b ? window.innerHeight : window.innerWidth) * 0.50 * (a ? -1 : 1));
  264. if(!b)
  265. {
  266. window.scrollBy(0, by);
  267. }
  268. else
  269. {
  270. window.scrollBy(by, 0);
  271. }
  272. }
  273.  
  274. function onkeydown (b)
  275. {
  276. var a = (window.event) ? b.keyCode : b.which;
  277. if (a != KeyEvent.DOM_VK_SPACE && (b.altKey || b.ctrlKey || b.metaKey))
  278. {
  279. return;
  280. }
  281. var by = Math.round(window.innerHeight * 0.10);
  282. switch (a)
  283. {
  284. case KeyEvent.DOM_VK_RIGHT:
  285. case KeyEvent.DOM_VK_D:
  286. case KeyEvent.DOM_VK_NUMPAD6:
  287. window.scrollBy(by, 0);
  288. cancelEvent(b);
  289. break;
  290. case KeyEvent.DOM_VK_LEFT:
  291. case KeyEvent.DOM_VK_A:
  292. case KeyEvent.DOM_VK_NUMPAD4:
  293. window.scrollBy(by * -1, 0);
  294. cancelEvent(b);
  295. break;
  296. case KeyEvent.DOM_VK_W:
  297. case KeyEvent.DOM_VK_NUMPAD8:
  298. window.scrollBy(0, by * -1);
  299. cancelEvent(b);
  300. break;
  301. case KeyEvent.DOM_VK_S:
  302. case KeyEvent.DOM_VK_NUMPAD2:
  303. window.scrollBy(0, by);
  304. cancelEvent(b);
  305. break;
  306. case KeyEvent.DOM_VK_SPACE:
  307. scroll_space(b.shiftKey, b.ctrlKey);
  308. cancelEvent(b);
  309. break;
  310. case KeyEvent.DOM_VK_Q:
  311. case KeyEvent.DOM_VK_NUMPAD5:
  312. rescale(0);
  313. cancelEvent(b);
  314. break;
  315. case KeyEvent.DOM_VK_P:
  316. cfg();
  317. cancelEvent(b);
  318. }
  319. }
  320.  
  321. var cfg_bgclr;
  322. var cfg_fitWH = true;
  323. var cfg_fitB = true;
  324. var cfg_fitS;
  325. var cfg_js;
  326. if (typeof GM_getValue !== "undefined")
  327. {
  328. cfg_bgclr = GM_getValue("bgColor");
  329. cfg_fitWH = GM_getValue("fitWH", true);
  330. cfg_fitB = GM_getValue("fitB", true);
  331. cfg_fitS = GM_getValue("fitS");
  332. cfg_js = GM_getValue("js");
  333. }
  334.  
  335. function $(id) {return document.getElementById(id);} // for StupidFox
  336.  
  337. function cfg()
  338. {
  339. if (typeof GM_setValue !== "undefined")
  340. {
  341. function saveCfg()
  342. {
  343. GM_setValue("bgColor", $("ci_cfg_2_bgclr").value);
  344. GM_setValue("fitWH", $("ci_cfg_3_fitWH").checked);
  345. GM_setValue("fitB", $("ci_cfg_4_fitB").checked);
  346. GM_setValue("fitS", $("ci_cfg_5_fitS").checked);
  347. GM_setValue("js", $("ci_cfg_6_js").value);
  348. alert("Configuration Saved");
  349. if($("ci_cfg_2_bgclr").value){document.body.bgColor = $("ci_cfg_2_bgclr").value;}else{document.body.removeAttribute("bgColor");}
  350. }
  351. if(img){img.removeEventListener("click", rescale, true);}
  352. window.removeEventListener("keydown", onkeydown, true);
  353. if(document.head){document.head.innerHTML = "";}
  354. document.body.innerHTML = "";
  355. var div = document.createElement("div");
  356. div.style.margin = "11% auto";
  357. div.style.width = "444px";
  358. div.style.border = "solid 1px black";
  359. div.style.background = "silver";
  360. div.innerHTML = "<b><center>Configuration</center></b>"
  361. + "<br><input id='ci_cfg_2_bgclr' type='text' size='6'> Background color (empty = default)"
  362. + "<br><br>Fit to window images:"
  363. + "<br><br><input id='ci_cfg_3_fitWH' type='checkbox'> Larger than window both vertically and horizontally"
  364. + "<br><br><input id='ci_cfg_4_fitB' type='checkbox'> Larger than window either vertically or horizontally"
  365. + "<br><br><input id='ci_cfg_5_fitS' type='checkbox'> Smaller than window"
  366. + "<br><br><center>Custom JS Action:<textarea id='ci_cfg_6_js' style='margin: 0px; width: 400px; height: 50px;'></textarea>"
  367. + "<br><input id='ci_cfg_save' type='button' value='Save configuration'></center>";
  368. document.body.appendChild(div);
  369. $("ci_cfg_2_bgclr").value = GM_getValue("bgColor", "");
  370. $("ci_cfg_3_fitWH").checked = GM_getValue("fitWH", true);
  371. $("ci_cfg_4_fitB").checked = GM_getValue("fitB", true);
  372. $("ci_cfg_5_fitS").checked = GM_getValue("fitS");
  373. $("ci_cfg_6_js").value = GM_getValue("js", "");
  374. $("ci_cfg_save").addEventListener("click", saveCfg, true);
  375. }
  376. else
  377. {
  378. alert("Sorry, Chrome userscripts in native mode can't have configurations! Install TamperMonkey extension. (it's very good)");
  379. }
  380. }
  381. makeimage();