@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 3.63 kB
JavaScript
import{jsx as B}from"react/jsx-runtime";import"maplibre-gl/dist/maplibre-gl.css";import{Renderer as N}from"@expofp/renderer";import{addProtocol as U,Map as G}from"maplibre-gl";import{Protocol as Y}from"pmtiles";import{useEffect as E,useRef as c}from"react";import{createStyleTransform as k}from"./utils/resolve-map-style";export const MAP_DIM_LAYER_ID="expofp-map-dim";const y="expofp-map-dim-source",H="3d-expofp";let g=null;const J=["coalesce",["get","name:en"],["get","name_en"],["get","name:latin"],["get","name"]],V={type:"Feature",geometry:{type:"Polygon",coordinates:[[[-180,-85],[180,-85],[180,85],[-180,85],[-180,-85]]]},properties:{}};function I(e){if(!e||typeof e!="object")return!1;const r=e.length;if(typeof r!="number"||r<16)return!1;const o=e[0];return typeof o=="number"&&Number.isFinite(o)}function W(e){if(I(e))return Array.from(e);const o=e?.defaultProjectionData?.mainMatrix;return I(o)?Array.from(o):(console.warn("Maplibre custom layer received an unsupported projection matrix payload.",e),null)}function b(e){return typeof e=="string"?e.includes("name"):Array.isArray(e)?e.some(r=>b(r)):!e||typeof e!="object"?!1:Object.values(e).some(r=>b(r))}function X(e){return e.type!=="symbol"||!e.id||!e.layout?!1:b(e.layout["text-field"])}function q(e){const r=e.getStyle();for(const o of r.layers??[])X(o)&&e.setLayoutProperty(o.id,"text-field",J)}function K(){if(!g){g=new Y;try{U("pmtiles",g.tile)}catch(e){console.warn("Maplibre PMTiles protocol registration failed.",e)}}}export default function Q({sceneDef:e,geoConfig:r,staticTransform:o,tileSource:w,mapOptions:O,onRendererReady:h,onMapDimLayerReady:x,onMapLoadError:M}){const d=c(null),L=c(null),l=c(null),P=c(h),S=c(x),_=c(M),C=c({sceneDef:e,geoConfig:r,staticTransform:o,tileSource:w,mapOptions:O});return E(()=>{P.current=h,S.current=x,_.current=M}),E(()=>{if(!d.current)return;const{sceneDef:m,geoConfig:n,staticTransform:T,tileSource:A,mapOptions:u}=C.current;let p=!1;const f={...m};f.rootLayer={...m.rootLayer};const F=m.rootLayer.children;f.rootLayer.children=F.filter(i=>i?.name?.toString().toLowerCase()!=="areamap"),f.background=void 0,f.staticTransform=T,K();const z=n.bounds?{bounds:n.bounds,fitBoundsOptions:{padding:n.fitPadding,bearing:n.bearing}}:{center:n.center,zoom:n.zoom},j=k(A.style),t=new G({container:d.current,...z,bearing:n.bearing,pitch:u?.pitch??30,maxPitch:u?.maxPitch??70,minZoom:u?.minZoom,maxZoom:u?.maxZoom,maxBounds:u?.maxBounds,bearingSnap:0,canvasContextAttributes:{antialias:!0}});n.zoomAdjustment&&t.jumpTo({zoom:t.getZoom()+n.zoomAdjustment}),L.current=t,t.once("error",i=>{t.isStyleLoaded()||_.current?.(i?.error??i)});const R=i=>{const a=i?.id;!a||t.hasImage(a)||t.addImage(a,{width:1,height:1,data:new Uint8Array(4)})};t.on("styleimagemissing",R);const Z={id:H,type:"custom",renderingMode:"3d",onAdd(i,a){if(p)return;const s=new N({canvas:t.getCanvas(),gl:a});if(p){s.dispose();return}s.init(f),l.current=s,P.current?.(s,t,f,()=>t.triggerRepaint())},render(i,a){if(!l.current||l.current.isDisposed)return;const s=W(a??i);s&&l.current.render(s)}},D=()=>{q(t),t.getSource(y)||t.addSource(y,{type:"geojson",data:V}),t.getLayer(MAP_DIM_LAYER_ID)||t.addLayer({id:MAP_DIM_LAYER_ID,type:"fill",source:y,paint:{"fill-color":"#000000","fill-opacity":0,"fill-opacity-transition":{duration:0,delay:0}}}),S.current?.(t),t.addLayer(Z)};return t.on("style.load",D),t.setStyle(A.style,j?{transformStyle:j}:void 0),()=>{p=!0,t.off("style.load",D),t.off("styleimagemissing",R),l.current?.dispose(),l.current=null,t.remove(),L.current=null}},[]),B("div",{ref:d,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%"}})}