류림스 공간

[항해99 59일차] 2022.05.03 TIL (지도 줌 인 줌 아웃 할때 이벤트 발생 시키기, 커스텀 오버레이 생성) 본문

TIL/2022 TIL

[항해99 59일차] 2022.05.03 TIL (지도 줌 인 줌 아웃 할때 이벤트 발생 시키기, 커스텀 오버레이 생성)

ryurim 2022. 5. 4. 02:07
반응형

오늘은 .. 기획 멘토링 받고 기획적인 부분 회의를 하고 ,

오후 늦게 작업을 했다..ㅠㅠ

 

기획부분은 너무너무 어려운 것 같다.

그리고 우리조의 핵심 기능은 지도로 오피스 매물 검색하고, 지도 이동 할때마다

해당 좌표 사이에 있는 매물들을 지도에 마커로 띄워주는 것..ㅠㅠ

 

이것 밖에 없어서

핵심 기능 구현을 먼저 해보고, 안되면 ..다른걸로 틀라고 해주셔서

오늘 지도 부분을 엄청 열심히 ..고민했던 것 같다.

 

우선 오늘 내가 한 것은 별거 없지만...

마커부분을 커스텀 오버레이로 바꾼 것이다 !!

회의하느라 코딩할 시간이 너무 적었다.ㅠㅠ

짜잔..이렇게 무료한 마커를 디자이너분들이 디자인 해주신 대로 커스텀 했다 !!!

 

지도부분 코드

import React, { useEffect, useState } from "react";
import styled from "styled-components";

import { useDispatch, useSelector } from "react-redux";
import { actionCreators as mapActions } from "../../redux/modules/map";
//아이콘
import { TiPlus, TiMinus } from "react-icons/ti";
import { MdMyLocation } from "react-icons/md";

import { Map, MapMarker, CustomOverlayMap } from "react-kakao-maps-sdk";
import { Position, Search, Overlay } from "./index";
import _ from "lodash";


const MainMap = (props) => {
  const dispatch = useDispatch();
  const getOffice = useSelector((state) => state.map.office_list);
  console.log("getOffice : ", getOffice);

  const { kakao } = window;
  const [level, setLevel] = useState(3); //지도레벨
  const [map, setMap] = useState(); //지도
  const [pos, setPos] = useState(); //경도 위도
  const [_level, _setLevel] = useState()

  const [state, setState] = useState({
    //기본 설정값
    center: {
      lat: 33.450701,
      lng: 126.570667,
    },
    errMsg: null,
    isLoading: true,
  });

  useEffect(() => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          setState((prev) => ({
            ...prev,
            center: {
              lat: position.coords.latitude, // 위도
              lng: position.coords.longitude, // 경도
            },
            isLoading: false,
          }));
        },
        (err) => {
          setState((prev) => ({
            ...prev,
            errMsg: err.message,
            isLoading: false,
          }));
        }
      );
    } else {
      setState((prev) => ({
        ...prev,
        errMsg: "현재 위치를 표시할 수 없어요.",
        isLoading: false,
      }));
    }
    //위도 경도
  }, []);
  const setLocation = () => {
    console.log(`현재 지도레벨은 ${level}입니다`);
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function (position) {
        map.setCenter(
          new kakao.maps.LatLng(
            position.coords.latitude,
            position.coords.longitude
          )
        );
      });
    }
  };
  return (
    <React.Fragment>
      <Search />
      <MainContent>
        <Map
          center={state.center}
          onCreate={(map) => setMap(map)}
          onZoomChanged={(map) => _setLevel(map.getLevel())}
          onDragEnd={(map) =>
            setPos({
              lat: map.getCenter().getLat(),
              lng: map.getCenter().getLng(),
              swLatLng: {
                lat: map.getBounds().getSouthWest().getLat(),
                lng: map.getBounds().getSouthWest().getLng(),
              },
              neLatLng: {
                lat: map.getBounds().getNorthEast().getLat(),
                lng: map.getBounds().getNorthEast().getLng(),
              },
            })
          }
          style={{ width: "100%", height: "inherit" }}
          level={level}
          minLevel={1}
          maxLevel={10}
        >
          {/* 커스텀 마커부분 */}
          <CustomOverlayMap position={ state.center}>
              <Overlay/>
          </CustomOverlayMap>
          {/* 커스텀 마커부분 */}
          {getOffice?.map((position, index) => (
            <CustomOverlayMap
              key={`${position.title}-${position.coordinate}`}
              position={position.coordinate} // 마커를 표시할 위치
              
              title={position.title} // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
            >
              <Overlay position={position}/>
            </CustomOverlayMap>
          ))}

          <Lev>
            <button onClick={setLocation}>
              <MdMyLocation size="24px" />
            </button>
            <button onClick={() => (level > 1 ? setLevel(level - 1) : null)}>
              <TiPlus size="21px" />
            </button>
            <button onClick={() => (level < 10 ? setLevel(level + 1) : null)}>
              <TiMinus size="21px" />
            </button>
          </Lev>
        </Map>
        {/* {pos && console.log('변경된 지도 중심좌표는 ' + pos.lat + ' 이고, 경도는 ' + pos.lng + ' 입니다', 
        '남서쪽' + pos.swLatLng.lat ,pos.swLatLng.lng, '북동쪽좌표' + pos.neLatLng.lat ,pos.neLatLng.lng)
        
        } */}
        {pos && <Position pos={pos} map={map} _level={_level}/>}
        
      </MainContent>
    </React.Fragment>
  );
};
const MainContent = styled.div`
  height: inherit;
  position: relative;
`;

