@Azat2015

Как сделать, чтобы стрелки не пропадали?

Здравствуйте.
Хочу сделать скрипт, который может в открытом окне браузера рисовать стрелки с подписями.
Подскажите, пжлст, как сделать, чтобы при рисовании новой стрелки не стирались старые? Можно обойтись без создания массива со стрелками? Без onMove стрелки сохраняются, но тогда не видно процесса рисования стрелки.
<!-- index.html -->
<canvas id="canvas"></canvas>

<script>
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");
  let startX, startY, endX, endY;
  // массив для хранения стрелок и текстов
  const elements = [];  

  // загрузка изображения
  const img = new Image();
  img.src = "image.jpg";
  img.onload = function() {
    // устанавливаем размеры canvas равными размерам изображения
    canvas.width = img.width;
    canvas.height = img.height;

    // рисование изображения
    ctx.drawImage(img, 0, 0, img.width, img.height);

    // настройка стиля линий
    ctx.lineWidth = 4;
    ctx.strokeStyle = "#FFB700";
    ctx.fillStyle = "#FFB700";
    ctx.font = "bold 18px sans-serif";

    // обработчик события нажатия кнопки мыши
    canvas.addEventListener("mousedown", function(event) {
      startX = event.offsetX;
      startY = event.offsetY;

      // обработчик события перемещения мыши
      canvas.addEventListener("mousemove", onMove);
    });

    // обработчик события отпускания кнопки мыши
    canvas.addEventListener("mouseup", function(event) {
      endX = event.offsetX;
      endY = event.offsetY;

      // рассчитываем длину и угол стрелки
      const dx = endX - startX;
      const dy = endY - startY;
      const length = Math.sqrt(dx**2 + dy**2);
      const angle = Math.atan2(dy, dx);

      // рисуем линию
      ctx.beginPath();
      ctx.moveTo(startX, startY);
      ctx.lineTo(endX, endY);
      ctx.stroke();

      // рисуем стрелку на конце линии
      ctx.beginPath();
      ctx.moveTo(endX, endY);
      ctx.lineTo(endX - 20 * Math.cos(angle - Math.PI/6), endY - 20 * Math.sin(angle - Math.PI/6));
      ctx.lineTo(endX - 20 * Math.cos(angle + Math.PI/6), endY - 20 * Math.sin(angle + Math.PI/6));
      ctx.closePath();
      ctx.fill();

      // удаляем обработчик события перемещения мыши
      canvas.removeEventListener("mousemove", onMove);
    });

    // функция для обработки перемещения мыши
    function onMove(event) {
      // очищаем canvas
      //ctx.clearRect(0, 0, canvas.width, canvas.height);

      // рисуем изображение
      ctx.drawImage(img, 0, 0, img.width, img.height);

      // рисуем линию от начальной позиции до текущей позиции мыши
      ctx.beginPath();
      ctx.moveTo(startX, startY);
      ctx.lineTo(event.offsetX, event.offsetY);
      ctx.stroke();

      // рисуем стрелку на конце линии
      const dx = event.offsetX - startX;
      const dy = event.offsetY - startY;
      const length = Math.sqrt(dx**2 + dy**2);
      const angle = Math.atan2(dy, dx);
      ctx.beginPath();
      ctx.moveTo(event.offsetX, event.offsetY);
      ctx.lineTo(event.offsetX - 10 * Math.cos(angle - Math.PI/6), event.offsetY - 10 * Math.sin(angle - Math.PI/6));
      ctx.lineTo(event.offsetX - 10 * Math.cos(angle + Math.PI/6), event.offsetY - 10 * Math.sin(angle + Math.PI/6));
      ctx.closePath();
      ctx.fill();
    }
	
	    // обработчик события клика мыши
    canvas.addEventListener("click", function(event) {

      // рисуем текст
      ctx.fillText(prompt("Введите текст"), startX+10, startY+10);
    });
  };
</script>
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ответы на вопрос 1
@iljaGolubev
придумать как использовать старый канвас
newCtx.drawImage(oldCtx, 0, 0, img.width, img.height);

Если поддержка safari не нужна, то пробовать через OffscreenCanvas

Но лучше сразу массивы прикручивать - не ждать пока UX потребует отменить последнее действие. Можно взять что-то готовое, к примеру, это.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы