Tagbangers Blog

React map gl と styled component で custom marker を作ってみました

こんにちは、フロントエンドチームのシルベスターです。


React で custom marker を作りたいなーと思っていろいろ調べた結果、

uber の react-map-gl と styled-components を使うと簡単に作れるねってことがわかりました


なぜかと言うと、react component として import できて、必要な props を渡すだけでできるから?笑


早速やってみましょう


Getting Started

React-map-gl

npm i react-map-gl

Styled-components

npm i styled-components


マップを表示してみよう

ファイルに import して props を渡すと、

import * as React from "react";
import styled from "styled-components";
import ReactMapGL from "react-map-gl";

const Container = styled.div`
  height: 100vh;
`;

export default () => {
  const [viewport, setViewport] = React.useState({
    width: "100%",
    height: "100%",
    longitude: 139.63270819862225,
    latitude: 35.458058995332536,
    zoom: 13.5,
    mapStyle: "mapbox://styles/mapbox/streets-v11",
    // 自分の AccessToken
    mapboxApiAccessToken: **********
  });

  return (
    <Container>
        <ReactMapGL {...viewport} onViewportChange={setViewport} />
    </Container>
  );
};


マップが表示されます!



Custom marker を追加

Marker component に longitude, latitude, draggable(optional) を渡してみましょう

import * as React from "react";
import styled from "styled-components";
import ReactMapGL, { Marker as ReactMapGLMarker } from "react-map-gl";

const Container = styled.div`
  // 省略
`;

const Marker = styled(ReactMapGLMarker)`
  cursor: pointer;
  background-image: url("https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png");
  background-size: cover;
  border-radius: 50%;
  width: 64px;
  height: 64px;
`;

export default () => {
  const [viewport, setViewport] = React.useState({
    // 省略
  });

  const [marker, setMarker] = React.useState({
    longitude: 139.63270819862225,
    latitude: 35.458058995332536,
    draggable: true
  });

const onDragEnd = (e) => {
    setMarker({
      ...marker,
      longitude: e.lngLat[0],
      latitude: e.lngLat[1]
    });
  };

  return (
    <Container>
        <ReactMapGL {...viewport} onViewportChange={setViewport}>
          <Marker {...marker} onDragEnd={onDragEnd} />
        </ReactMapGL>
    </Container>
  );
};


そうすると今度 marker もマップ上に表示されるようになりました



おまけ

Marker の callback は3つしかなくて

  • onDragStart
  • onDrag
  • onDragEnd

それ以外のイベント、onClick や onMouseEnter などを呼びたい時は <div> などのタグで囲む必要はある


それでは、onMouseEnter で遊んでみましょう


import ...

// 省略


export default () => {

// 省略

  const onMouseEnter = () => {
    setMarker({
      ...marker,
      longitude: marker.longitude + Math.random() * 0.1,
      latitude: marker.latitude + Math.random() * 0.1
    });
  };

  return (
    <Container>
        <ReactMapGL {...viewport} onViewportChange={setViewport}>
          <div onMouseEnter={onMouseEnter}>
            <Marker {...marker} onDragEnd={onDragEnd} />
          </div>
        </ReactMapGL>
    </Container>
  );
};



はい、marker に逃げられました笑




以上 react-map-gl と styled-components で custom marker の作成でした


最後のくだらないところまで読んでくれてありがとうございました!