less copy protection, more size visualization
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

210 lignes
5.3 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. world.addEventListener("mousedown", e => deselect());
  144. document.addEventListener("mouseup", e => clickUp());
  145. });
  146. window.addEventListener("resize", () => {
  147. updateSizes();
  148. })
  149. document.addEventListener("mousemove", (e) => {
  150. if (clicked) {
  151. clicked.style.left = (e.clientX - dragOffsetX) + "px";
  152. clicked.style.top = (e.clientY - dragOffsetY) + "px";
  153. }
  154. });
  155. function updateWorldHeight() {
  156. const value = document.querySelector("#options-height-value").value;
  157. const unit = document.querySelector("#options-height-unit").value;
  158. config.height = math.unit(value + " " + unit)
  159. updateSizes();
  160. }