Pixel.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. var canvas = {};
  2. const dotProduct = function(U, V) {
  3. return U.x * V.x + U.y * V.y;
  4. };
  5. const isInside = function(vertex) {
  6. const AB = { x: canvas.vertex.b.x - canvas.vertex.a.x, y: canvas.vertex.b.y - canvas.vertex.a.y };
  7. const AM = { x: vertex.x - canvas.vertex.a.x, y: vertex.y - canvas.vertex.a.y };
  8. const BC = { x: canvas.vertex.c.x - canvas.vertex.b.x, y: canvas.vertex.c.y - canvas.vertex.b.y };
  9. const BM = { x: vertex.x - canvas.vertex.b.x, y: vertex.y - canvas.vertex.b.y };
  10. return (0 <= dotProduct(AB, AM) && dotProduct(AB, AM) <= dotProduct(AB, AB))
  11. && (0 <= dotProduct(BC, BM) && dotProduct(BC, BM) <= dotProduct(BC, BC));
  12. };
  13. const draw = function(ctx, source, coords) {
  14. if (!coords) {
  15. ctx.clearRect(0, 0, canvas.element.width, canvas.element.height);
  16. coords = { x: 0, y: 0 };
  17. canvas.quadrants.images = canvas.quadrants.images.filter(i => {
  18. return isInside({ x: i.x, y: i.y })
  19. || isInside({ x: (i.x + i.image.width) * 2, y: i.y })
  20. || isInside({ x: (i.x + i.image.width) * 2, y: (i.y + i.image.height) * 2 })
  21. || isInside({ x: i.x, y: (i.y + i.image.height) * 2 });
  22. });
  23. canvas.quadrants.images.forEach(i => i.drawn = false);
  24. }
  25. const imgQ1 = new Image();
  26. imgQ1.src = canvas.url + source + "00";
  27. const imgQ2 = new Image();
  28. imgQ2.src = canvas.url + source + "01";
  29. const imgQ3 = new Image();
  30. imgQ3.src = canvas.url + source + "10";
  31. const imgQ4 = new Image();
  32. imgQ4.src = canvas.url + source + "11";
  33. const imgIndex = canvas.quadrants.images.findIndex(i => imgQ1.src === i.image.src)
  34. const img = canvas.quadrants.images[imgIndex];
  35. if (!!imgIndex || !img.naturalWidth) {
  36. imgQ1.onload = () => {
  37. ctx.drawImage(imgQ1, coords.x, coords.y);
  38. imgQ2.onload = () => ctx.drawImage(imgQ2, coords.x + imgQ1.width, coords.y);
  39. imgQ3.onload = () => ctx.drawImage(imgQ3, coords.x, coords.y + imgQ1.height);
  40. imgQ4.onload = () => ctx.drawImage(imgQ4, coords.x + imgQ1.width, coords.y + imgQ1.height);
  41. canvas.quadrants.images.push({
  42. drawn = true,
  43. image = imgQ1,
  44. images = [imgQ1, imgQ2, imgQ3, imgQ4],
  45. x = coords.x,
  46. y = coords.y
  47. });
  48. };
  49. } else {
  50. const vector = { x: canvas.mouse.x - canvas.mouse.prevX, y: canvas.mouse.y - canvas.mouse.prevY };
  51. ctx.drawImage(imgQ1, img.x + vector.x, img.y + vector.y);
  52. ctx.drawImage(imgQ2, img.x + imgQ1.width + vector.x, img.y + vector.y);
  53. ctx.drawImage(imgQ3, img.x, img.y + imgQ1.height + vector.y);
  54. ctx.drawImage(imgQ4, img.x + imgQ1.width + vector.x, img.y + imgQ1.height + vector.y);
  55. canvas.quadrants.images.splice(imgIndex, 1, Object.assign(img, {
  56. drawn: true,
  57. x: img.x + vector.x,
  58. y: img.x + vector.y
  59. }));
  60. }
  61. if (parseInt(source + "00", 2) >= 2 ** (canvas.level + 1) * 2)
  62. draw(ctx, (parseInt(source, 2) - (2 ** (canvas.level + 1) / 2)).toString(2).padStart(source.length, 0),
  63. { x: img.x, y: img.y - img.height * 2 });
  64. if (true)
  65. draw(ctx, (parseInt(source, 2) + 4).toString(2).padStart(source.length, 0),
  66. { x: img.x + img.width * 2, y: img.y });
  67. if (parseInt(source + "00", 2) < 4 ** (canvas.level + 1) - 2 ** (canvas.level + 1) * 2)
  68. draw(ctx, (parseInt(source, 2) + (2 ** (canvas.level + 1) / 2)).toString(2).padStart(source.length, 0),
  69. { x: img.x, y: img.y + img.height * 2 });
  70. if (parseInt(source + "00", 2) % (2 ** (canvas.level + 1) * 2))
  71. draw(ctx, (parseInt(source, 2) - 4).toString(2).padStart(source.length, 0),
  72. { x: img.x - img.width * 2, y: img.y });
  73. };
  74. const mouseMove = function(e) {
  75. canvas.mouse.x = e.clientX;
  76. canvas.mouse.y = e.clientY;
  77. console.log("Dragging: " + canvas.isDragging);
  78. if (canvas.isDragging) {
  79. draw(canvas.context);
  80. }
  81. canvas.mouse.prevX = e.clientX;
  82. canvas.mouse.prevY = e.clientY;
  83. };
  84. const mouseDown = function(e) {
  85. if (canvas.element === document.activeElement) {
  86. canvas.isDragging = true;
  87. }
  88. };
  89. const mouseUp = function(e) {
  90. canvas.isDragging = false;
  91. };
  92. const init = function() {
  93. canvas = {
  94. url: "http://localhost:5000/image/",
  95. element: document.getElementById("canvas"),
  96. get context() { return canvas.element.getContext("2d"); },
  97. isDragging: false,
  98. mouse: {
  99. x: 0,
  100. y: 0,
  101. prevX: 0,
  102. prevY: 0
  103. },
  104. get boundary() { return canvas.element.getBoundingClientRect(); },
  105. vertex: {
  106. get a() { return { x: canvas.boundary.top + window.scrollY, y: canvas.boundary.left + window.scrollX }; },
  107. get b() { return { x: canvas.boundary.top + window.scrollY, y: canvas.boundary.right }; },
  108. get c() { return { x: canvas.boundary.bottom, y: canvas.boundary.right }; },
  109. get d() { return { x: canvas.boundary.bottom, y: canvas.boundary.left + window.scrollX }; }
  110. },
  111. level: 0,
  112. quadrants: {
  113. width: 0,
  114. height: 0,
  115. images: []
  116. /*{
  117. drawn: false,
  118. image: null,
  119. images: [],
  120. x: 0,
  121. y: 0
  122. }*/
  123. }
  124. };
  125. canvas.element.setAttribute("width", 500); // window.getComputedStyle(document.body).getPropertyValue("width"));
  126. canvas.element.setAttribute("height", 500); // window.getComputedStyle(document.body).getPropertyValue("height"));
  127. document.addEventListener("mousemove", mouseMove);
  128. document.addEventListener("mouseup", mouseUp);
  129. document.addEventListener("mousedown", mouseDown);
  130. draw(canvas.context, "00");
  131. };