@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 5.5 kB
JavaScript
import{jsx as F,jsxs as Y}from"react/jsx-runtime";import{isLayerDefs as q}from"@expofp/renderer";import ee from"color";import{runInAction as re}from"mobx";import{observer as te}from"mobx-react-lite";import{useCallback as j,useEffect as R,useMemo as u,useRef as f,useState as $}from"react";import oe from"../../data";import{getLayerSvg as ne,svgArea as C,svgAreaExplicit as ie}from"../../data/svg";import{createSceneDef as ae}from"../../engine/defs";import t,{uiState as i}from"../../store";import M from"../../tools/settings";import V from"../../utils/is-debug";import{fitRectIsFraming as ce,getVenueFitMarginPercent as se,resolveVenueFitRect as le}from"../../utils/scene-bounds";import me from"../Map/drawing/config/config-all";import{loadLayersImages as ue}from"../Map/drawing/config/loadBoothsImages";import{MapCursorCoords as fe}from"../Map/MapCursorCoords";import{MapViewport as pe}from"../Map/MapViewport";import{clearSelection as de}from"../Map/pointer";import{setMapScene as B}from"../Map/scene";import{useBuildRoute as ge}from"../Map/traffic/useBuildRoute";import{useManageTraffic as be}from"../Map/traffic/useManageTraffic";import{centerCoordinates as Se}from"../Map/viewport";import he from"./MaplibreWrapper";import{useCameraReactions as ye}from"./useCameraReactions";import{useDimming as Re}from"./useDimming";import{useKioskCameraEvents as Ce}from"./useKioskCameraEvents";import{useLayerVisibilitySync as Me}from"./useLayerVisibilitySync";import{usePoiMarkers as Ae}from"./usePoiMarkers";import{useWayfindingAndMarkers as Le}from"./useWayfindingAndMarkers";import{cameraForLocalRect as Pe,deriveGeoConfig as ve,getLocalRectGeoBounds as ze,getVisibleRectFitPadding as De,INITIAL_FIT_ZOOM_ADJUSTMENT as xe}from"./utils/geo-config";import{applyMapOptions as N,getTileSource as Te,MAP_MIN_ZOOM as Ee}from"./utils/map-helpers";import{calculateTransformMatrix as Oe}from"./utils/solver";const U="routes-api.expofp.com",we=800;function Ie(a,b,s){return{getCameraState:()=>{const o=a.getCenter();return{lng:o.lng,lat:o.lat,zoom:a.getZoom(),bearing:a.getBearing(),pitch:a.getPitch()}},applyCameraState:o=>{a.easeTo({center:[o.lng,o.lat],zoom:o.zoom,bearing:o.bearing??b,pitch:o.pitch??s(),duration:we,essential:!0})},resetPitch:()=>{const o=s();a.getPitch()!==o&&a.jumpTo({pitch:o})}}}function Z(){t.poiMarkerStore.clear(),re(()=>{t.layerStore.layers.forEach(a=>{a.configured=!1,a.children=[],a.loaded=!1}),t.layerStore.layersLoaded=!1})}const _e=te(function({viewMode:b}){const[s,o]=$(null),[z,D]=$(!1),m=f(null),p=f(null),A=f(null),x=f(null),S=f(null),r=u(()=>ve(),[]),L=u(()=>le({layerViewbox:t.layerStore.viewboxRectangle,explicitArea:ie?C:null,layerRectangle:t.layerStore.rectangle,sceneDef:s,svgArea:C}),[s]),h=L.rect,d=u(()=>{if(!r)return null;const e=ce(L.source)?0:se(h,C),n=De(0);e&&i.screenSize&&(n.left+=i.screenSize.width*e,n.right+=i.screenSize.width*e,n.top+=i.screenSize.height*e,n.bottom+=i.screenSize.height*e);const l=i.screenSize?Pe(h,r.gpsConfig,r.bearing,{width:i.screenSize.width,height:i.screenSize.height},n):null;return l?{center:l.center,bearing:r.bearing,zoom:l.zoom}:{center:r.center,bearing:r.bearing,zoom:r.zoom,bounds:ze(h,r.gpsConfig),fitPadding:n,zoomAdjustment:xe}},[r,L,h]),y=u(()=>r?Oe(r.gpsConfig,ne()?.getAttribute("units")):null,[r]),T=i.mapSettings.pitchdegrees,E=i.maxPitch,g=u(()=>{const e=b==="map2d";return{pitch:e?0:T,maxPitch:e?0:E,minZoom:Ee}},[b,T,E]),P=f(g),G=u(()=>Te(),[]),c=u(()=>{if(!s||!y)return null;const e=s.rootLayer.children,n=q(e)?e.filter(l=>l.name.toLowerCase()!=="areamap"):e;return{...s,rootLayer:{...s.rootLayer,children:n},background:void 0,staticTransform:y}},[s,y]),O=f(null);R(()=>{O.current=c},[c]),R(()=>{if(c)return B(c),()=>B(void 0)},[c]);const{mapDimAnimatorRef:w,venueDimAnimatorRef:I,applyDimmingTarget:_,handleMapDimLayerReady:J}=Re(m,O);R(()=>{if(!r)return;let e=!1;Z(),me().then(({layers:v,cleanup:k})=>{if(e){k();return}A.current=k;const Q=ee(M.backgroundColor==="none"?"#ebebeb":M.backgroundColor).string();o(ae(v,C,Q))}).catch(v=>{e||console.warn("Maplibre scene configuration failed.",v)});const n=w.current,l=I.current;return()=>{e=!0,Z(),A.current?.(),A.current=null,S.current&&(t.maplibreStore.clearCameraPortIfCurrent(S.current),S.current=null),m.current=null,p.current=null,x.current=null,D(!1),n?.stop(),l?.stop(),i.sceneDefReady=!1}},[r,w,I]);const K=j((e,n)=>{m.current=e,p.current=e.getCanvas(),x.current=n,D(!0),e.once("idle",()=>N(e,P.current));const l=Ie(e,r?.bearing??e.getBearing(),()=>P.current.pitch??0);S.current=l,t.maplibreStore.setCameraPort(l),t.fp.getCenterCoordinates=()=>Se(p.current),_({immediate:!0}),ue(),t.layerStore.layersLoaded=!0,t.fp.onFpConfigured&&t.fp.onFpConfigured(),i.sceneDefReady=!0,n()},[_,r]);R(()=>{P.current=g,N(m.current,g)},[g]),Ce(z,m),Le(c,p),Ae(z,m,r),Me(c,m,r),ye(m,r,c),ge({enabled:t.layerStore.layersLoaded&&i.buildRoute,scene:c??void 0});const W=oe.busRoutes??!1;be({permission:t.layerStore.layersLoaded&&W,scene:c??void 0,dataJsonUrl:`https://${U}/v1/routes?expo=${M.EXPO}`,websocketUrl:`wss://${U}/locations?expo=${M.EXPO}`});const X=j(e=>{console.warn("Maplibre map failed to load; falling back to floorplan mode.",e),t.maplibreStore.deactivateMaplibre()},[]);if(!r||!d||!y||!c)return null;const H=`${d.center.join(",")}:${d.bearing}:${d.zoom}`;return Y(he,{sceneDef:c,geoConfig:d,tileSource:G,mapOptions:g,debug:V,onMapReady:K,onMapDimLayerReady:J,onMapLoadError:X,onPointerMissed:de,children:[F(pe,{}),V&&F(fe,{canvas:p})]},H)});export default _e;