const Lev = styled.div`
  width: 40px;
  height: 205px;
  position: absolute;
  bottom: 96px;
  left: 16px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 5px;

  & button {
    width: 40px;
    height: 40px;
    background: #ffffff;
    border: none;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.1);
  }
`;
export default MainMap;

나는 카카오 지도 sdk라이브러리로 했다.

우선 CustomOverlayMap 을 임포트 한 뒤

 {getOffice?.map((position, index) => (
            <CustomOverlayMap
              key={`${position.title}-${position.coordinate}`}
              position={position.coordinate} // 마커를 표시할 위치
              
              title={position.title} // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
            >
              <Overlay position={position}/>
            </CustomOverlayMap>
          ))}

이런식으로 Map안에 children으로 넣었다.

오버레이 컴포넌트

import React from 'react';
import { Grid,Text } from '../../elements/index';
 
const Overlay = (props) => {
    const {position} =props;
  // console.log(position?.estate[0]?.type, "????")
    return (
        <React.Fragment>
              <Grid
              width="54px" height="65px" borderRadius="8px"
              bg="#000" color="#fff" position="relative"
            >
              <Grid display="flex" flexDirection="column"  alignItems="center" padding="10px 0" >
                <Text bold size="10px">{position?.title}</Text>
                <Text bold size="14px">999만</Text>
              </Grid>
              
              <Grid   width="27px" height="16px" position="absolute" top="-5px" right="-10px" bg="#fff" borderRadius="27px"
              border="1px solid #ccc" display="flex" alignItems="center" justifyContent="center">
                <Text color="#000" size="8px">999</Text>
              </Grid>
              <Grid   width="54px" height="20px" position="absolute"  bottom="0" bg="#fff" borderRadius="0 0 8px 8px"
              border="1px solid #000" display="flex" alignItems="center" justifyContent="center">
                <Text color="#000" size="10px">999</Text>
              </Grid>
            </Grid>
        </React.Fragment>
    );
};

export default Overlay;

이렇게 스타일을 주어서 완성했다 !!!!

 

그다음에 줌인 줌아웃 했을 때 이벤트를 발생시키는 걸 해보았는데.

잘 안된다.ㅠㅠㅠㅠㅠㅠㅠㅠ

 

우선 드레그엔드 이벤트 발생시킨 후 줌인 줌아웃하면..

콘솔로그에 잘 찍히는데

 

맨처음에 줌인 줌아웃 먼저 하면 콘솔에 아무것도 안찍힌다..

이부분을 알아내야 될 것같다..!!!!

 

이제 내가 고민해야 될 부분은 바로...

 

지도 레벨에 따라 다른 매물을 보여줘야되는데 어떻게 조건을 줘야될지이다..

이게 핵심인데..ㅠㅠㅠㅠㅠㅠㅠㅠㅠ

728x90
반응형
Comments