@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 3.31 kB
JavaScript
import{Box as T}from"@expofp/geometry";import{update as M}from"@expofp/renderer";import{reaction as R}from"mobx";import{createImageDef as L}from"../../../../engine/defs";import{attachExactRoll as V}from"../../../../engine/utils/rotation.js";import u,{layersStore as P,uiState as W}from"../../../../store";import{setMarkerResolver as B}from"../../pointer";import{createImageCanvas as Y,getBounds as y,imageCanvasCssSize as A}from"./canvases";const _="_selected";export const MARKER_LAYER_NAME="markers";export function rescaleMarker(s,h,f){const{center:r,rotation:a,elevation:o}=s.bounds,{width:i,height:m}=h;return s.bounds=y(r.x,r.y,i,m,f,a,o),[s]}function j(s){b=s}export function configMarkers(s){const{scene:h}=s,f=[],r=new Map,a=new Map;let o=[];const i=h.rootLayer.children.find(e=>e.name===MARKER_LAYER_NAME);i.onScale=({pixelSize:e})=>j(e),B(markerAt),M(i);async function m(e){const t=[];e.forEach(c=>{const{name:d,content:n,width:l,height:g,scale:k}=c;if(r.has(d))return;const p=new Image,x=new Promise((w,D)=>{p.onload=()=>{r.set(d,{img:p,width:l,height:g,scale:k}),w()},p.onerror=v=>{D(v)}});t.push(x),p.src=n,p.crossOrigin="anonymous"}),await Promise.all(t)}const E=(e,t)=>{e.onScale=({pixelSize:c})=>rescaleMarker(e,t,c)},$=e=>{e.screenSpace||V(e)};function I(e,t){const c=a.get(e);if(c)return c;const d=Y(t.img,t.width,t.height,window.devicePixelRatio,t.scale||1);return a.set(e,d),d}function F(){const e=u.routeStore.markersData.markers;if(!e.length)return;o=[];const t=1,c=0,d=W.is3DView;e.forEach(n=>{const l=r.get(n.icon);if(!l)return;const g=r.get(n.selectedIcon);if(!g)return;const k=l.scale||1,p=I(n.icon,l),x=I(n.selectedIcon,g),w=P.findLayer(n.z)?.visible??!0,D=A(l.img,l.width,l.height,k),v=A(g.img,g.width,g.height,k),N=y(n.x,n.y,D.width,D.height,t,c),O=y(n.x,n.y,v.width,v.height,t,c);let S;switch(n.position){case"lefttop":S=[0,0];break;case"centertop":S=[.5,0];break;case"centerbottom":S=[.5,1];break;default:S=[.5,.5]}const C={...L(p,N,{hidden:!w,origin:S}),id:n.id,scale:k,screenSpace:d},z={...L(x,O,{hidden:!(w&&n.active),origin:S}),id:`${n.id}${_}`,scale:k,screenSpace:d};E(C,D),E(z,v),o.push(C,z)}),i.children=o,o.forEach($)}function H(){i.children=[],o=[]}function K(){const e=u.routeStore.markersData.markers;e.length&&e.forEach(t=>{const c=o.find(l=>l.id===t.id),d=o.find(l=>l.id===`${t.id}${_}`);if(!c||!d)return;const n=P.findLayer(t.z)?.visible??!0;t.active?(c.hidden=!0,d.hidden=!(n&&t.active)):(c.hidden=!n,d.hidden=!0)})}return f.push(R(()=>[u.routeStore.selectedMarkers,u.layerStore.visible],()=>{if(!u.routeStore.markersData.markers.length){H(),M(i);return}K(),M(...o)})),f.push(R(()=>u.routeStore.markersData.markers,()=>{m(u.routeStore.markersData.icons).then(()=>{F(),M(i)})},{fireImmediately:!0})),function(){f.forEach(t=>t()),f.length=0,i.onScale=void 0,B(),b=1,M(i)}}export function markerAt(s,h){return getMarkerFromClick(s,h,b)}export function getMarkerFromClick(s,h,f){for(const r of u.routeStore.markersData.markers){const a=u.routeStore.markersData.icons.find(m=>m.name===r.icon);if(!a)continue;const o=a.width*(a.scale||1)*f,i=a.height*(a.scale||1)*f;if(q(s,h,r.x,r.y,o,i)){const m=u.layerStore.findLayer(r.z);if(!m||m&&m.visible)return r}}return null}function q(s,h,f,r,a,o){return T.fromCenter({x:f,y:r},{x:2*a,y:2*o}).containsPoint({x:s,y:h})}let b=1;