ymaps нарисовать область поиска на карте ymaps.control.Button

Мне необходимо при нажатии кнопки ymaps.control.Button рисовать несколько областей выбора на карте. Яндекс предлагает такой вариант: https://tech.yandex.ru/maps/jsbox/2.1/polygon_custom. Как изменить алгоритм чтобы рисование области происходило без зажатой клавиши "Alt" и можно было по клику кнопки переключаться с перетаскивания на рисование. В примере ниже я пробовал сделать это через selectOnClick для ymaps.control.Button. Однако процесс рисования продолжает выполнение если повторно нажать на кнопку.

Как сделать закраску выделенной области ?

ymaps.ready(['ext.paintOnMap']).then(function() {
  var map = new ymaps.Map('map', {
    center: [55.75, 37.62],
    zoom: 14,
    controls: []
  });

  var paintProcess;

  // Опции многоугольника или линии.
  var styles = [{
    strokeColor: '#e25e71',
    strokeOpacity: 1,
    strokeWidth: 3,
    fillColor: '#36A8E2',
    fillOpacity: 0.5
  }];

  var currentIndex = 0;
  let painting = false;


  // Создадим кнопку для выбора типа рисуемого контура.
  var button = new ymaps.control.Button({
    data: {
      content: 'Polygon / Polyline'
    },
    options: {
      maxWidth: 150,
      selectOnClick: true
    }
  });
  map.controls.add(button);

  // Подпишемся на событие нажатия кнопки мыши.

  button.events

    .add('select', function() {

      painting = true;
      map.events.add('mousedown', function(e) {
        if (painting === true) {
          if (currentIndex == styles.length - 1) {
            currentIndex = 0;
          } else {
            currentIndex += 1;
          }
          paintProcess = ymaps.ext.paintOnMap(map, e, {
            style: styles[currentIndex]
          });
        }


        // Если кнопка мыши была нажата с зажатой клавишей "alt", то начинаем рисование контура.
        // if (e.get('altKey')) {
        // }
      });
      map.events.add('mouseup', function(e) {

        // console.log(painting, paintProcess);

        if (painting === true) {
          if (paintProcess) {
            // Получаем координаты отрисованного контура.
            let coordinates = paintProcess.finishPaintingAt(e);
            coordinates.push(coordinates[0])
            //console.log(coordinates)
            paintProcess = null;
            // В зависимости от состояния кнопки добавляем на карту многоугольник или линию с полученными координатами.
            var geoObject = button.isSelected() ?
              new ymaps.Polyline(coordinates, {}, styles[currentIndex]) :
              new ymaps.Polygon([coordinates], {}, styles[currentIndex]);

            map.geoObjects.add(geoObject);
          }

        }

      });


      // }
    })

    .add('deselect', function() {




      painting = false;
      $(document).trigger("mouseup");
      return painting;
    });


  // Подпишемся на событие отпускания кнопки мыши.

}).catch(console.error);









///// paintOnMap.js







