Google Maps API v3:自定义叠加层,画布图未在Safari中接收事件

时间:2012-03-23 20:21:56

标签: javascript google-maps google-maps-api-3 browser dom-events

我正在尝试在Google Maps API v3中实现自定义叠加层,并通过canvas元素完成一些自定义绘制。基本上我从API中复制了Polygon元素,但是能够从用户接收事件(目标是删除区域上的一些东西,原生拖放)。

因此绘图工作正常,我将一个监听器附加到canvas元素,这就是麻烦发生的地方。 Safari(使用5.1.4测试)提供事件,直到我通过检索上下文并添加路径对canvas元素进行绘制。对于Chrome(17),Firefox(10)和Opera(11),没有问题。

您可以查看页面here。当您单击地图中心的灰色多边形时,应在地图下方添加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();
  }

}

我测试了不同的事件(点击,鼠标悬停,dragenter等),不同的方式来附加事件(通过google.maps.event.addDOMListener,浏览器addEventListener和jQuery on),同样的结果:Safari拒绝播放,而其他人按预期工作,触发我的功能。

我还尝试将叠加层添加到另一个地图窗格,例如overlayMouseTarget或floatPane,而不进行其他更改。

为了再试一次,我实现了一个简单的画布(具有相同的形状,或多或少相同的绘制过程)来测试Safari是否在这种情况下收到事件,是的,它正在工作。

对一个简单的div元素做同样的工作是完美的,一旦我开始在画布上绘制就会出现问题。

我不确定我做错了什么,或者Google Maps API和Safari之间是否存在错误。因此,如果您能够完成我刚刚写完的整个故事,那么您的帮助将会非常受欢迎。)

由于

修改 显然,Brendan Kenny报告OS X 10.6.8和Safari 5.1.2没有问题。我用OS X 10.6.8和Safari 5.0.5进行了测试,没有任何问题。

我创建了第二页here,除了删除绘图部分之外没有其他任何更改(我删除了draw方法中画布中使用上下文的所有部分)。单击红色矩形时,下面的div中会添加一个“plop”,它在Safari 5.1.4中按预期工作。

编辑2 在Safari 6.0中修复,我想我不会知道发生了什么。

1 个答案:

答案 0 :(得分:1)

Google 真的不喜欢这种技巧。他们的画布和你的画布将争夺z-index,只有一个会收到鼠标事件,并且A)你的东西会起作用,但是你将无法点击/平移/缩放地图或B)反之亦然。您可能有时可以让它工作,但是在平移地图后它将无法工作,因为新的磁贴将以更高的z-index进入。如果你添加谷歌的控件或尝试使用双指触控板缩放,你会看到那些不起作用。

使用Google的Polygon类等,所有这些都应该适合全世界。我从经验中说话 - 我试图以这种方式完成我的项目,然后碰到同一堵墙。我倾向于谷歌的意志,一切都是时髦的。