Displays a base image and an "x-ray" view of a second image where the mouse is pointing
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

214 line
6.3 KiB

  1. "use strict";
  2. let overlayLoaded = false;
  3. let baseLoaded = false;
  4. let radius = 200;
  5. document.addEventListener("DOMContentLoaded", e => {
  6. document.querySelector("#load-button").addEventListener("click", e => {
  7. console.log("Trying to load...");
  8. const baseInput = document.querySelector("#base-url").value;
  9. const overlayInput = document.querySelector("#overlay-url").value;
  10. try {
  11. let baseURL = new URL(baseInput)
  12. console.log(baseURL);
  13. } catch {
  14. document.querySelector("#base-url").value = "";
  15. document.querySelector("#base-url").placeholder = "Invalid URL...";
  16. }
  17. try {
  18. let overlayURL = new URL(overlayInput)
  19. console.log(overlayURL);
  20. } catch {
  21. document.querySelector("#overlay-url").value = "";
  22. document.querySelector("#overlay-url").placeholder = "Invalid URL...";
  23. }
  24. const overlayImg = document.querySelector("#overlay-img");
  25. const baseImg = document.querySelector("#base-img");
  26. overlayImg.src = overlayInput;
  27. baseImg.src = baseInput;
  28. load();
  29. try {
  30. localStorage.setItem("base", baseInput);
  31. localStorage.setItem("overlay", overlayInput);
  32. } catch {
  33. console.error("Couldn't set something in local storage :(")
  34. }
  35. });
  36. let url = new URL(window.location);
  37. const overlay = document.querySelector("#overlay");
  38. overlay.addEventListener("mousemove", e => {
  39. let x = e.clientX - e.target.getBoundingClientRect().x;
  40. let y = e.clientY - e.target.getBoundingClientRect().y;
  41. updateOverlay([[x,y]]);
  42. });
  43. overlay.addEventListener("touchmove", e => {
  44. let offsetX = e.target.getBoundingClientRect().x;
  45. let offsetY = e.target.getBoundingClientRect().y;
  46. let touches = [];
  47. for (let i=0; i < e.touches.length; i++) {
  48. let x = e.touches[i].clientX - offsetX;
  49. let y = e.touches[i].clientY - offsetY;
  50. touches.push([x,y]);
  51. }
  52. updateOverlay(touches);
  53. });
  54. document.querySelector("#radius").addEventListener("change", e => {
  55. try {
  56. radius = parseInt(e.target.value);
  57. } catch {
  58. console.warn("That wasn't a valid radius: " + e.target.value);
  59. }
  60. });
  61. // see if we have params already; if so, use them!
  62. const overlayImg = document.querySelector("#overlay-img");
  63. const baseImg = document.querySelector("#base-img");
  64. if (url.searchParams.has("base") && url.searchParams.has("overlay")) {
  65. let baseURL = url.searchParams.get("base");
  66. let overlayURL = url.searchParams.get("overlay");
  67. baseImg.src = baseURL;
  68. overlayImg.src = overlayURL;
  69. load();
  70. } else {
  71. const baseInput = document.querySelector("#base-url");
  72. const overlayInput = document.querySelector("#overlay-url");
  73. try {
  74. baseInput.value = localStorage.getItem("base");
  75. overlayInput.value = localStorage.getItem("overlay");
  76. } catch {
  77. console.error("Couldn't get something from local storage :(")
  78. }
  79. }
  80. if (url.searchParams.has("radius")) {
  81. try {
  82. radius = parseInt(url.searchParams.get("radius"));
  83. document.querySelector("#radius").value = radius;
  84. } catch {
  85. console.warn("That was a bogus radius...");
  86. }
  87. }
  88. document.querySelector("#share-button").addEventListener("click", e => {
  89. let shareURL = new URL(window.location);
  90. for (var key of shareURL.searchParams.keys()) {
  91. shareURL.searchParams.delete(key);
  92. }
  93. shareURL.searchParams.append("base", baseImg.src);
  94. shareURL.searchParams.append("overlay", overlayImg.src);
  95. console.log(shareURL);
  96. window.location = shareURL;
  97. });
  98. });
  99. function load() {
  100. document.querySelector("#menu").classList.remove("start");
  101. const overlayImg = document.querySelector("#overlay-img");
  102. const baseImg = document.querySelector("#base-img");
  103. overlayImg.addEventListener("load", function overlayLoad() {
  104. console.log("The overlay is loaded");
  105. overlayLoaded = true;
  106. if (overlayLoaded && baseLoaded) {
  107. setup();
  108. }
  109. overlayImg.removeEventListener("load", overlayLoad);
  110. })
  111. baseImg.addEventListener("load", function baseLoad() {
  112. console.log("The base is loaded");
  113. baseLoaded = true;
  114. if (overlayLoaded && baseLoaded) {
  115. setup();
  116. }
  117. baseImg.removeEventListener("load", baseLoad);
  118. })
  119. }
  120. function setup() {
  121. const overlay = document.querySelector("#overlay");
  122. const base = document.querySelector("#base");
  123. const overlayImg = document.querySelector("#overlay-img");
  124. const baseImg = document.querySelector("#base-img");
  125. /** @type {CanvasRenderingContext2D} */
  126. const overlayCtx = overlay.getContext("2d");
  127. /** @type {CanvasRenderingContext2D} */
  128. const baseCtx = base.getContext("2d");
  129. baseCtx.canvas.width = baseImg.width;
  130. baseCtx.canvas.height = baseImg.height;
  131. baseCtx.drawImage(baseImg, 0, 0);
  132. overlayCtx.canvas.width = overlayImg.width;
  133. overlayCtx.canvas.height = overlayImg.height;
  134. console.log("Done");
  135. }
  136. function updateOverlay(points) {
  137. /** @type {CanvasRenderingContext2D} */
  138. const overlayCtx = overlay.getContext("2d");
  139. const overlayImg = document.querySelector("#overlay-img");
  140. const w = overlayCtx.canvas.width;
  141. const h = overlayCtx.canvas.height;
  142. overlayCtx.save();
  143. overlayCtx.globalCompositeOperation = "source-over";
  144. overlayCtx.clearRect(0, 0, w, h);
  145. points.forEach(point => {
  146. const [x,y] = point;
  147. overlayCtx.beginPath();
  148. overlayCtx.ellipse(x, y, radius, radius, 0, 0, 2 * Math.PI);
  149. const gradient = overlayCtx.createRadialGradient(x, y, 0, x, y, radius);
  150. gradient.addColorStop(0.75, '#000000FF');
  151. gradient.addColorStop(1, '#00000000');
  152. overlayCtx.fillStyle = gradient;
  153. overlayCtx.fill();
  154. })
  155. overlayCtx.globalCompositeOperation = "source-in";
  156. overlayCtx.drawImage(overlayImg, 0, 0);
  157. overlayCtx.restore();
  158. }