Pixel.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. const dotProduct = function(U, V) {
  2. return U.x * V.x + U.y * V.y;
  3. };
  4. const isInside = function(vertex, square) {
  5. const AB = { x: square.b.x - square.a.x, y: square.b.y - square.a.y };
  6. const AM = { x: vertex.x - square.a.x, y: vertex.y - square.a.y };
  7. const BC = { x: square.c.x - square.b.x, y: square.c.y - square.b.y };
  8. const BM = { x: vertex.x - square.b.x, y: vertex.y - square.b.y };
  9. return (0 <= dotProduct(AB, AM) && dotProduct(AB, AM) <= dotProduct(AB, AB))
  10. && (0 <= dotProduct(BC, BM) && dotProduct(BC, BM) <= dotProduct(BC, BC));
  11. };
  12. const toBinary = function(decimal, padding) {
  13. return decimal.toString(2).padStart(padding, 0);
  14. };
  15. const canvas = {
  16. get boundary() { return document.getElementById("canvas").getBoundingClientRect() },
  17. vertices: {
  18. get a() { return { x: 0, y: 0 }; },
  19. get b() { return { x: 0, y: canvas.boundary.width }; },
  20. get c() { return { x: canvas.boundary.height, y: canvas.boundary.width }; },
  21. get d() { return { x: canvas.boundary.height, y: 0 }; }
  22. },
  23. url: "http://127.0.0.1:5000/image/",
  24. images: [],
  25. level: 3
  26. };
  27. const mouse = {
  28. prevX: 0,
  29. prevY: 0
  30. };
  31. const draw = function(ctx, csize, isize, url, level, images, coords) {
  32. ctx.clearRect(0, 0, csize.width, csize.height);
  33. return draw_(ctx, isize, url, level, images.map((i) => {
  34. return Object.assign(i, {drawn: false});
  35. }), "0".repeat((level + 1) * 2), coords);
  36. }
  37. const draw_ = function(ctx, isize, url, level, images, id, coords) {
  38. if (!isInside(coords, canvas.vertices)) {
  39. return images;
  40. } else {
  41. const decimal = parseInt(id, 2);
  42. const index = images.findIndex((i) => (url + id) === i.image.src);
  43. const target = images[index];
  44. if (target) {
  45. if (target.drawn) {
  46. return images;
  47. } else {
  48. if (target.image.naturalWidth) {
  49. ctx.drawImage(target.image, target.x + coords.x, target.y + coords.y);
  50. } else {
  51. target.image.onload = () => ctx.drawImage(target.image, target.x + coords.x, target.y + coords.y);
  52. }
  53. images.push({
  54. image: target.image,
  55. x: target.x + coords.x,
  56. y: target.y + coords.y,
  57. drawn: true
  58. });
  59. images.splice(index);
  60. }
  61. } else {
  62. const image = new Image();
  63. image.src = url + id;
  64. console.log(decimal);
  65. image.onload = () => ctx.drawImage(image, coords.x, coords.y);
  66. images.push({
  67. image: image,
  68. x: coords.x,
  69. y: coords.y,
  70. drawn: true
  71. });
  72. }
  73. switch (decimal % 4) {
  74. case 0:
  75. if (decimal >= 2 ** (level + 1) * 2)
  76. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2 ** (level + 1) * 2 + 2, id.length), { x: coords.x, y: coords.y - isize.height });
  77. if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
  78. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 1, id.length), { x: coords.x + isize.width, y: coords.y });
  79. if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
  80. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2, id.length), { x: coords.x, y: coords.y + isize.height });
  81. if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
  82. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 3, id.length), { x: coords.x - isize.width, y: coords.y });
  83. break;
  84. case 1:
  85. if (decimal >= 2 ** (level + 1) * 2)
  86. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2 ** (level + 1) * 2 + 2, id.length), { x: coords.x, y: coords.y - isize.height });
  87. if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
  88. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 3, id.length), { x: coords.x + isize.width, y: coords.y });
  89. if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
  90. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2, id.length), { x: coords.x, y: coords.y + isize.height });
  91. if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
  92. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 1, id.length), { x: coords.x - isize.width, y: coords.y });
  93. break;
  94. case 2:
  95. if (decimal >= 2 ** (level + 1) * 2)
  96. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2, id.length), { x: coords.x, y: coords.y - isize.height });
  97. if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
  98. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 1, id.length), { x: coords.x + isize.width, y: coords.y });
  99. if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
  100. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2 ** (level + 1) * 2 - 2, id.length), { x: coords.x, y: coords.y + isize.height });
  101. if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
  102. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 3, id.length), { x: coords.x - isize.width, y: coords.y });
  103. break;
  104. case 3:
  105. if (decimal >= 2 ** (level + 1) * 2)
  106. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2, id.length), { x: coords.x, y: coords.y - isize.height });
  107. if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
  108. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 3, id.length), { x: coords.x + isize.width, y: coords.y });
  109. if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
  110. images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2 ** (level + 1) * 2 - 2, id.length), { x: coords.x, y: coords.y + isize.height });
  111. if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
  112. images = draw_(ctx, isize, url, level, images, toBinary(decimal - 1, id.length), { x: coords.x - isize.width, y: coords.y });
  113. break;
  114. }
  115. return images;
  116. }
  117. };
  118. const main = function() {
  119. const c = document.getElementById("canvas");
  120. c.setAttribute("width", 1000); // window.getComputedStyle(document.body).getPropertyValue("width"));
  121. c.setAttribute("height", 1000); // window.getComputedStyle(document.body).getPropertyValue("height"));
  122. document.addEventListener("mousemove", (e) => {
  123. const image = new Image();
  124. image.src = canvas.url + "0".repeat((canvas.level + 1) * 2)
  125. image.onload = () => {
  126. if (c === document.activeElement && e.buttons === 1) {
  127. canvas.images = draw(c.getContext("2d"), canvas.boundary, {width: image.width, height: image.height},
  128. canvas.url, canvas.level, canvas.images,
  129. {x: e.clientX - mouse.prevX, y: e.clientY - mouse.prevY});
  130. mouse.prevX = e.clientX;
  131. mouse.prevY = e.clientY;
  132. }
  133. };
  134. });
  135. const image = new Image();
  136. image.src = canvas.url + "0".repeat((canvas.level + 1) * 2)
  137. image.onload = () => {
  138. canvas.images = draw(c.getContext("2d"), canvas.boundary, {width: image.width, height: image.height},
  139. canvas.url, canvas.level, canvas.images, {x: 0, y: 0});
  140. }
  141. };