ymaps.modules.define('ext.paintOnMap', ['meta', 'util.extend', 'pane.EventsPane', 'Event'], function(provide, meta, extend, EventsPane, Event) {
  'use strict';

  // zIndex пейна событий карты по умолчанию равен 500.
  // Подробней в документации: https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/map.pane.Manager-docpage/
  var EVENTS_PANE_ZINDEX = 500;

  var DEFAULT_UNWANTED_BEHAVIORS = ['drag', 'scrollZoom'];
  var DEFAULT_STYLE = {
    strokeColor: '#0000ff',
    strokeWidth: 1,
    strokeOpacity: 1
  };
  var DEFAULT_TOLERANCE = 16;

  var badFinishPaintingCall = function() {
    throw new Error('(ymaps.ext.paintOnMap) некорректный вызов PaintingProcess#finishPaintingAt. Рисование уже завершено.');
  };

  /**
   * @interface ymaps.ext.paintOnMap.PaintingProcess
   */

  /**
   * Отключает режим рисования.
   * @function
   * @name ymaps.ext.paintOnMap.PaintingProcess#finishPaintingAt
   * @param {Number[]|ymaps.Event} [positionOrEvent] Координаты точки, в которой рисование должно закончиться.
   * Координаты задаются в пикселях относительно верхнего левого угла карты.
   * @return {Number[]} Координаты.
   */

  /**
   * Включает режим рисования.
   * @name ymaps.ext.paintOnMap
   * @param {ymaps.Map} map
   * @param {Number[]|ymaps.Event} [positionOrEvent] Координаты точки, в которой рисование должно закончиться.
   * Координаты задаются в пикселях относительно верхнего левого угла карты.
   * @param {Object} [config]
   * @param {String[]|null} [config.unwantedBehaviors] Список поведений карты, которые должны быть выключены во время
   * рисования. Перетаскивание карты и её масштабирование колесом мыши выключены по умолчанию.
   * @param {Object} [config.style] Стили такие же, как в ymaps.Polygon или ymaps.Polyline.
   * @param {String} [config.style.strokeColor='#0000ff'] Цвет линии или обводки.
   * @param {Number} [config.style.strokeWidth=1] Толщина линии или обводки.
   * @param {Number} [config.style.strokeOpacity=1] Прозрачность линии или обводки.
   * @param {Number} [config.tolerance=16] Уровень упрощения координат в пикселях.
   * @returns {ymaps.ext.paintOnMap.PaintingProcess} Процесс рисования.
   */
  function paintOnMap(map, positionOrEvent, config) {
    config = config || {};
    var style = extend(DEFAULT_STYLE, config.style || {});

    var unwantedBehaviors = config.unwantedBehaviors === undefined ?
      DEFAULT_UNWANTED_BEHAVIORS : config.unwantedBehaviors;

    var pane = new EventsPane(map, {
      css: {
        position: 'absolute',
        width: '100%',
        height: '100%'
      },
      zIndex: EVENTS_PANE_ZINDEX + 50,
      transparent: true
    });

    map.panes.append('ext-paint-on-map', pane);

    if (unwantedBehaviors) {
      map.behaviors.disable(unwantedBehaviors);
    }

    // Создаём canvas-элемент.
    var canvas = document.createElement('canvas');
    var ctx2d = canvas.getContext('2d');
    var rect = map.container.getParentElement().getBoundingClientRect();
    canvas.width = rect.width;
    canvas.height = rect.height;

    ctx2d.globalAlpha = style.strokeOpacity;
    ctx2d.strokeStyle = style.strokeColor;
    ctx2d.lineWidth = style.strokeWidth;

    canvas.style.width = '100%';
    canvas.style.height = '100%';

    pane.getElement().appendChild(canvas);

    var firstPosition = positionOrEvent ? toPosition(positionOrEvent) : null;
    var coordinates = firstPosition ? [firstPosition] : [];

    var bounds = map.getBounds();
    var latDiff = bounds[1][0] - bounds[0][0];
    var lonDiff = bounds[1][1] - bounds[0][1];

    canvas.onmousemove = function(e) {
      coordinates.push([e.offsetX, e.offsetY]);

      ctx2d.clearRect(0, 0, canvas.width, canvas.height);
      ctx2d.beginPath();

      ctx2d.moveTo(coordinates[0][0], coordinates[0][1]);
      for (var i = 1; i < coordinates.length; i++) {
        ctx2d.lineTo(coordinates[i][0], coordinates[i][1]);
      }

      ctx2d.stroke();
    }.bind(this);

    // Создаём косвенное обращение, чтобы не сдерживать сборщик мусора.
    var paintingProcess = {
      finishPaintingAt: function(positionOrEvent) {
        paintingProcess.finishPaintingAt = badFinishPaintingCall;

        // Получаем координаты, прежде чем удалить пейн.
        if (positionOrEvent) {
          coordinates.push(toPosition(positionOrEvent));
        }

        map.panes.remove(pane);
        if (unwantedBehaviors) {
          map.behaviors.enable(unwantedBehaviors);
        }

        var tolerance = config.tolerance === undefined ? DEFAULT_TOLERANCE : Number(config.tolerance);
        if (tolerance) {
          coordinates = simplify(coordinates, tolerance);
        }
        // Преобразовываем координаты canvas-элемента в геодезические координаты.
        return coordinates.map(function(x) {
          var lon = bounds[0][1] + (x[0] / canvas.width) * lonDiff;
          var lat = bounds[0][0] + (1 - x[1] / canvas.height) * latDiff;

          return meta.coordinatesOrder === 'latlong' ? [lat, lon] : [lon, lat];
        });
      }
    };

    return paintingProcess;
  }

  function toPosition(positionOrEvent) {
    return positionOrEvent instanceof Event ? [positionOrEvent.get('offsetX'), positionOrEvent.get('offsetY')] :
      positionOrEvent;
  }

  function simplify(coordinates, tolerance) {
    var toleranceSquared = tolerance * tolerance;
    var simplified = [coordinates[0]];

    var prev = coordinates[0];
    for (var i = 1; i < coordinates.length; i++) {
      var curr = coordinates[i];
      if (Math.pow(prev[0] - curr[0], 2) + Math.pow(prev[1] - curr[1], 2) > toleranceSquared) {
        simplified.push(curr);
        prev = curr;
      }
    }

    return simplified;
  }

  provide(paintOnMap);
});
<!DOCTYPE html>
<html>

<head>
  <title>Нарисовать произвольную область на карте</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <!--
        Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
        Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
    -->
  <script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;apikey=<ваш API-ключ>" type="text/javascript"></script>
  <script src="paintOnMap.js" type="text/javascript"></script>
  <script src="polygon_custom.js" type="text/javascript"></script>
  <style>
    html,
    body {
      width: 100%;
      height: 95%;
      padding: 0;
      margin: 0;
      font-family: Arial;
    }
    
    #map {
      widht: 100%;
      height: 90%;
    }
    
    p {
      font-family: Sans-Serif;
      font-size: 12px;
      padding: 12px 0px 12px 10px;
      margin: 0px;
    }
  </style>
</head>

<body>
  <p>Чтобы включить режим рисования, нужно нажать левую кнопку мыши, зажав клавишу "alt".</p>
  <div id="map"></div>
  <canvas id="draw-canvas"></canvas>
</body>

</html>


Ответы (0 шт):