露天层:两个手指运动(Dragpan)



Google最近重新设计了地图移动行为。现在,在移动设备上,您可以用两个手指移动地图。(请参阅手机上的地图简单示例,而不是任何浏览器模拟器!)。

我想在OpenLayer中实现相同的功能。检测移动设备(例如Wurfl),禁用dragPan不是问题,但是如何编写自己的ol.interaction.Interaction与两个手指一起工作?

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

阻力交互通常带有'条件'选项。您提供一个函数,采用一个参数( ol.mapbrowserevent )并返回一个布尔值,指示是否应适用互动。

ol.mapbrowserevent 包装原始浏览器事件,这意味着您可以在其中查找触摸数组,并检查它是否长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> 

上一个答案说使用ol.BrowserEvent.originalEvent.touches。调试时,我发现事件类型为pointerdown。我看到的消息来源说,指针降低事件没有touches元素,这解释了我看到的内容以及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
      })
    })