feat(wip): 지도 툴팁 기능 활성화

This commit is contained in:
2022-04-20 03:27:41 +09:00
parent ce8d1cbeb2
commit 6d8151df5f
3 changed files with 85 additions and 6 deletions
+26
View File
@@ -5,6 +5,8 @@
left: `${city.x - 20}px`,
top: `${city.y - 15}px`,
}"
@mouseenter="silent"
@mouseleave="silent"
>
<a
class="city_link"
@@ -12,7 +14,12 @@
:data-nation="city.nation"
:data-id="city.id"
:href="props.href"
:style="{
cursor: city.clickable ? 'pointer' : 'default',
}"
@click="clicked"
@mouseenter="mouseenter"
@mouseleave="mouseleave"
>
<div
class="city_img"
@@ -36,6 +43,8 @@ import type { MapCityParsed } from "@/map";
import { toRef, type PropType } from "vue";
const emit = defineEmits<{
(event: "click", evnet: MouseEvent): void;
(event: "mouseenter", e: MouseEvent): void;
(event: "mouseleave", e: MouseEvent): void;
}>();
const props = defineProps({
city: {
@@ -72,6 +81,23 @@ function getCityState(): string {
function clicked(event: MouseEvent) {
emit("click", event);
}
function mouseenter(event: MouseEvent) {
event.stopPropagation();
emit("mouseenter", event);
console.log("enter");
}
function mouseleave(event: MouseEvent) {
event.stopPropagation();
emit("mouseleave", event);
console.log("out");
}
function silent(event: MouseEvent) {
event.stopPropagation();
console.log(city.value.name);
}
</script>
<style lang="scss" scoped>
+27 -1
View File
@@ -5,6 +5,8 @@
left: `${city.x - 20}px`,
top: `${city.y - 15}px`,
}"
@mouseenter="silent"
@mouseleave="silent"
>
<div
v-if="city.color"
@@ -20,7 +22,12 @@
:data-nation="city.nation"
:data-id="city.id"
:href="props.href"
:style="{
cursor: city.clickable?'pointer':'default',
}"
@click="clicked"
@mouseenter="mouseenter"
@mouseleave="mouseleave"
>
<div class="city_img">
<img :src="`${imagePath}/cast_${city.level}.gif`" />
@@ -45,7 +52,9 @@
import type { MapCityParsed } from "@/map";
import { toRef, type PropType } from "vue";
const emit = defineEmits<{
(event: "click", evnet: MouseEvent): void;
(event: "click", e: MouseEvent): void;
(event: "mouseenter", e: MouseEvent): void;
(event: "mouseleave", e: MouseEvent): void;
}>();
const props = defineProps({
city: {
@@ -73,6 +82,23 @@ const imagePath = toRef(props, "imagePath");
function clicked(event: MouseEvent) {
emit("click", event);
}
function mouseenter(event: MouseEvent) {
event.stopPropagation();
emit("mouseenter", event);
console.log('enter');
}
function mouseleave(event: MouseEvent) {
event.stopPropagation();
emit("mouseleave", event);
console.log('out');
}
function silent(event: MouseEvent){
event.stopPropagation();
console.log(city.value.name);
}
</script>
<style lang="scss" scoped>
+32 -5
View File
@@ -21,7 +21,7 @@
>
<span class="tooltiptext" />
</div>
<div class="map_body">
<div ref="map_area" class="map_body">
<div class="map_bglayer1" />
<div class="map_bglayer2" />
<div class="map_bgroad" />
@@ -55,6 +55,8 @@
:image-path="imagePath"
:is-my-city="city.id === drawableMap.myCity"
@click="emit('city-click', city, $event)"
@mouseenter="activatedCity = city"
@mouseleave="activatedCity = undefined"
/>
</template>
<template v-else
@@ -64,11 +66,27 @@
:city="city"
:is-my-city="city.id === drawableMap.myCity"
@click="emit('city-click', city, $event)"
@mouseenter="activatedCity = city"
@mouseleave="activatedCity = undefined"
/></template>
</div>
<div class="city_tooltip">
<div class="city_name" />
<div class="nation_name" />
<div
ref="tooltipDom"
class="city_tooltip"
:style="{
display: isOutside || !activatedCity ? 'none' : 'block',
position: 'absolute',
left: `${(() => {
if (cursorX + tooltipWidth + 10 > 700) {
return cursorX - tooltipWidth - 5;
}
return cursorX + 10;
})()}px`,
top: `${cursorY + 30}px`,
}"
>
<div class="city_name">{{ activatedCity?.text }}</div>
<div class="nation_name">{{ activatedCity?.nation }}</div>
</div>
</div>
</template>
@@ -127,7 +145,7 @@ export type CityPositionMap = {
<script lang="ts" setup>
import "@/../css/map.css";
import type { loadMapOption } from "@/map";
import { type PropType, toRef, inject, type Ref, ref, watch } from "vue";
import { type PropType, toRef, inject, type Ref, ref, watch, type ComponentPublicInstance } from "vue";
import { v4 as uuidv4 } from "uuid";
import type { MapResult } from "@/defs";
import { joinYearMonth } from "@/util/joinYearMonth";
@@ -141,6 +159,8 @@ import { unwrap } from "@/util/unwrap";
import MapCityBasic from "./MapCityBasic.vue";
import MapCityDetail from "./MapCityDetail.vue";
import { convertDictById } from "@/common_legacy";
import { useElementSize, useMouseInElement } from "@vueuse/core";
const uuid = uuidv4();
const gameConstStore = unwrap_err(
inject<Ref<GameConstStore>>("gameConstStore"),
@@ -148,6 +168,11 @@ const gameConstStore = unwrap_err(
"gameConstStore가 주입되지 않았습니다."
);
const tooltipDom = ref<ComponentPublicInstance<HTMLDivElement>>();
const map_area = ref<ComponentPublicInstance<HTMLDivElement>>();
const { elementX: cursorX, elementY: cursorY, isOutside } = useMouseInElement(map_area);
const { width: tooltipWidth } = useElementSize(tooltipDom);
const emit = defineEmits<{
(event: "city-click", city: MapCityParsed, e: MouseEvent): void;
(event: "parsed", drawable: MapCityDrawable): void;
@@ -217,6 +242,7 @@ function getTitleColor(): string | undefined {
}
const drawableMap = ref<MapCityDrawable>(convertCityObjs(props.modelValue));
const activatedCity = ref<MapCityParsed>();
function getBeginGameLimitTooltip(): string | undefined {
const { startYear, year, month } = mapResult.value;
@@ -375,6 +401,7 @@ function convertCityObjs(obj: MapResult): MapCityDrawable {
watch(
() => props.modelValue,
(mapInfo) => {
activatedCity.value = undefined;
drawableMap.value = convertCityObjs(mapInfo);
}
);