Skip to content

Commit 788f121

Browse files
authored
merge: 지도 대표이미지 기능 추가 (#27)
merge: 지도 대표이미지 기능 추가 (#27)
2 parents b211f13 + 8632efd commit 788f121

File tree

1 file changed

+85
-34
lines changed
  • packages/react-native/src/pages/Maps

1 file changed

+85
-34
lines changed
Lines changed: 85 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,131 @@
11
import { Dimensions, View, TouchableOpacity } from 'react-native';
22
import { Font } from 'design-system';
33
import { geoPath, geoMercator } from 'd3-geo';
4-
import { Svg, G, Path } from 'react-native-svg';
4+
import { Svg, G, Path, Image, Defs, Pattern } from 'react-native-svg';
55
import { useState } from 'react';
66
import mapData from '@/assets/mapData';
77
import { KoreaLocationName } from '@/types/map';
88
import { StackNavigation } from '@/types/navigation';
99
import useBottomSheet from '@/hooks/useBottomSheet';
10+
import useGallery from '@/hooks/useGallery';
11+
import Header from '@/components/common/Header';
1012

1113
interface MapsMainProps {
1214
navigation: StackNavigation<'Maps/Main'>;
1315
}
1416

17+
type RegionRepresentImage = Partial<Record<KoreaLocationName, string>>;
18+
1519
const { width, height } = Dimensions.get('window');
1620

1721
export default function Maps({ navigation }: MapsMainProps) {
1822
const [region, setRegion] = useState<KoreaLocationName>();
1923
const { BottomSheet, showBottonSheet } = useBottomSheet();
24+
const [regionImage, setRegionImage] = useState<RegionRepresentImage>();
25+
const { getPhoto } = useGallery();
2026

21-
const projection = geoMercator() // 구형 투영도
22-
.scale(3300) // 스케일 조정
23-
.center([127.766922, 35.907757]) // 한국의 중심 좌표
27+
const projection = geoMercator()
28+
.scale(3300)
29+
.center([127.766922, 35.907757])
2430
.translate([width / 2, height / 2]);
2531

2632
const pathGenerator = geoPath().projection(projection);
2733

34+
const handleAddRegionImage = async (regionName: KoreaLocationName) => {
35+
const photo = (await getPhoto()) as string;
36+
if (photo) {
37+
setRegionImage((prev) => ({
38+
...prev,
39+
[regionName]: photo,
40+
}));
41+
}
42+
};
43+
2844
return (
2945
<View className="flex-1 bg-[#D2F3F8]">
46+
<Header type="logo" />
3047
<Svg width={width} height={height}>
48+
<Defs>
49+
{mapData.features.map((feature) => {
50+
const regionName = feature.properties.CTP_KOR_NM;
51+
const patternImage = regionImage?.[regionName];
52+
return (
53+
patternImage && (
54+
<Pattern
55+
key={regionName}
56+
id={`${regionName}Image`}
57+
patternUnits="userSpaceOnUse"
58+
width={width / 4}
59+
height={height / 4}
60+
>
61+
<Image
62+
href={patternImage}
63+
width={width / 4}
64+
height={height / 4}
65+
preserveAspectRatio="xMidYMid slice"
66+
/>
67+
</Pattern>
68+
)
69+
);
70+
})}
71+
</Defs>
3172
<G>
3273
{mapData.features.map((feature) => {
3374
const geoFeature = feature as GeoJSON.Feature<GeoJSON.Geometry>;
75+
const regionName = feature.properties.CTP_KOR_NM;
76+
const patternId = `${regionName}Image`;
77+
3478
return (
3579
<Path
36-
key={feature.properties.CTP_KOR_NM}
80+
key={regionName}
3781
d={pathGenerator(geoFeature) || ''}
38-
fill="white"
82+
fill={
83+
regionImage?.[regionName] ? `url(#${patternId})` : 'white'
84+
}
3985
stroke="#000"
4086
strokeWidth={1}
4187
onPress={() => {
42-
setRegion(feature.properties.CTP_KOR_NM);
88+
setRegion(regionName);
4389
showBottonSheet();
4490
}}
4591
/>
4692
);
4793
})}
4894
</G>
4995
</Svg>
50-
<BottomSheet isShow={Boolean(region)}>
51-
<View className="flex justify-evenly items-center mt-2 flex-col gap-4">
52-
<View className="flex">
53-
<Font.Bold type="mainTitle" color="black">
54-
{region}
55-
</Font.Bold>
56-
</View>
57-
<View className="flex items-center w-full ">
58-
<TouchableOpacity className="py-2">
59-
<Font type="title1" color="black">
60-
대표사진 설정하기
61-
</Font>
62-
</TouchableOpacity>
63-
<View className="w-[90%] h-[0.5px] bg-[#333333]" />
64-
<TouchableOpacity
65-
className="py-2"
66-
onPress={() =>
67-
region &&
68-
navigation.navigate('Maps/Record', { location: region })
69-
}
70-
>
71-
<Font type="title1" color="black">
72-
로그보기
73-
</Font>
74-
</TouchableOpacity>
96+
{region && (
97+
<BottomSheet isShow={Boolean(region)}>
98+
<View className="flex justify-evenly items-center mt-2 flex-col gap-4">
99+
<View className="flex">
100+
<Font.Bold type="mainTitle" color="black">
101+
{region}
102+
</Font.Bold>
103+
</View>
104+
<View className="flex items-center w-full ">
105+
<TouchableOpacity
106+
className="py-2"
107+
onPress={() => handleAddRegionImage(region)}
108+
>
109+
<Font type="title1" color="black">
110+
대표사진 설정하기
111+
</Font>
112+
</TouchableOpacity>
113+
<View className="w-[90%] h-[0.5px] bg-[#333333]" />
114+
<TouchableOpacity
115+
className="py-2"
116+
onPress={() =>
117+
region &&
118+
navigation.navigate('Maps/Record', { location: region })
119+
}
120+
>
121+
<Font type="title1" color="black">
122+
로그보기
123+
</Font>
124+
</TouchableOpacity>
125+
</View>
75126
</View>
76-
</View>
77-
</BottomSheet>
127+
</BottomSheet>
128+
)}
78129
</View>
79130
);
80131
}

0 commit comments

Comments
 (0)