react-three-map 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -66,7 +66,8 @@ We hope that you enjoy using React Three Map as much as we enjoyed building it.
66
66
 
67
67
  ## Roadmap
68
68
 
69
- - [ ] Use ThreeJS as a Map Layer.
69
+ - [x] Use ThreeJS as a Map Layer (Maplibre).
70
+ - [x] Support on demand rendering.
70
71
  - [ ] Use ThreeJS as a canvas overlay.
71
72
  - [ ] Add stencil buffers to occlude from the map.
72
73
  - [ ] Fully decompose the projection matrix into all the Camera properties required.
@@ -74,4 +75,4 @@ We hope that you enjoy using React Three Map as much as we enjoyed building it.
74
75
  - [ ] Support multiple coordinate transformations using only one ThreeJS renderer.
75
76
  - [ ] Support `drei` `<Html>` component.
76
77
  - [ ] Support MapBox.
77
- - [ ] Support on demand rendering.
78
+ - [ ] Support Google Maps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-map",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Use react-three-fiber inside MapLibre and Mapbox",
5
5
  "main": "dist/cjs/main.js",
6
6
  "module": "dist/es/main.js",
@@ -12,9 +12,13 @@ export function useOnAdd (ref: StateRef, renderProps: RenderProps<HTMLCanvasElem
12
12
  const onAdd = useFunction((map: MapInstance, gl: WebGLRenderingContext)=>{
13
13
 
14
14
  const canvas = map.getCanvas();
15
- const root = createRoot(canvas);
15
+ const invalidate = () => {
16
+ map.triggerRepaint();
17
+ return 0;
18
+ }
19
+ const root = createRoot(canvas, invalidate);
16
20
  root.configure({
17
- frameloop: "never",
21
+ frameloop: "demand",
18
22
  dpr: window.devicePixelRatio,
19
23
  shadows: true,
20
24
  events: createEvents(),
@@ -19,7 +19,9 @@ export function useRender(
19
19
  camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
20
20
  gl.resetState();
21
21
  advance(Date.now() * 0.001, true);
22
- map.current.triggerRepaint();
22
+ if(ref.current.state.frameloop === 'always') {
23
+ map.current.triggerRepaint();
24
+ }
23
25
  })
24
26
 
25
27
  return render;
@@ -2,20 +2,23 @@ import { ThemeState, useLadleContext } from "@ladle/react";
2
2
  import 'maplibre-gl/dist/maplibre-gl.css';
3
3
  import Map from 'react-map-gl/maplibre';
4
4
  import { Canvas } from "../canvas/canvas";
5
+ import { Canvas as FiberCanvas } from "@react-three/fiber"
5
6
  import { MyScene } from "./my-scene";
7
+ import { MapControls } from "@react-three/drei"
6
8
 
7
- export function BasicSetup() {
9
+ export function WithMap() {
8
10
  const theme = useLadleContext().globalState.theme;
9
- const mapStyle = theme === ThemeState.Dark
10
- ? "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
11
- : "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
11
+ const mapStyle = theme === ThemeState.Dark
12
+ ? "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
13
+ : "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
12
14
  return <div style={{ height: '100vh' }}>
13
15
  <Map
14
16
  antialias
15
17
  initialViewState={{
16
18
  latitude: 51.5073218,
17
19
  longitude: -0.1276473,
18
- zoom: 22
20
+ zoom: 18,
21
+ pitch: 60,
19
22
  }}
20
23
  mapStyle={mapStyle}
21
24
  >
@@ -26,3 +29,11 @@ export function BasicSetup() {
26
29
  </div>
27
30
  }
28
31
 
32
+ export const WithoutMap = () => {
33
+ return <div style={{ height: '100vh' }}>
34
+ <FiberCanvas camera={{position: [100,100,100]}} shadows="basic">
35
+ <MyScene />
36
+ <MapControls makeDefault />
37
+ </FiberCanvas>
38
+ </div>
39
+ }
@@ -1,41 +1,48 @@
1
1
  import { Box, Plane, useHelper } from "@react-three/drei";
2
- import { MeshProps, useFrame } from '@react-three/fiber';
2
+ import { MeshProps, useFrame, useThree } from '@react-three/fiber';
3
3
  import 'maplibre-gl/dist/maplibre-gl.css';
4
- import { useRef, useState } from 'react';
4
+ import { useCallback, useRef, useState } from 'react';
5
5
  import { CameraHelper, MathUtils, Mesh, OrthographicCamera } from "three";
6
6
 
7
7
  export function MyScene() {
8
8
  return <>
9
9
  <Lights />
10
10
  <Floor />
11
- <MyBox position={[-1.2, 1.5, 0]} />
12
- <MyBox position={[1.2, 1.5, 0]} />
13
- <MyBox position={[1.2, 1.5, 2.4]} />
11
+ <MyBox position={[-8* 3, 8*1.5, 0]} />
12
+ <MyBox position={[8*3, 8*1.5, 0]} />
14
13
  </>
15
14
  }
16
15
 
17
16
 
18
17
  function MyBox(props: MeshProps) {
19
18
  const [hovered, hover] = useState(false);
20
- const [clicked, click] = useState(false);
21
19
  const mesh = useRef<Mesh>(null)
20
+ const invalidate = useThree(st=>st.invalidate);
21
+
22
+ const onOver = useCallback(()=>{
23
+ hover(true);
24
+ }, [])
25
+
26
+ const onOut = useCallback(()=>{
27
+ hover(false);
28
+ }, [])
22
29
 
23
30
  useFrame((_st, dt)=>{
24
31
  if(!mesh.current) return;
25
32
  mesh.current.rotateY(dt);
33
+ invalidate();
26
34
  })
27
35
 
28
36
  return (
29
37
  <Box
30
38
  {...props}
31
39
  ref={mesh}
32
- args={[1, 1, 1]}
40
+ args={[16, 16, 16]}
33
41
  receiveShadow
34
42
  castShadow
35
- scale={props.scale || clicked ? props.scale || 1.5 : 1}
36
- onClick={() => click(!clicked)}
37
- onPointerOver={() => hover(true)}
38
- onPointerOut={() => hover(false)}
43
+ onClick={onOver}
44
+ onPointerOver={onOver}
45
+ onPointerOut={onOut}
39
46
  >
40
47
  <meshStandardMaterial
41
48
  color={hovered ? "red" : "orange"}
@@ -49,7 +56,7 @@ function Lights() {
49
56
  const cam = useRef<OrthographicCamera>(null);
50
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
58
  useHelper(cam as any, CameraHelper)
52
- const camSize = 5;
59
+ const camSize = 100;
53
60
  return <>
54
61
  <ambientLight intensity={0.5} />
55
62
  <directionalLight
@@ -73,7 +80,7 @@ function Lights() {
73
80
 
74
81
  function Floor() {
75
82
  return <Plane
76
- args={[50, 50]}
83
+ args={[200, 200]}
77
84
  position={[0, 0, 0]}
78
85
  rotation={[-90 * MathUtils.DEG2RAD, 0, 0]}
79
86
  receiveShadow
@@ -0,0 +1,46 @@
1
+ import { ThemeState, useLadleContext } from "@ladle/react";
2
+ import { Box, Stats } from "@react-three/drei";
3
+ import 'maplibre-gl/dist/maplibre-gl.css';
4
+ import { useState } from "react";
5
+ import Map from 'react-map-gl/maplibre';
6
+ import { MathUtils } from "three";
7
+ import { Canvas } from "../canvas/canvas";
8
+
9
+ export function Default() {
10
+
11
+ const theme = useLadleContext().globalState.theme;
12
+
13
+ const mapStyle = theme === ThemeState.Dark
14
+ ? "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
15
+ : "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json";
16
+
17
+ const [hovered, hover] = useState(false);
18
+
19
+ return <div style={{ height: '100vh', position: 'relative' }}>
20
+ <Map
21
+ antialias
22
+ initialViewState={{
23
+ latitude: 51,
24
+ longitude: 0,
25
+ zoom: 13,
26
+ pitch: 60,
27
+ }}
28
+ mapStyle={mapStyle}
29
+ >
30
+ <Canvas latitude={51} longitude={0}>
31
+ <Box
32
+ args={[500,500,500]}
33
+ position={[0,250,0]}
34
+ rotation={[0,45 * MathUtils.DEG2RAD,0]}
35
+ onPointerOver={() => hover(true)}
36
+ onPointerOut={() => hover(false)}
37
+ material-color={hovered ? 'purple' : 'orange'}
38
+ />
39
+ <Stats />
40
+ </Canvas>
41
+ </Map>
42
+ <div style={{position: 'absolute', top: 0, right: 0}}>
43
+ Hover over the box, it will only render once to change colour, or when you move the camera. Look at the stats to confirm.
44
+ </div>
45
+ </div>
46
+ }
@@ -1,12 +0,0 @@
1
- import { MapControls } from "@react-three/drei"
2
- import { Canvas } from "@react-three/fiber"
3
- import { MyScene } from "./my-scene"
4
-
5
- export const NoMap = () => {
6
- return <div style={{ height: '100vh' }}>
7
- <Canvas camera={{position: [0,10,0]}} shadows="basic">
8
- <MyScene />
9
- <MapControls makeDefault />
10
- </Canvas>
11
- </div>
12
- }