less copy protection, more size visualization
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

212 строки
5.4 KiB

  1. let selected = null;
  2. let selectedEntity = null;
  3. let entityIndex = 0;
  4. let clicked = null;
  5. let dragging = false;
  6. let clickTimeout = null;
  7. let dragOffsetX = null;
  8. let dragOffsetY = null;
  9. const config = {
  10. height: math.unit(10, "meters")
  11. }
  12. const entities = {
  13. }
  14. function updateSizes() {
  15. drawScale();
  16. Object.entries(entities).forEach(([key, entity]) => {
  17. const element = document.querySelector("#entity-" + key);
  18. const canvasHeight = document.querySelector("#display").clientHeight;
  19. const pixels = math.divide(entity.height, config.height) * canvasHeight;
  20. element.style.setProperty("--height", pixels + "px");
  21. });
  22. }
  23. function drawScale() {
  24. function drawTicks(/** @type {CanvasRenderingContext2D} */ ctx, pixelsPer) {
  25. for (let y = ctx.canvas.clientHeight - 50; y >= 50; y -= pixelsPer) {
  26. drawTick(ctx, 50, y);
  27. }
  28. }
  29. function drawTick(/** @type {CanvasRenderingContext2D} */ ctx, x, y) {
  30. const oldStyle = ctx.strokeStyle;
  31. ctx.beginPath();
  32. ctx.moveTo(x, y);
  33. ctx.lineTo(x + 20, y);
  34. ctx.strokeStyle = "#000000";
  35. ctx.stroke();
  36. ctx.beginPath();
  37. ctx.moveTo(x + 20, y);
  38. ctx.lineTo(ctx.canvas.clientWidth - 70, y);
  39. ctx.strokeStyle = "#aaaaaa";
  40. ctx.stroke();
  41. ctx.beginPath();
  42. ctx.moveTo(ctx.canvas.clientWidth - 70, y);
  43. ctx.lineTo(ctx.canvas.clientWidth - 50, y);
  44. ctx.strokeStyle = "#000000";
  45. ctx.stroke();
  46. ctx.strokeStyle = oldStyle;
  47. }
  48. const canvas = document.querySelector("#display");
  49. /** @type {CanvasRenderingContext2D} */
  50. const ctx = canvas.getContext("2d");
  51. const pixelsPer = (ctx.canvas.clientHeight - 100) / config.height.value;
  52. ctx.clearRect(0, 0, canvas.width, canvas.height);
  53. ctx.scale(1, 1);
  54. ctx.canvas.width = canvas.clientWidth;
  55. ctx.canvas.height = canvas.clientHeight;
  56. ctx.beginPath();
  57. ctx.moveTo(50, 50);
  58. ctx.lineTo(50, ctx.canvas.clientHeight - 50);
  59. ctx.stroke();
  60. ctx.beginPath();
  61. ctx.moveTo(ctx.canvas.clientWidth - 50, 50);
  62. ctx.lineTo(ctx.canvas.clientWidth - 50, ctx.canvas.clientHeight - 50);
  63. ctx.stroke();
  64. drawTicks(ctx, pixelsPer);
  65. }
  66. function makeEntity() {
  67. const entityTemplate = {
  68. name: "",
  69. author: "",
  70. height: math.unit(Math.random() * 2 + 1, "meters")
  71. }
  72. return entityTemplate;
  73. }
  74. function clickDown(e) {
  75. clicked = e.target;
  76. const rect = e.target.getBoundingClientRect();
  77. let entX = document.querySelector("#entities").getBoundingClientRect().x;
  78. let entY = document.querySelector("#entities").getBoundingClientRect().y;
  79. dragOffsetX = e.clientX - rect.left + entX;
  80. dragOffsetY = e.clientY - rect.top + entY;
  81. clickTimeout = setTimeout(() => {dragging = true}, 100)
  82. }
  83. function clickUp() {
  84. clearTimeout(clickTimeout);
  85. if (clicked) {
  86. if (dragging) {
  87. dragging = false;
  88. } else {
  89. select(clicked);
  90. }
  91. clicked = null;
  92. }
  93. }
  94. function deselect() {
  95. if (selected) {
  96. selected.classList.remove("selected");
  97. }
  98. selected = null;
  99. }
  100. function select(target) {
  101. deselect();
  102. selected = target;
  103. selectedEntity = entities[target.dataset.key];
  104. selected.classList.add("selected");
  105. entityInfo(selectedEntity);
  106. }
  107. function entityInfo(entity) {
  108. document.querySelector("#entity-name").innerText = "Name: " + entity.name;
  109. document.querySelector("#entity-author").innerText = "Author: " + entity.author;
  110. document.querySelector("#entity-height").innerText = "Height: " + entity.height.format({ precision: 3 });
  111. }
  112. function displayEntity(entity, x, y) {
  113. const location = entity.location;
  114. const img = document.createElement("img");
  115. img.src = "./pepper.png"
  116. img.classList.add("entity");
  117. img.style.left = x + "px";
  118. img.style.top = y + "px";
  119. img.addEventListener("mousedown", e => clickDown(e));
  120. img.id = "entity-" + entityIndex;
  121. img.dataset.key = entityIndex;
  122. entities[entityIndex] = entity;
  123. entityIndex += 1;
  124. const world = document.querySelector("#entities");
  125. world.appendChild(img);
  126. }
  127. document.addEventListener("DOMContentLoaded", () => {
  128. for (let x = 0; x < 5; x++) {
  129. const entity = makeEntity();
  130. entity.name = "Green is my pepper";
  131. entity.author = "Fen"
  132. const x = 300 + Math.random() * 600;
  133. const y = 300 + Math.random() * 400;
  134. displayEntity(entity, x, y);
  135. }
  136. updateSizes();
  137. document.querySelector("#options-height-value").addEventListener("input", e => {
  138. updateWorldHeight();
  139. })
  140. document.querySelector("#options-height-unit").addEventListener("input", e => {
  141. updateWorldHeight();
  142. })
  143. const entities = document.querySelector("#entities");
  144. world.addEventListener("mousedown", e => deselect());
  145. document.addEventListener("mouseup", e => clickUp());
  146. });
  147. window.addEventListener("resize", () => {
  148. updateSizes();
  149. })
  150. document.addEventListener("mousemove", (e) => {
  151. if (clicked) {
  152. clicked.style.left = (e.clientX - dragOffsetX) + "px";
  153. clicked.style.top = (e.clientY - dragOffsetY) + "px";
  154. }
  155. });
  156. function updateWorldHeight() {
  157. const value = document.querySelector("#options-height-value").value;
  158. const unit = document.querySelector("#options-height-unit").value;
  159. config.height = math.unit(value + " " + unit)
  160. updateSizes();
  161. }