Code example
import { useMemo, useState } from 'react';
import {
Spherical,
createCircleState,
createGeoPoint,
createMapCameraPosition,
type MarkerState,
} from '@mapconductor/js-sdk-core';
import { Circle, Marker, Polyline } from '@mapconductor/js-sdk-react';
import { MapLibreDesign, MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
// (1) Create the map
const initialCamera = createMapCameraPosition({
position: createGeoPoint({ latitude: 35.6812, longitude: 139.7671 }),
zoom: 12,
});
const mapViewState = useMapLibreViewState({
mapDesignType: MapLibreDesign.OsmBrightJa,
cameraPosition: initialCamera,
});
// (2) Prepare the data and interaction state
const center = createGeoPoint({ latitude: 21.382314, longitude: -157.933097 });
const [edge, setEdge] = useState(() => Spherical.computeOffset({
origin: center, distance: 1000, heading: 90,
}));
const radiusMeters = useMemo(
() => Spherical.computeDistanceBetween(center, edge),
[edge],
);
const circleState = useMemo(() => createCircleState({
id: 'circle', center, radiusMeters,
fillColor: 'rgba(37, 99, 235, 0.3)',
}), [radiusMeters]);
const resizeCircle = (markerState: MarkerState) => setEdge(markerState.position);
// (3) Render the map and its overlays
<MapLibreMapView2D state={mapViewState}>
<Circle state={circleState} />
<Polyline points={[center, edge]} zIndex={1} />
<Marker position={center} />
<Marker position={edge} draggable onDrag={resizeCircle} />
</MapLibreMapView2D>
How the code works
Draw a circle and resize its radius by dragging the edge marker; the radius line is ordered above the circle.
The edge point is React state seeded by Spherical.computeOffset, Spherical.computeDistanceBetween(center, edge) derives radiusMeters, and useMemo rebuilds the CircleState whenever that radius changes.
Dragging the edge marker calls resizeCircle to move edge, while the Polyline drawn at zIndex 1 keeps the radius line above the fill and the circle grows to match.