Google Maps API v3: пользовательский оверлей с рисованием на холсте, не получающий события в Safari - PullRequest
4 голосов
/ 24 марта 2012

Я пытаюсь реализовать пользовательское наложение в API Карт Google v3, причем некоторые пользовательские рисунки выполняются с помощью элемента canvas.По сути, я воспроизводлю элемент Polygon из API, но с возможностью получать события от пользователя (цель состоит в том, чтобы добавить некоторые вещи в зону с помощью встроенного drag'n drop).

Так что рисование работаетхорошо, я прикрепляю слушателя к элементу canvas, и вот тут возникают проблемы.Safari (протестировано с 5.1.4) доставляет событие, пока я не начну рисовать элемент canvas, извлекая контекст и добавляя путь.Для Chrome (17), Firefox (10) и Opera (11) проблем нет.

Вы можете просмотреть страницу здесь .Когда вы щелкаете по серому многоугольнику в центре карты, под картой необходимо добавить plop, чтобы убедиться, что событие было доставлено.

Вот некоторые части кода, сначала создаваяналожение и добавление его на панели.

EventReceiverOverlay.prototype.onAdd = function() {
  var holder = document.createElement('canvas');
  holder.style.opacity = 0.5;
  this.canvas_ = holder;

  google.maps.event.addDomListener(holder, 'click', function(event) {
/*      holder.addEventListener('click', function(event) { */
    document.getElementById('message_container').innerHTML += 'plop';
  }, false);

  this.getPanes().overlayLayer.appendChild(holder);
}

Затем рисуем наложение (updateScreenPoints позволяет преобразовать все координаты точек в пиксельные координаты):

EventReceiverOverlay.prototype.draw = function() {
  var overlayProjection = this.getProjection();

  var swCorner = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var neCorner = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  this.updateScreenPoints();
  var canvas = this.canvas_;

  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    ctx.save();

    ctx.strokeStyle = '#f00';
    ctx.lineWidth = 2;
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.style.width, canvas.style.height);

    canvas.style.position = 'relative';
    canvas.style.left = Math.round(swCorner.x) + 'px';
    canvas.style.top = Math.round(neCorner.y) + 'px';

    ctx.beginPath();
    ctx.moveTo(this.screenPoints_[0].x, this.screenPoints_[0].y);
    for (var i = 1; i < this.screenPoints_.length; i++) {
      ctx.lineTo(this.screenPoints_[i].x, this.screenPoints_[i].y);
    }
    ctx.fill();
    ctx.restore();
  }

}

Я тестировал сразличные события (щелчок, наведение мыши, перетаскивание и т. д.), различные способы прикрепления события (через google.maps.event.addDOMListener, браузер addEventListener и jQuery on) с одинаковыми результатами: Safari отказывается играть красиво, тогда какдругие работают как положено, вызывая мою функцию.

Я также попытался добавить наложение на другую панель карты, такую ​​как overlayMouseTarget или floatPane, без дополнительных изменений.

Чтобы дать еще одну попыткуЯ реализовал простой холст (с той же формой, более или менее одинаковым процессом рисования), чтобы проверить, получает ли Safari событие в этом случае, и да, это 'работает.

То же самое с простым элементом div работает отлично, проблема возникает, как только я начинаю рисовать на холсте.

Я не уверен в том, что я сделал неправильно или есть ли ошибка между Google Maps API и Safari.Так что ваша помощь будет очень признательна, если вам удастся пройти весь рассказ, который я только что написал:)

Спасибо

Редактировать Очевидно, что, как сообщает Брендан Кенни, нетпроблемы с OS X 10.6.8 и Safari 5.1.2.Я протестировал его с OS X 10.6.8 и Safari 5.0.5, но также без проблем.

Я сделал вторую страницу, здесь , без каких-либо других изменений, кроме удаления чертежной части.(Я удалил все части, которые использовали контекст из холста в методе draw).При нажатии на красный прямоугольник в div ниже добавляется «plop», и он работает как положено в Safari 5.1.4.

Редактировать 2 Исправлено в Safari 6.0, думаю, яне будет знать, что случилось.

1 Ответ

1 голос
/ 16 мая 2012

Google действительно не любит эту технику. Их холст и ваш холст будут бороться за z-индекс, только одно получит событие мыши, и либо А) ваши вещи будут работать, но вы не сможете нажимать / перемещать / увеличивать карту или Б) и наоборот. Вы могли бы иногда заставить его работать, но тогда после панорамирования карты это не будет работать, потому что новые плитки появятся с более высоким z-индексом. Если вы добавите элементы управления Google или попробуете использовать масштабирование трекпада двумя пальцами, вы увидите, что они не работают.

Используйте класс Google Polygon и т. Д., И все должно быть в порядке с миром. Я говорю из опыта - я пытался сделать свой проект таким образом и ударил в ту же стену. Я склонился к воле Google, и все отлично.

...