ghettovoice / vuelayers

Web map Vue components with the power of OpenLayers
https://vuelayers.github.io/
MIT License
682 stars 230 forks source link

mouse events passthrough using vl-overlay and d3 #441

Closed wendellwt closed 2 years ago

wendellwt commented 3 years ago

Hello,

I added a d3.js svg overlay to the map using vl-overlay, and that works fine. However, the D3 svg div captures all mouse events and doesn't pass them to vuelayers. I don't know if it is a d3 issue, a vuelayers issue, or an html/css/div issue, and I would like advice.

Here is a fiddle that shows the issue: https://jsfiddle.net/wendellwt/haeqg0o3/69/ The svg div is 100px x 100px and the dot is in the middle. The map cannot be moved with the mouse while the mouse is within the svg div area, only when the mouse is outside the svg div area.

Setting the css of the svg div to pointer-events: none; doesn't help.

What can I do to make the overlay containing D3's svg div not trap the mouse events and pass them to the map?

wendellwt commented 2 years ago

It is possible to convert the svg div to an image and use that as an icon: https://jsfiddle.net/wendellwt/jfwv3nau/106/ However, doing it that way doesn't allow any interactions with D3 (mouseover/tooltip, transitions, etc.).

The OL examples has an SVG example that uses map.addLayer( new Layer() ). There is also a D3 example that uses a Canvas layer. Both of those seem to use a render() function to map between those layers and the map layer. Which of those methods would work best with vuelayers?

ghettovoice commented 2 years ago

Hello @wendellwt , to allow pointer event passing through overlay there is special property stopEvent on the vl-overlay.

<vl-overlay id="my_overlay" :position="coords" positioning='center-center' :stop-event="false">
     <div id="my-svg"
          class="my-class"
          style="width: 100px; height: 100px; background-color='transparent'">
     </div>        
</vl-overlay>

As for ol examples: svg and d3. I can't say which one will work best, didn't any similar things yet. I can only show how to setup them with vuelayers:

<template>
    <vl-map @created="mapCreated">...</vl-map>
</template>

<script>
import Layer from 'ol/layer/Layer'

export default {
    methods: {
        mapCreated (vm) {
          // vm - vl-map instance
          // map - ol/Map instance
          const map = vm.$map

          // add any custom layer manually
          map.addLayer(new Layer ({ render: ... }))
        },
    }
}
</script>
wendellwt commented 2 years ago

Great! That's just what I was looking for. Thank you!

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.