add MapZoom layout component
This commit is contained in:
@@ -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>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as MapZoom } from './MapZoom'
|
||||||
Reference in New Issue
Block a user