내 세상

[React] React-leaflet rectangle gradient 적용 방법 본문

Technical/React

[React] React-leaflet rectangle gradient 적용 방법

sga8 2025. 1. 9. 11:33
728x90
반응형

React-Leafet 사용 시, 동적인 정보를 보여주기 위해 Rectangle을 Customize해서 사용하고 있음.
다만, Rectangle은 SVG 요소이기 때문에, fillColor를 Gradient로 사용이 불가하고 단색으로만 가능함.

하지만, svg defs 선언을 통해서 SVG 요소에도 Gradient를 적용할 수 있는 방안을 발견

 

MapContainer 내부에 svg-defs를 통해 먼저 linearGradient를 먼저 설정한다.
그리고 Rectangle이나 SVG 요소에서 fillColor를 'url(#grad-RED)' 와 같은 형식으로 사용하면 됨

 

const MyContainer = memo(
  ({ onMove, mapCenter, mapZoom, showDialogWithData, mapMarkers }) => {
    ....

    const addGradient = () => {
      const colorToGradient = ["RED", "BLUE", "GREY"];
      return colorToGradient.map((item) => {
        const { start, end } = getGradientColors(item)
        return (
          <linearGradient
            id={`grad-${item}`}
            x1="0%"
            y1="0%"
            x2="100%"
            y2="100%"
            key={item}
          >
            <stop offset="0%" stopColor={start} />
            <stop offset="100%" stopColor={end} />
          </linearGradient>
        )
      })
    }


    _.forEach(mapMarkers, (elem) => {
      ...
    })

    L.CRS.MyCRS = L.extend({}, L.CRS.Simple, {
      transformation: new L.Transformation(1, 0, 1, 0), // ax+b, cy+d
    })
    return (
      <MapContainer
        center={mapCenter}
        zoom={mapZoom}
        zoomControl={false}
        attributionControl={false}
        maxBounds={boundsMap}
        style={{ height: '100%', fontFamily: 'IBM Plex Sans', fontWeight: 500 }}
        crs={L.CRS.MyCRS}
        maxZoom={10}
        id="map"
        ref={mapRef}
      >
        <svg>
          <defs>{addGradient()}</defs>
        </svg>
        <Marker icon={icon} position={{ lat: 0, lng: 0 }}></Marker>
        <Marker icon={icon} position={{ lat: 0, lng: 1980 }}></Marker>
        <Marker icon={icon} position={{ lat: 360, lng: 0 }}></Marker>
        <Rectangle
          bounds ={[[100,0],[10,100]]}
          pathOptions ={{fillColor: 'url(#grad-RED)'}} />
      </MapContainer>
    )
  }
)
728x90
반응형