@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 2.08 kB
JavaScript
import{Box as d,Polygon as S,Rect as P}from"@expofp/geometry";import{getTrianglesFromFpPaths as A}from"../../data/svg";import{boothStore as x,layersStore as u}from"../../store";import{LayersMode as H}from"../../store/LayerStore";import{eventScopedValue as T}from"../../tools/event-scoped-cache.js";import w from"../../tools/logger";import{planReaction as M}from"../../utils/plan-reactions.js";const b=T(()=>({segments:[],segmentToHitAreas:new Map,prevSegment:null,boothsWithPaths:[]}));function I(){const c=x.booths.filter(t=>t.visible&&t.rect&&t.rect.size.width>0&&t.rect.size.height>0),o=b();if(o.segments=[],o.prevSegment=null,o.segmentToHitAreas=new Map,o.boothsWithPaths=c.filter(t=>t.paths),!c.length)return;const s=[];let m=1/0,i=1/0,l=-1/0,e=-1/0;for(const t of c){const f=t.rotate?new P(t.rect.center,t.rect.size,t.rotate):null,n=f?f.bounds:t.rect;s.push({booth:t,shape:f??t.rect,bounds:n}),n.min.x<m&&(m=n.min.x),n.min.y<i&&(i=n.min.y),n.max.x>l&&(l=n.max.x),n.max.y>e&&(e=n.max.y)}const r=d.fromMinMax({x:m,y:i},{x:l,y:e}),a=2,h=Math.ceil(r.size.width/a),g=Math.ceil(r.size.height/a);for(let t=0;t<a;t++)for(let f=0;f<a;f++){const n=r.min.x+t*h,y=r.min.y+f*g,p=new d(n,y,h,g);o.segments.push(p),o.segmentToHitAreas.set(p,s.filter(v=>p.intersects(v.bounds)))}w.log("hover segmentToHitAreas",o.segmentToHitAreas)}export function bindBoothHitTest(){M(()=>[x.booths,u.loaded,u.visible],()=>I(),{fireImmediately:!0})}function z(c,o){const s=b(),m={x:c,y:o};let i;s.prevSegment&&s.prevSegment.containsPoint(m)?i=s.prevSegment:i=s.segments.find(e=>e.containsPoint(m)),i&&(s.prevSegment=i);const l=i?s.segmentToHitAreas.get(i):void 0;if(l){const e=l.filter(r=>r.booth.visible&&r.shape.containsPoint(m));if(e.length)return(e.length>1?e.sort((a,h)=>a.booth.rect.area-h.booth.rect.area)[0]:e[0]).booth}for(const e of s.boothsWithPaths)if(e.visible)for(const r of e.paths)for(const a of A(r.index,u.mode!==H.Default?e.layer.name:"")){const h=a.map(g=>({x:g[0],y:g[1]}));if(S.fromConvexRing(h).containsPoint(m))return e}return null}export default function X(c,o){return z(c,o)}