@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 4.67 kB
JavaScript
import{Rect as S}from"@expofp/geometry";import{update as E}from"@expofp/renderer";import{comparer as H,reaction as X}from"mobx";import{createImageDef as M}from"../../../../engine/defs";import{DEFAULT_FONT_URL as k}from"../../../../engine/fonts";import{boothStore as Y,uiState as B}from"../../../../store";import{createDimmingAnimator as G}from"../../../../utils/dimming";import{createClusterPinCanvas as W,createPoiPinCanvas as $}from"./canvases";import{clusterCounterCircle as K,clusterCountFontPx as L,clusterCountText as R,COUNT_BLOCK_HALF_EM as V,PIN_ASPECT as _}from"./pin-geometry";export function configPins(t,i,s){const o=[];let r=[],n=[],u=[];function f(){const c=B.selectedPoiTypeFilters;if(!c.length)return[];const P=new Set(c.map(m=>m.id));return Y.booths.filter(m=>m.visible&&P.has(m.poiTypeId)&&m.rect)}const d=c=>{r.push(c)};function e(){r.forEach(c=>c.stop()),r=[]}function a(){t.children=n.map(c=>Q(c,d))}function l(){u=Array.from({length:Math.floor(n.length/2)},()=>Z(d)),i.children=u.map(c=>c.image),s.children=u.map(c=>c.count)}function p(c,P){const m=new Set,y=C=>C?.forEach(b=>m.add(b)),N=tt(u,c,nt*P.pixelSize);N.forEach((C,b)=>{et(C,c[b])&&y([C.image,C.count]),y(C.fader.place(!0))});const D=new Set(N);for(const C of u)D.has(C)||y(C.fader.place(!1));return m.size?[...m]:void 0}const h={onCluster:(c,P)=>p(c,P),marker:{width:x,height:T,origin:w}};return t.clustering=h,o.push(X(()=>f(),c=>{n=c,e(),a(),l(),E(t,i,s)},{equals:H.shallow,fireImmediately:!0})),function(){o.forEach(P=>P()),o.length=0,e(),u=[],t.clustering=void 0,t.children=[],i.children=[],s.children=[],E(t,i,s)}}function A(t,i,s,o,r){let n,u=r,f=!1,d=!1;const e=l=>{const p=1-Math.min(Math.max(l,0),1);let h=!1;if(s()!==p&&(i(p),h=!0),!u&&l>=1&&t.some(c=>!c.hidden)){for(const c of t)c.hidden=!0;h=!0}h&&(f?d=!0:E(...t))},a=()=>{if(!n&&(n=G(e,PIN_FADE_MS),o(n),!r)){const l=f;f=!0,n.setTarget(!0,{immediate:!0}),f=l}return n};return{place(l){if(l===u)return;u=l;let p=!1;if(l&&t.some(h=>h.hidden)){for(const h of t)h.hidden=!1;p=!0}return f=!0,d=!1,a().setTarget(!l),f=!1,p||d?t:void 0}}}function U(t,i,s,o){const{bounds:r}=t,n=i*o,u=i*s*o;if(!(r.size.x===n&&r.size.y===u))return r.set(r.center.x,r.center.y,n,u,r.rotation,r.elevation),[t]}function j(){return v||(v=$(g,window.devicePixelRatio)),v}function J(){return I||(I=W(x,window.devicePixelRatio)),I}function Q(t,i){const s=new S(t.rect.center,{x:g,y:g*_},0,t.elevation*2),o={...M(j(),s,{hidden:!1,origin:w}),screenSpace:!0,opacity:1};o.onScale=({pixelSize:n})=>U(o,g,_,n);const r=A([o],n=>{o.opacity=n},()=>o.opacity??1,i,!0);return o.placement={onPlace:n=>r.place(n)},o}function z(t){const i=Math.round(Math.min(Math.max(t,0),1)*255).toString(16);return`${ot}${i.padStart(2,"0")}`}function Z(t){const i=new S({x:0,y:0},{x,y:T},0,0),s={...M(J(),i,{hidden:!0,origin:w}),screenSpace:!0,opacity:0};s.onScale=({pixelSize:n})=>U(s,x,_,n);const o=q(s),r=A([s,o],n=>{s.opacity=n,o.lines[0].color=z(n)},()=>s.opacity??1,t,!1);return{image:s,count:o,fader:r}}function q(t){const i={lines:[{text:R(2),color:z(0),fontUrl:k,fontSize:0}],bounds:new S({x:t.bounds.center.x,y:t.bounds.center.y},{x:0,y:0},0,t.bounds.elevation),padding:[0,0],alignment:{horizontal:"center",vertical:"top",text:"center"},screenSpace:!0,hidden:!0};return i.onScale=({pixelSize:s})=>{const o=L(O.r)*s,r=x*s,u=2*((T-O.cy)*s+V*o),{bounds:f}=i,[d]=i.lines;if(!(d.fontSize===o&&f.size.x===r&&f.size.y===u))return d.fontSize=o,f.set(t.bounds.center.x,t.bounds.center.y,r,u,f.rotation,t.bounds.elevation),[i]},i}function tt(t,i,s){const o=Math.min(i.length,t.length),r=[],n=new Set,u=[];t.forEach(({image:e},a)=>{if(!e.hidden)for(let l=0;l<o;l++){const{x:p,y:h}=i[l],c=Math.hypot(p-e.bounds.center.x,h-e.bounds.center.y);c<=s&&u.push({distance:c,cluster:l,unit:a})}}),u.sort((e,a)=>e.distance-a.distance||e.cluster-a.cluster||e.unit-a.unit);for(const{cluster:e,unit:a}of u)r[e]||n.has(t[a])||(r[e]=t[a],n.add(t[a]));const f=t.map((e,a)=>({unit:e,index:a})).filter(({unit:e})=>!n.has(e)).sort((e,a)=>F(e.unit)-F(a.unit)||e.index-a.index);let d=0;for(let e=0;e<o;e++)r[e]||(r[e]=f[d++].unit);return r}function F({image:t}){return t.hidden?0:t.opacity??1}function et({image:t,count:i},s){const{x:o,y:r,elevation:n,unitCount:u}=s,f=R(u),[d]=i.lines,e=t.bounds;if(e.center.x===o&&e.center.y===r&&e.elevation===n&&d.text===f)return!1;e.set(o,r,e.size.x,e.size.y,e.rotation,n);const{bounds:a}=i;return a.set(o,r,a.size.x,a.size.y,a.rotation,n),d.text=f,!0}export const PIN_LAYER_NAME="poiFilterPins",PIN_CLUSTER_LAYER_NAME="poiFilterPinClusters",PIN_COUNT_LAYER_NAME="poiFilterPinCounts",PIN_FADE_MS=300;const g=32,w=[.5,1],x=44,nt=x,ot="#000000",O=K(x),T=x*_;let v,I;