ako977
ako977

Reputation: 792

Setting mapbox-gl marker from click event causes strange artifacts to appear on map in VueJS

mapbox-gl-js version: 0.53.1

browser: Google Chrome Version 73.0.3683.86 (Official Build) (64-bit) and Firefox 66.0.2 (64-bit)

OS: MacOS Mojave 10.14.4

Steps to Trigger Behavior

  1. Implement mapbox in VueJS Single Page Application
  2. Select feature on marker Selected feature triggers click event with this.currentMap.on('click', layerId, callbackFunc)
  3. callbackFunc runs the function described below to set the marker on the map. The artifacts only appear when the marker is set on the map, not on the click event
  4. The map is removed and listeners destroyed, but creating a new mapbox instance still shows the artifacts; only a full browser reload clears it until the feature is clicked again

The features are on a layer made of a defined source (below):

{
      'type': 'FeatureCollection',
      'features': [{
        'type': 'Feature',
        'geometry': {
          'type': 'Point',
          'coordinates': [X, Y]
        },
        'properties': o
      }, ...]
    }

and a layer defined below:

 {
         'id': <layerId>,
         'type': 'circle',
         'source': <sourceId>,
         'minzoom': <displayAtZoomLevel>,
         'icon-allow-overlap': true,
         'paint': {
           // make circles larger as the user zooms from <displayAtZoomLevel> to z22
          'circle-radius': {
            'base': 2,
            'stops': [[<displayAtZoomLevel>, 3], [22, 180]]
           },
           // https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
          'circle-color': '#fff',
          'circle-stroke-width': 1,
          'circle-stroke-color': '#204da2'
       }
    }

Expected Behavior

Map should appear as normal with a marker

enter image description here

Actual Behavior

Map shows scrambled artifacts especially on roads, etc. when Map marker is added using the following code:

setMarker (markerContext, { lng, lat }, requestRouteCallback) {
    let lngLat = [Number(lng), Number(lat)]
    if (lngLat.length) {
      const marker = new mapboxgl.Marker().setLngLat(lngLat).addTo(this.currentMap)
      if (markerContext === 'start') {
        if (this.startEndMarkers.start) {
          this.startEndMarkers.start.remove()
        }
        this.startEndMarkers.start = marker
      } else if (markerContext === 'end') {
        if (this.startEndMarkers.end) {
          this.startEndMarkers.end.remove()
        }
        this.startEndMarkers.end = marker
      }
      this.currentMap.flyTo({ center: lngLat, zoom: 12, curve: 2 })
    }
}

Map shows this:

enter image description here

Initially posting this on Mapbox GL's github gave a possible hint that the map is painting dashed pathways on streets. I have found that it seems to occur when the map under goes some movement, like a pan or zoom. If I place a marker on the map without causing any movement, the artifacts do not appear.

Upvotes: 0

Views: 1019

Answers (2)

cweitat
cweitat

Reputation: 1257

You need to freeze the map's instance prior to making any actions to it. https://github.com/vuejs/vue/issues/2637#issuecomment-331913620

Freeze the object to prevent the map from disorientated and for any actions done to the map, call back the data with an extra Object key which in case is 'wrapper'. You can replace panMap with any other functions that you want to do with the map

<template><MglMap :accessToken="..." :mapStyle="..." @load="onMapLoaded" /></template>
    
<script>  
methods: {  
 onMapLoaded(event) {
   this.mapboxEvent = Object.freeze({wrapper: event.map});
 },
 panMap(event) {
   this.mapboxEvent.wrapper.panTo([lng, lat], {duration: 1000, zoom: 14});
 }
}
</script>

Reference question: Mapbox style changes/breaks on zoom when a layer is added

Upvotes: 0

ako977
ako977

Reputation: 792

So far I have found a way to solve the issue, yet I still do not know exactly why.

I am passing the event object to some other function on click and pulling the map feature from the event object.

If I deep clone the feature in the event object before passing it to my other functions, the artifacts do not appear.

Upvotes: 0

Related Questions