Displays a base image and an "x-ray" view of a second image where the mouse is pointing
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

253 rindas
7.5 KiB

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