Pixel Art Zoom

Add-on that allows the user to scroll images so they can view pixel art in browser

  1. // ==UserScript==
  2. // @name Pixel Art Zoom
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2.1
  5. // @description Add-on that allows the user to scroll images so they can view pixel art in browser
  6. // @author You
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13. main();
  14. function main() {
  15. var CSSPixelated = "pixelated-21321322";
  16. var mouseDown = false;
  17. var target = undefined;
  18. var imgContainer = undefined;
  19. var originalWidth = 0;
  20. var originalHeight = 0;
  21. var originalX = 0;
  22. var originalY = 0;
  23. var zoom = 1;
  24. addCSSClasses(CSSPixelated);
  25. document.addEventListener("mousedown", function (e) {
  26. var targetElem = e.target.tagName;
  27. if ((e.ctrlKey && e.shiftKey) && targetElem === "IMG") {
  28. mouseDown = true;
  29. e.preventDefault();
  30. e.stopPropagation();
  31. createImgContainer(e);
  32. zoom += 1;
  33. resizeImg();
  34. }
  35. });
  36. document.addEventListener("mouseup", function (e) {
  37. if (mouseDown) {
  38. e.preventDefault();
  39. e.stopPropagation();
  40. mouseDown = false;
  41. }
  42. });
  43. document.addEventListener("wheel", function (e) {
  44. if (e.ctrlKey && imgContainer && e.target.hasAttribute("data-open")) {
  45. e.preventDefault();
  46. e.stopPropagation();
  47. if (e.deltaY > 0) {
  48. zoom = Math.max(1, zoom - 1);
  49. }
  50. else if (e.deltaY < 0) {
  51. zoom = Math.min(10, zoom + 1);
  52. }
  53. resizeImg();
  54. }
  55. });
  56. function resizeImg() {
  57. if (target === undefined || imgContainer === undefined)
  58. throw new Error("target or imageContainer were undefined");
  59. var targetWidth = zoom * originalWidth;
  60. var targetHeight = zoom * originalHeight;
  61. target.style.width = targetWidth + "px";
  62. target.style.height = targetHeight + "px";
  63. if (originalX + targetWidth > window.scrollX + window.innerWidth) {
  64. imgContainer.style.left = window.scrollX + Math.max(0, Math.floor((window.innerWidth - targetWidth) / 2)) + "px";
  65. }
  66. else {
  67. imgContainer.style.left = Math.max(window.scrollX, originalX - (targetWidth - originalWidth) / 2) + "px";
  68. }
  69. if (originalY + targetHeight > window.scrollY + window.innerHeight) {
  70. imgContainer.style.top = window.scrollY + Math.max(0, Math.floor((window.innerHeight - targetHeight) / 2)) + "px";
  71. }
  72. else {
  73. imgContainer.style.top = Math.max(window.scrollY, originalY - (targetHeight - originalHeight) / 2) + "px";
  74. }
  75. }
  76. function createImgContainer(e) {
  77. if (imgContainer !== undefined)
  78. return;
  79. target = e.target;
  80. imgContainer = document.createElement("div");
  81. var offset = cumulativeOffset(target);
  82. imgContainer.style.top = offset.top + "px";
  83. imgContainer.style.left = offset.left + "px";
  84. imgContainer.className = CSSPixelated;
  85. target = target.cloneNode(true);
  86. target.removeAttribute("style");
  87. target.removeAttribute("class");
  88. target.removeAttribute("height");
  89. target.removeAttribute("width");
  90. target.setAttribute("data-open", "active");
  91. originalWidth = target.width;
  92. originalHeight = target.height;
  93. originalX = offset.left;
  94. originalY = offset.top;
  95. imgContainer.appendChild(target);
  96. document.body.insertBefore(imgContainer, document.body.firstElementChild);
  97. target.setAttribute("tabindex", "0");
  98. target.addEventListener("blur", function () {
  99. destroyImgContainer();
  100. }, true);
  101. target.focus();
  102. function cumulativeOffset(elem) {
  103. var bbox = elem.getBoundingClientRect();
  104. var style = window.getComputedStyle(elem);
  105. var marginLeft = parseInt((style.marginLeft || "0").replace(" px", ""), 10);
  106. var marginTop = parseInt((style.marginTop || "0").replace(" px", ""), 10);
  107. return {
  108. left: bbox.left + window.scrollX - marginLeft,
  109. top: bbox.top + window.scrollY - marginTop,
  110. };
  111. }
  112. }
  113. function destroyImgContainer() {
  114. if (imgContainer === undefined)
  115. return;
  116. document.body.removeChild(imgContainer);
  117. target = undefined;
  118. imgContainer = undefined;
  119. zoom = 1;
  120. }
  121. }
  122. function addCSSClasses(className) {
  123. var head = document.head;
  124. var newCss = document.createElement("style");
  125. newCss.type = "text/css";
  126. newCss.innerHTML = "\n." + className + "{\n image-rendering: -webkit-optimize-contrast; \n image-rendering: -webkit-crisp-edges; \n image-rendering: -moz-crisp-edges; \n image-rendering: -o-crisp-edges; \n image-rendering: pixelated; \n -ms-interpolation-mode: nearest-neighbor; \n position:absolute;\n z-index: 1000000;\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.6), 0 15px 12px rgba(0, 0, 0, 0.46);\n background: #BBBC94;\n}\n";
  127. head.appendChild(newCss);
  128. }
  129. })();