Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/VMapbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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).
-->
<div>
<!-- Are these named slots actually ever used?-->
<slot name="layers"></slot>
<slot name="sources"></slot>
<slot></slot>
Expand Down
92 changes: 64 additions & 28 deletions src/components/v-mapbox-layer.js
Original file line number Diff line number Diff line change
@@ -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)
}
}
};
58 changes: 45 additions & 13 deletions src/stories/index.stories.js
Original file line number Diff line number Diff line change
@@ -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';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more general thing, with or without ; ?

import { withKnobs, button } from '@storybook/addon-knobs';

import 'mapbox-gl/dist/mapbox-gl.css'
// needed for the v-mapbox-geocoder
Expand Down Expand Up @@ -32,7 +30,6 @@ const zoomTemplate = `
/>
`


const navigationTemplate = `
<v-mapbox
map-style="mapbox://styles/mapbox/satellite-streets-v10"
Expand Down Expand Up @@ -88,7 +85,6 @@ const canvasTemplate = `
</div>
`


const injectTemplate = `
<v-mapbox
map-style="mapbox://styles/mapbox/satellite-streets-v10"
Expand Down Expand Up @@ -128,6 +124,7 @@ const layerA = {
'fill-opacity': 1
}
}

const layerB = {
'id': 'b',
'type': 'fill',
Expand Down Expand Up @@ -166,7 +163,17 @@ const sortingTemplate = `
<!-- green (we want this on top) -->
<v-mapbox-layer :options="layerA"></v-mapbox-layer>
<!-- red -->
<v-mapbox-layer before="a" :options="layerB"></v-mapbox-layer>
<v-mapbox-layer :options="layerB"></v-mapbox-layer>
</v-mapbox>
`

const dynamicLayersTemplate = `
<v-mapbox
:map-style="style"
access-token="pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw"
style="height: 300px;"
>
<v-mapbox-layer v-for="layer in layers" :options="layer" :key="layer.id" />
</v-mapbox>
`

Expand All @@ -177,13 +184,10 @@ const styleAndLayerTemplate = `
style="height: 300px;"
:center="[0, 0]"
>
<!-- green (we want this on top) -->
<v-mapbox-layer :options="layerA"></v-mapbox-layer>
<v-mapbox-layer :options="layerA"></v-mapbox-layer>
</v-mapbox>
`



storiesOf('Map', module)
.add('map', () => {
return {
Expand All @@ -200,7 +204,7 @@ storiesOf('Map', module)
},
template: zoomTemplate,
mounted () {
button('random center', () => {
button('random center', () => {
this.center = [Math.random() * 50, Math.random() * 50]
})
}
Expand All @@ -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'
Expand All @@ -237,6 +240,7 @@ storiesOf('Map', module)
}
}
})

.add('map with navigation control', () => {
return {
template: navigationTemplate
Expand Down Expand Up @@ -330,6 +334,7 @@ storiesOf('Map', module)
}
}
})

.add('layer order', () => {
return {
template: sortingTemplate,
Expand All @@ -342,6 +347,33 @@ storiesOf('Map', module)
},
}
})

.add('add and remove layers', () => {
return {
template: dynamicLayersTemplate,
data: () => ({
style: 'mapbox://styles/global-data-viewer/cjtss3jfb05w71fmra13u4qqm',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is from a specific project? is it useful to relate that to this general package, even if only in a story?

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,
Expand Down