react-three-map is a bridge to use react-three-fiber inside react-map-gl.
Until now you had:
| imperative | declarative (react) |
|---|---|
| Maplibre/Mapbox | react-map-gl |
| THREE.js | react-three-fiber |
Now with react-three-map, you can use them together 🤜⭐🤛.
npm install react-three-mapCheck out our examples here (powered by Ladle).
Let's build the same react-three-fiber basic example, but now it can be inside a map. (live demo). | ![]() |
- Import
Canvasfromreact-three-mapinstead of@react-three/fiber. - Give it a latitude and longitude so it knows where to position the scene in the map.
- Everything else should work just as usual.
import"maplibre-gl/dist/maplibre-gl.css"import{createRoot}from'react-dom/client'importReact,{useRef,useState}from'react'import{useFrame}from"@react-three/fiber"import{useRef,useState}from"react"importMapfrom"react-map-gl/maplibre"import{Canvas}from"react-three-map/maplibre"// import { Canvas } from "react-three-map" // if you are using MapBoxfunctionBasicExample(){return<MapantialiasinitialViewState={{latitude: 51,longitude: 0,zoom: 13,pitch: 60}}mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"><Canvaslatitude={51}longitude={0}><hemisphereLightargs={["#ffffff","#60666C"]}position={[1,4.5,3]}/><object3Dscale={500}><Boxposition={[-1.2,1,0]}/><Boxposition={[1.2,1,0]}/></object3D></Canvas></Map>}Look how complex is to add just one ThreeJS object to a map.
Look how complex is to create your custom root for R3F.
You can now replace all that complexity and hundreds of lines of code with the <Canvas> component exported by react-three-map, which includes a tone of extra features and seamless integration, supporting pointer events, raycasting, and much more, all out of the box.
Same as in @react-three/fiber, the <Canvas> object is where you start to define your React Three Fiber Scene.
import"maplibre-gl/dist/maplibre-gl.css"importMapfrom"react-map-gl/maplibre"import{Canvas}from'react-three-map/maplibre'// import { Canvas } from "react-three-map" // if you are using MapBoxconstApp=()=>(<MapinitialViewState={{latitude: 51,longitude: 0,zoom: 13}}mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"><Canvaslatitude={51}longitude={0}><pointLightposition={[10,10,10]}/><mesh><sphereGeometry/><meshStandardMaterialcolor="hotpink"/></mesh></Canvas></Map>)It shares most of the props from R3F <Canvas>, so you can check them directly in the @react-three/fiber docs. There are a few important exceptions though, which are mentioned bellow.
| Prop | Description | Default |
|---|---|---|
| latitude | The latitude coordinate where to add the scene. | |
| longitude | The longitude coordinate where to add the scene. | |
| altitude | The altitude coordinate where to add the scene. | 0 |
| frameloop | Render mode: "always", "demand". | "always" |
Because the scene now lives in a map, we leave a lot of the render and camera control to the map, rather than to R3F.
Therefore, the following <Canvas> props are ignored:
- gl
- camera
- resize
- orthographic
- dpr
This component allows you to have 3D objects at different coordinates.
import{Canvas,Coordinates}from'react-three-map'<Canvaslatitude={51}longitude={0}><Coordinateslatitude={50}longitude={0}><mesh><sphereGeometry/></mesh></Coordinates><Coordinateslatitude={52}longitude={0}><mesh><sphereGeometry/></mesh></Coordinates></Canvas>| Props | Description | Default |
|---|---|---|
| latitude | The latitude coordinate where to add the scene. | |
| longitude | The longitude coordinate where to add the scene. | |
| altitude | The altitude coordinate where to add the scene. | 0 |
Access the map from inside react-three-map.
import{useMap}from"react-three-map";// import { useMap } from "react-three-map/maplibre"; if you use maplibreconstComponent=()=>{constmap=useMap();return<>...</>}
