React Three Map - v1.0.9
    Preparing search index...

    Interacting with the Map

    This guide covers how to interact with the underlying map from your Three.js components.

    The useMap hook gives you access to the MapLibre or Mapbox map instance.

    import { useMap } from "@wendylabsinc/react-three-map/maplibre";

    function MapController() {
    const map = useMap();

    const flyToLondon = () => {
    map.flyTo({
    center: [-0.1278, 51.5074],
    zoom: 15,
    pitch: 60,
    duration: 2000
    });
    };

    return (
    <mesh onClick={flyToLondon}>
    <boxGeometry args={[50, 50, 50]} />
    <meshStandardMaterial color="blue" />
    </mesh>
    );
    }

    You can subscribe to map events like zoom, pan, and rotation changes.

    import { useMap } from "@wendylabsinc/react-three-map/maplibre";
    import { useEffect, useState } from "react";

    function ZoomIndicator() {
    const map = useMap();
    const [zoom, setZoom] = useState(map.getZoom());

    useEffect(() => {
    const onZoom = () => setZoom(map.getZoom());
    map.on("zoom", onZoom);
    return () => map.off("zoom", onZoom);
    }, [map]);

    // Scale object based on zoom level
    const scale = Math.pow(2, 15 - zoom) * 10;

    return (
    <mesh scale={[scale, scale, scale]}>
    <sphereGeometry args={[1]} />
    <meshStandardMaterial color="red" />
    </mesh>
    );
    }

    When using frameloop="demand", you control when the scene re-renders:

    import { useThree } from "@react-three/fiber";

    function AnimatedObject() {
    const invalidate = useThree((state) => state.invalidate);

    // Call invalidate() whenever you need a re-render
    const handleClick = () => {
    // ... update some state
    invalidate(); // Request a new frame
    };

    return (
    <mesh onClick={handleClick}>
    <boxGeometry />
    </mesh>
    );
    }

    Useful for loading data only for the visible area:

    import { useMap } from "@wendylabsinc/react-three-map/maplibre";
    import { useEffect } from "react";

    function VisibleAreaLoader() {
    const map = useMap();

    useEffect(() => {
    const loadVisibleData = () => {
    const bounds = map.getBounds();
    console.log("Visible area:", {
    north: bounds.getNorth(),
    south: bounds.getSouth(),
    east: bounds.getEast(),
    west: bounds.getWest()
    });
    // Load data for these bounds...
    };

    map.on("moveend", loadVisibleData);
    loadVisibleData(); // Initial load

    return () => map.off("moveend", loadVisibleData);
    }, [map]);

    return null;
    }

    You can combine map interaction with React Three Fiber hooks:

    import { useMap } from "@wendylabsinc/react-three-map/maplibre";
    import { useFrame } from "@react-three/fiber";
    import { useRef } from "react";

    function CompassNeedle() {
    const map = useMap();
    const meshRef = useRef();

    useFrame(() => {
    if (meshRef.current) {
    // Rotate to always point north regardless of map rotation
    const bearing = map.getBearing();
    meshRef.current.rotation.y = (bearing * Math.PI) / 180;
    }
    });

    return (
    <mesh ref={meshRef}>
    <coneGeometry args={[10, 50, 4]} />
    <meshStandardMaterial color="red" />
    </mesh>
    );
    }