Я пытаюсь реализовать пользовательское наложение в 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, думаю, яне будет знать, что случилось.