Skip to content

自定义样式

TIP

mapbox gl draw 画出来的图形是多个图层的组合,要想彻底重定义样式,可以根据需求修改theme.js源码,然后传入构造函数。

示例

示例源码
tsx
import React, { useEffect, useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import { MbMap, MbTiandituLayer } from '@mapbox-react/core'
import MapboxDraw from '@mapbox-web/draw'
import type { ChangeEvent } from 'react'

const App = () => {
  const [mapCenter] = useState([116, 39])
  const [zoom, setZoom] = useState(10)
  const [pitch, setPitch] = useState(0)
  const mapInst = useRef<any>()
  const [mode, setMode] = useState('')

  const draw = useRef<MapboxDraw>()
  const savedData = useRef('')
  const features = useRef<Record<string, any>>({})

  const createdHandler = (map: any) => {
    draw.current = new MapboxDraw(map, {
      userProperties: true,
      styles: window.customTheme,
    })
    map.on('draw.create', (e) => {
      features.current[e.features[0].id] = e.features[0]
    })
  }

  const changeMode = (e: ChangeEvent<HTMLSelectElement>) => {
    const newMode = e.target.value

    setMode(newMode)
    if (newMode === 'draw_text') {
      draw.current?.changeMode(newMode, {
        text: 'Text',
        'text-color': 'white',
        'text-size': 20,
      })
    } else if (newMode === 'draw_image') {
      draw.current?.changeMode(newMode, {
        imageId: 'logo',
        imageUrl: 'https://mapbox-web.github.io/mapbox-react/images/snowDrop.png',
      })
    } else {
      draw.current?.changeMode(newMode)
    }
  }

  return (
    <div className="map-wrapper">
      <MbMap
        ref={mapInst}
        center={mapCenter}
        zoom={zoom}
        pitch={pitch}
        onCreated={createdHandler}
      >
        <div style={{ position: 'absolute', top: '10px', left: '10px' }}>
          <div className="actions" style={{ color: 'white' }}>
            Choose Mode:
            <select
              value={mode}
              style={{ width: '250px' }}
              onChange={changeMode}
            >
              <optgroup label="文本(Text)">
                <option value="draw_text">文本(Text)</option>
              </optgroup>
              <optgroup label="线状(Line)">
                <option value="draw_line_string">折线(Line)</option>
                <option value="draw_curve">曲线(Curve)</option>
                <option value="draw_arc">弧线(Arc)</option>
              </optgroup>
              <optgroup label="面状(Area)">
                <option value="draw_polygon">多边形(Polygon)</option>
                <option value="draw_circle">圆(Circle)</option>
                <option value="draw_ellipse">椭圆(Ellipse)</option>
                <option value="draw_rectangle">矩形(Rectange)</option>
                <option value="draw_sector">扇形(Sector)</option>
                <option value="draw_lune">弓形(Lune)</option>
                <option value="draw_closed_curve">
                  闭合曲面(Closed Curve)
                </option>
              </optgroup>
              <optgroup label="箭头(Arrow)">
                <option value="draw_fine_arrow">细直箭头(Fine Arrow)</option>
                <option value="draw_assault_direction">
                  突击方向(Assault Direction)
                </option>
                <option value="draw_double_arrow">钳击(Double Arrow)</option>
                <option value="draw_attack_arrow">
                  进攻箭头(Attack Arrow)
                </option>
                <option value="draw_tailed_attack_arrow">
                  燕尾进攻箭头(Tailed Attack Arrow)
                </option>
                <option value="draw_squad_combat">
                  战斗小队(Squad Combat)
                </option>
              </optgroup>
              <optgroup label="图片(Image)">
                <option value="draw_image">图片(Image)</option>
              </optgroup>
            </select>
          </div>
        </div>
      </MbMap>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector('#root'))
自定义样式源码
ts
export default [
  {
    'id': 'gl-draw-symbol-inactive',
    'type': 'symbol',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'user_display-type', 'symbol'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'text-color': ['get', 'user_text-color'],
    },
    'layout': {
      'text-allow-overlap': true,
      'icon-allow-overlap': true,
      'text-size': ['get', 'user_text-size'],
      'icon-image': ['get', 'user_image-id'],
      'icon-size': ['get', 'user_icon-size'],
      'text-field': ['get', 'user_text'],
      'text-font': ['Open Sans Regular']
    }
  },
  {
    'id': 'gl-draw-symbol-active',
    'type': 'symbol',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'user_display-type', 'symbol'],
      ['==', '$type', 'Point'],
      ['==', 'active', 'true'],
      ['==', 'meta', 'feature']
    ],
    'paint': {
      'text-color': ['get', 'user_text-color'],
    },
    'layout': {
      'text-allow-overlap': true,
      'icon-allow-overlap': true,
      'text-size': ['get', 'user_text-size'],
      'icon-image': ['get', 'user_image-id'],
      'icon-size': ['get', 'user_icon-size'],
      'text-field': ['get', 'user_text'],
      'text-font': ['Open Sans Regular']
    }
  },
  {
    'id': 'gl-draw-polygon-fill-inactive',
    'type': 'fill',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'Polygon'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'fill-color': ['get', 'user_fill-color'],
      'fill-outline-color': ['get', 'user_line-color'],
      'fill-opacity': ['get', 'user_opacity']
    },
  },
  {
    'id': 'gl-draw-polygon-fill-active',
    'type': 'fill',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
    'paint': {
      'fill-color': ['get', 'user_fill-color'],
      'fill-outline-color': ['get', 'user_line-color'],
      'fill-opacity': ['get', 'user_opacity']
    },
  },
  {
    'id': 'gl-draw-polygon-midpoint',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'midpoint']],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-inactive',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'Polygon'],
      ['!=', 'mode', 'static']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-active',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-dasharray': [0.2, 2],
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-line-inactive',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'LineString'],
      ['!=', 'mode', 'static']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-width': ['get', 'user_line-width'],
      'line-opacity': ['get', 'user_opacity'],
    }
  },
  {
    'id': 'gl-draw-line-active',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'LineString'],
      ['==', 'active', 'true']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-dasharray': [0.2, 2],
      'line-color': ['get', 'user_line-color'],
      'line-width': 5,
      'line-opacity': 1,
    }
  },
  {
    'id': 'gl-draw-polygon-and-line-vertex-stroke-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'meta', 'vertex'],
      ['==', '$type', 'Point'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-polygon-and-line-vertex-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'meta', 'vertex'],
      ['==', '$type', 'Point'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-point-point-stroke-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['!has', 'user_display-type'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 5,
      'circle-opacity': 1,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-point-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['!has', 'user_display-type'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#3bb2d0'
    }
  },
  {
    'id': 'gl-draw-point-stroke-active',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['==', 'active', 'true'],
      ['!=', 'meta', 'midpoint']
    ],
    'paint': {
      'circle-radius': 7,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-point-active',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['!=', 'meta', 'midpoint'],
      ['==', 'active', 'true']],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-polygon-fill-static',
    'type': 'fill',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
    'paint': {
      'fill-color': '#404040',
      'fill-outline-color': '#404040',
      'fill-opacity': 0.1
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-static',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': '#404040',
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-line-static',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'LineString']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': '#404040',
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-point-static',
    'type': 'circle',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Point']],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#404040'
    }
  },
];
默认样式源码
js
export default [
  {
    'id': 'gl-draw-symbol-inactive',
    'type': 'symbol',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'user_display-type', 'symbol'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'text-color': ['get', 'user_text-color'],
    },
    'layout': {
      'text-allow-overlap': true,
      'icon-allow-overlap': true,
      'text-size': ['get', 'user_text-size'],
      'icon-image': ['get', 'user_image-id'],
      'icon-size': ['get', 'user_icon-size'],
      'text-field': ['get', 'user_text'],
      'text-font': ['Open Sans Regular']
    }
  },
  {
    'id': 'gl-draw-symbol-active',
    'type': 'symbol',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'user_display-type', 'symbol'],
      ['==', '$type', 'Point'],
      ['==', 'active', 'true'],
      ['==', 'meta', 'feature']
    ],
    'paint': {
      'text-color': ['get', 'user_text-color'],
    },
    'layout': {
      'text-allow-overlap': true,
      'icon-allow-overlap': true,
      'text-size': ['get', 'user_text-size'],
      'icon-image': ['get', 'user_image-id'],
      'icon-size': ['get', 'user_icon-size'],
      'text-field': ['get', 'user_text'],
      'text-font': ['Open Sans Regular']
    }
  },
  {
    'id': 'gl-draw-polygon-fill-inactive',
    'type': 'fill',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'Polygon'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'fill-color': ['get', 'user_fill-color'],
      'fill-outline-color': ['get', 'user_line-color'],
      'fill-opacity': ['get', 'user_opacity']
    },
  },
  {
    'id': 'gl-draw-polygon-fill-active',
    'type': 'fill',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
    'paint': {
      'fill-color': ['get', 'user_fill-color'],
      'fill-outline-color': ['get', 'user_line-color'],
      'fill-opacity': ['get', 'user_opacity']
    },
  },
  {
    'id': 'gl-draw-polygon-midpoint',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'midpoint']],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-inactive',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'Polygon'],
      ['!=', 'mode', 'static']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-active',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-dasharray': [0.2, 2],
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-line-inactive',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'active', 'false'],
      ['==', '$type', 'LineString'],
      ['!=', 'mode', 'static']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': ['get', 'user_line-color'],
      'line-width': ['get', 'user_line-width'],
      'line-opacity': ['get', 'user_opacity'],
    }
  },
  {
    'id': 'gl-draw-line-active',
    'type': 'line',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'LineString'],
      ['==', 'active', 'true']
    ],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-dasharray': [0.2, 2],
      'line-color': ['get', 'user_line-color'],
      'line-width': 2,
      'line-opacity': 1,
    }
  },
  {
    'id': 'gl-draw-polygon-and-line-vertex-stroke-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'meta', 'vertex'],
      ['==', '$type', 'Point'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-polygon-and-line-vertex-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', 'meta', 'vertex'],
      ['==', '$type', 'Point'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-point-point-stroke-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['!has', 'user_display-type'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 5,
      'circle-opacity': 1,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-point-inactive',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['!has', 'user_display-type'],
      ['==', 'active', 'false'],
      ['==', '$type', 'Point'],
      ['==', 'meta', 'feature'],
      ['!=', 'mode', 'static']
    ],
    'paint': {
      'circle-radius': 3,
      'circle-color': '#3bb2d0'
    }
  },
  {
    'id': 'gl-draw-point-stroke-active',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['==', 'active', 'true'],
      ['!=', 'meta', 'midpoint']
    ],
    'paint': {
      'circle-radius': 7,
      'circle-color': '#fff'
    }
  },
  {
    'id': 'gl-draw-point-active',
    'type': 'circle',
    'filter': ['all',
      ['!=', 'user_visible', false],
      ['==', '$type', 'Point'],
      ['!=', 'meta', 'midpoint'],
      ['==', 'active', 'true']],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#fbb03b'
    }
  },
  {
    'id': 'gl-draw-polygon-fill-static',
    'type': 'fill',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
    'paint': {
      'fill-color': '#404040',
      'fill-outline-color': '#404040',
      'fill-opacity': 0.1
    }
  },
  {
    'id': 'gl-draw-polygon-stroke-static',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': '#404040',
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-line-static',
    'type': 'line',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'LineString']],
    'layout': {
      'line-cap': 'round',
      'line-join': 'round'
    },
    'paint': {
      'line-color': '#404040',
      'line-width': 2
    }
  },
  {
    'id': 'gl-draw-point-static',
    'type': 'circle',
    'filter': ['all', ['!=', 'user_visible', false], ['==', 'mode', 'static'], ['==', '$type', 'Point']],
    'paint': {
      'circle-radius': 5,
      'circle-color': '#404040'
    }
  },
];