diff --git a/src/components/VMapbox.vue b/src/components/VMapbox.vue
index d23c7c6..117d14e 100644
--- a/src/components/VMapbox.vue
+++ b/src/components/VMapbox.vue
@@ -4,6 +4,7 @@
Note: If you put a id on the main element it won't work with multiple maps on one page (for example with compare plugin).
-->
+
diff --git a/src/components/v-mapbox-layer.js b/src/components/v-mapbox-layer.js
index 6d84651..c3a67d7 100644
--- a/src/components/v-mapbox-layer.js
+++ b/src/components/v-mapbox-layer.js
@@ -1,44 +1,80 @@
export default {
name: 'v-mapbox-layer',
- render () { },
- data () {
- return {
- };
- },
+
+ inject: ['getMap'],
+
+ render: () => null,
+
props: {
options: {
- default: () => {
- return {};
- },
- type: [Object, String]
+ type: Object,
+ default: () => ({})
},
- // allows to place a layer before another
+
+ // Allows to place a layer before another
before: {
type: String,
- required: false
+ default: undefined
}
},
- mounted () {
- },
+
+ data: () => ({
+ isInitialized: false
+ }),
+
methods: {
- deferredMountedTo(map) {
- // if we were already mounted, we need to remove the old layr
- let oldLayer = map.getLayer(this.options.id)
- if (oldLayer) {
- map.removeLayer(this.options.id)
- try {
- map.removeSource(oldLayer.source)
- } catch {
- console.warn('could not remove source', oldLayer.source)
+ deferredMountedTo() {
+ if(!this.isInitialized) {
+ this.renderLayer();
+ this.isInitialized = true;
+ }
+ },
+
+ renderLayer() {
+ this.removeLayer();
+ this.addLayer();
+ },
+
+ addLayer() {
+ const map = this.getMap();
+ map.addLayer(this.options, this.before);
+ },
+
+ removeLayer() {
+ const map = this.getMap();
+ if(map) {
+ const layerId = this.options.id;
+ const layer = map.getLayer(layerId);
+ if(layer) {
+ const layerSource = layer.source;
+ map.removeLayer(layerId);
+ if(layerSource && !map.getStyle().layers.some(({ source }) => source === layerSource)) {
+ map.removeSource(layerSource);
+ }
}
}
- // if we want to add a layer before another layer, use the before option
- if (this.before) {
- map.addLayer(this.options, this.before)
- } else {
- map.addLayer(this.options)
+ },
+ },
+
+ mounted() {
+ const map = this.getMap();
+ // We can immediately initialize if we have the map ready
+ if(map && map.isStyleLoaded()) {
+ this.renderLayer();
+ this.isInitialized = true;
+ }
+ },
+
+ destroyed() {
+ this.removeLayer();
+ },
+
+ watch: {
+ options: {
+ deep: true,
+ handler() {
+ this.renderLayer();
}
- let layer = map.getLayer(this.options.id)
}
}
};
diff --git a/src/stories/index.stories.js b/src/stories/index.stories.js
index 5ab1f29..f204a02 100644
--- a/src/stories/index.stories.js
+++ b/src/stories/index.stories.js
@@ -1,9 +1,7 @@
/* eslint-disable react/react-in-jsx-scope */
-import { storiesOf, addDecorator } from '@storybook/vue';
-import { action } from '@storybook/addon-actions';
-import { withKnobs, text, number, boolean, array, select, color, date, button } from '@storybook/addon-knobs';
-import { linkTo } from '@storybook/addon-links';
+import { storiesOf } from '@storybook/vue';
+import { withKnobs, button } from '@storybook/addon-knobs';
import 'mapbox-gl/dist/mapbox-gl.css'
// needed for the v-mapbox-geocoder
@@ -32,7 +30,6 @@ const zoomTemplate = `
/>
`
-
const navigationTemplate = `
`
-
const injectTemplate = `
-
+
+
+`
+
+const dynamicLayersTemplate = `
+
+
`
@@ -177,13 +184,10 @@ const styleAndLayerTemplate = `
style="height: 300px;"
:center="[0, 0]"
>
-
-
+
`
-
-
storiesOf('Map', module)
.add('map', () => {
return {
@@ -200,7 +204,7 @@ storiesOf('Map', module)
},
template: zoomTemplate,
mounted () {
- button('random center', () => {
+ button('random center', () => {
this.center = [Math.random() * 50, Math.random() * 50]
})
}
@@ -225,7 +229,6 @@ storiesOf('Map', module)
map.setPaintProperty('a', 'fill-opacity', opacity)
})
button('toggle visibility', () => {
- let opacity = Math.random()
let visibility = map.getLayoutProperty('a', 'visibility')
if (visibility === 'visible') {
visibility = 'none'
@@ -237,6 +240,7 @@ storiesOf('Map', module)
}
}
})
+
.add('map with navigation control', () => {
return {
template: navigationTemplate
@@ -330,6 +334,7 @@ storiesOf('Map', module)
}
}
})
+
.add('layer order', () => {
return {
template: sortingTemplate,
@@ -342,6 +347,33 @@ storiesOf('Map', module)
},
}
})
+
+ .add('add and remove layers', () => {
+ return {
+ template: dynamicLayersTemplate,
+ data: () => ({
+ style: 'mapbox://styles/global-data-viewer/cjtss3jfb05w71fmra13u4qqm',
+ layers: []
+ }),
+ mounted() {
+ button('Toggle layer A', this.toggleLayerA),
+ button('Toggle layer B', this.toggleLayerB)
+ },
+ methods: {
+ toggleLayerA() {
+ const hasLayerA = this.layers.some(({ id }) => id === 'a');
+ if(hasLayerA) this.layers = this.layers.filter(({ id }) => id !== 'a');
+ else this.layers = [ ...this.layers, layerA];
+ },
+ toggleLayerB() {
+ const hasLayerB = this.layers.some(({ id }) => id === 'b');
+ if(hasLayerB) this.layers = this.layers.filter(({ id }) => id !== 'b');
+ else this.layers = [ ...this.layers, layerB];
+ }
+ }
+ }
+ })
+
.add('preserve drawing buffer order', () => {
return {
template: canvasTemplate,