add MapZoom layout component

This commit is contained in:
axolotle
2021-06-05 13:46:25 +02:00
parent 8a9fc9aef1
commit d23459d969
2 changed files with 86 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
<template>
<div :id="id" class="map-zoom">
<svg :view-box.camel="viewBox">
<g :transform="transform">
<slot name="default" />
</g>
</svg>
<button-zoom
v-bind="{ minZoom, maxZoom, value: scale }"
@zoom="onZoom"
/>
</div>
</template>
<script>
import { select, zoom } from 'd3'
export default {
name: 'MapZoom',
props: {
id: { type: String, required: true },
minZoom: { type: Number, default: 0.3 },
maxZoom: { type: Number, default: 1 }
},
data () {
return {
zoom: zoom().scaleExtent([this.minZoom, this.maxZoom]),
svg: undefined, // d3 select(svg)
width: undefined,
height: undefined,
scale: 1,
transform: 'translate(0, 0) scale(1)'
}
},
computed: {
viewBox () {
const { width, height } = this
if (width === undefined) return
return `-${width / 2} -${height / 2} ${width} ${height}`
}
},
methods: {
updateSize () {
const { width, height } = this.$el.getBoundingClientRect()
Object.assign(this.$data, { width, height })
},
onZoom (direction) {
this.zoom.scaleBy(this.svg, direction === 1 ? 1.3 : 1 / 1.3, [0, 0])
}
},
mounted () {
window.addEventListener('resize', () => this.updateSize())
this.zoom.on('zoom', ({ transform }) => {
this.transform = transform
this.scale = transform.k
})
this.updateSize()
this.svg = select('#' + this.id + ' svg')
this.svg.call(this.zoom)
}
}
</script>
<style lang="scss" scoped>
.map-zoom {
position: relative;
width: 100%;
height: 100%;
svg {
width: 100%;
height: 100%;
}
}
</style>
+1
View File
@@ -0,0 +1 @@
export { default as MapZoom } from './MapZoom'