110 lines
3.0 KiB
Vue
110 lines
3.0 KiB
Vue
<template>
|
|
<div class="position-relative">
|
|
<div @click="togglePopover">
|
|
<slot name="trigger">
|
|
<i class="bx bxs-map"></i>
|
|
</slot>
|
|
</div>
|
|
|
|
<div
|
|
v-if="isVisible"
|
|
class="position-absolute map z-3"
|
|
>
|
|
<button
|
|
type="button"
|
|
class="btn-close popover-close"
|
|
@click="togglePopover"
|
|
></button>
|
|
|
|
<div class="card">
|
|
<div class="card-body p-1">
|
|
<KakaoMap
|
|
v-if="coordinates"
|
|
:lat="coordinates.lat"
|
|
:lng="coordinates.lng"
|
|
class="w-px-250 h-px-200"
|
|
@onLoadKakaoMap="onLoadKakaoMap"
|
|
>
|
|
<KakaoMapMarker
|
|
:lat="coordinates.lat"
|
|
:lng="coordinates.lng"
|
|
/>
|
|
</KakaoMap>
|
|
|
|
<div class="position-absolute top-50 translate-middle-y end-0 me-3 z-1 d-flex flex-column gap-1">
|
|
<button class="btn-secondary border-none" @click="zoomOut">+</button>
|
|
<button class="btn-secondary border-none" @click="zoomIn">-</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { KakaoMap, KakaoMapMarker } from 'vue3-kakao-maps';
|
|
|
|
const props = defineProps({
|
|
address: {
|
|
type: String,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const isVisible = ref(false);
|
|
const coordinates = ref(null);
|
|
const map = ref(null);
|
|
|
|
// 주소를 좌표로 변환하는 함수
|
|
const convertAddressToCoordinates = () => {
|
|
return new Promise((resolve, reject) => {
|
|
if (!window.kakao || !window.kakao.maps) {
|
|
reject(new Error('Kakao Maps not loaded'));
|
|
return;
|
|
}
|
|
|
|
const geocoder = new window.kakao.maps.services.Geocoder();
|
|
geocoder.addressSearch(props.address, (result, status) => {
|
|
if (status === window.kakao.maps.services.Status.OK) {
|
|
resolve({
|
|
lat: parseFloat(result[0].y),
|
|
lng: parseFloat(result[0].x)
|
|
});
|
|
} else {
|
|
reject(new Error('Address conversion failed'));
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
const togglePopover = () => {
|
|
isVisible.value = !isVisible.value;
|
|
};
|
|
|
|
const onLoadKakaoMap = (mapRef) => {
|
|
map.value = mapRef;
|
|
};
|
|
|
|
// 지도 확대
|
|
const zoomIn = () => {
|
|
if (map.value) {
|
|
const level = map.value.getLevel();
|
|
map.value.setLevel(level + 1);
|
|
}
|
|
};
|
|
|
|
// 지도 축소
|
|
const zoomOut = () => {
|
|
if (map.value) {
|
|
const level = map.value.getLevel();
|
|
map.value.setLevel(level - 1);
|
|
}
|
|
};
|
|
|
|
// 컴포넌트 마운트 시 좌표 변환
|
|
onMounted(async () => {
|
|
coordinates.value = await convertAddressToCoordinates();
|
|
});
|
|
</script>
|