Openlayer:双指运动(dragPan)

时间:2017-03-13 16:54:28

标签: openlayers

谷歌最近重新设计了地图移动行为。现在在手机上你可以用两根手指移动地图。 (请参阅手机上的map-simple示例,而不是任何浏览器模拟器!)。

我想在openlayer中实现相同的功能。检测移动设备(例如WURFL),禁用dragPan不是问题,但如何编写自己的ol.interaction.Interaction以便用两根手指进行操作?

我查看了doku并没有找到任何示例,从哪里开始。

2 个答案:

答案 0 :(得分:1)

拖动交互通常带有“条件”选项。您提供了一个函数,它接受一个参数( ol.MapBrowserEvent )并返回一个布尔值,指示交互是否应该应用。

ol.MapBrowserEvent 包装原始浏览器事件,这意味着您只需在其上查找touches数组并检查它是否为长度为2。

<script>
    var map = new ol.Map({
        interactions: [
            new ol.interaction.DragPan({

                // This comment marks the beginning of the code of interest.

                condition: function(olBrowserEvent) {
                    if (olBrowserEvent.originalEvent.touches)
                        return olBrowserEvent.originalEvent.touches.length === 2;
                    return false;
                }

                // This comment marks the end.

            })
        ],
        layers: [
            // Your layers.
        ],
        target: 'map',
        view: new ol.View({
            center: [-33519607, 5616436],
            rotation: -Math.PI / 8,
            zoom: 8
        })
    });
</script> 

答案 1 :(得分:0)

上一个答案说使用 olBrowserEvent.originalEvent.touches。 调试时我发现事件类型是pointerdown。我看到消息来源说向下的指针没有触摸元素来解释我所看到的内容以及 Josh Mc 评论的内容。

我决定解决这个问题,我会自己计算触摸次数:

this.olMap.on('pointerdown', function (event) {
  TTT.cuncurrentTouches += 1
})
this.olMap.on('pointerup', function (event) {
  TTT.cuncurrentTouches -= 1
  if (TTT.concurrentTouches < 0) {
    TTT.cuncurrentTouches = 0
  }
})

我还发现之前的解决方案导致所有地图交互都被删除,只添加了平移。我不想将它们全部删除;相反,我只想替换 DragPan 交互。我通过创建一个没有 DragPan 的默认动作列表并添加我自己的 DragPan 来做到这一点。这会导致交互顺序评估发生变化,但它似乎适用于我的笔记本电脑和手机测试。

var interactions = defaultInteractions({ dragPan: false })
interactions.extend([
  new DragPan({
    condition: function (olBrowserEvent) {
      if (olBrowserEvent.originalEvent.pointerType !== 'touch') {
        return true // Mouse scroll will always work
      }
      if (TTT.cuncurrentTouches === 2) {
        return true
      }
    }
  })
])

this.olMap = new Map({
  target: this.$refs['openlayer-map-root'],
  interactions: interactions,
  layers: [
    // adding a background tiled layer
    new TileLayer({
      source: new OSM() // tiles are served by OpenStreetMap
    }),
    this.vectorLayer
  ],

  view: new View({
    zoom: 16,
    center: fromLonLat(center),
    constrainResolution: true
  })
})