@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 5.36 kB
JavaScript
import{Box as q,pointRotate as R,Polygon as J,Rect as v}from"@expofp/geometry";import{update as L}from"@expofp/renderer";import K from"color";import{reaction as P}from"mobx";import{SEPARATOR as G}from"../../../../constants";import U from"../../../../data";import{getTrianglesFromFpPaths as Y}from"../../../../data/svg";import{createShapeDef as tt,createTextDef as et,createTextDefLines as nt}from"../../../../engine/defs";import{loadCustomFontsUrls as ot}from"../../../../engine/fonts";import{getQuarterTurns as rt,getRollValue as st}from"../../../../engine/update-def";import{boothStore as it,uiState as N}from"../../../../store";import{RegularBooth as ct}from"../../../../store/BoothStore";import k from"../../../../tools/settings";import{getContrastTextColor as at}from"../../../../utils/getContrastTextColor";import{getFont as lt}from"./canvases";import{isBoothBadgeEligible as ht}from"./config-booth-badge-eligibility";import{getBadgeFontWeight as dt,getFontUrlByWeight as ut}from"./config-booth-labels";const ft=.5,gt=.3,z=15,mt=24,X=30,xt=12,pt=12,Z=.8,Q=document.createElement("canvas").getContext("2d");function yt(t){return t.length<=z?t:t.slice(0,z-1)+"\u2026"}function V(t){if(!t.paths?.length)return[];const n=t.layer?.name||"",e=[];for(const o of t.paths)for(const r of Y(o.index,n))e.push(r);return e}function Bt(t){const n=V(t);return n.length?q.fromPoints(n.flat().map(([e,o])=>({x:e,y:o}))):null}function St(t){const n=[],e=[];for(const o of t){const r=n.length;n.push({x:o[0][0],y:o[0][1]}),n.push({x:o[1][0],y:o[1][1]}),n.push({x:o[2][0],y:o[2][1]}),e.push([r,r+1,r+2])}return new J(n,e)}function H(t,n,e){return e.containsPoint({x:t,y:n})}function At(t,n,e,o,r,h,i,c){if(!t.length||!H(e,o,n))return i;const d={x:e,y:o};let a=0,f=i;const A=10;for(let y=0;y<A;y++){const m=(a+f)/2,I=r*m,g=h*m;[R({x:e+I,y:o},c,d),R({x:e,y:o+g},c,d),R({x:e+I,y:o+g},c,d)].every(l=>H(l.x,l.y,n))?a=m:f=m}return a}function Et(t){return Bt(t)??t.rect}function Tt(t,n,e,o,r,h){if(n.length){const a=Et(t),f={x:r>0?a.min.x:a.max.x,y:h>0?a.min.y:a.max.y},A=new Set;let y=null,m=1/0;for(const I of n)for(const g of I){const _=`${g[0]},${g[1]}`;if(A.has(_))continue;A.add(_);const u=g[0]+o*r,l=g[1]+o*h;if(H(u,l,e)){const B=Math.abs(u-f.x)+Math.abs(l-f.y);B<m&&(m=B,y={x:u,y:l})}}if(y)return y}const i=r>0?t.rect.min.x+o:t.rect.max.x-o,c=h>0?t.rect.min.y+o:t.rect.max.y-o,d=t.rotate??0;return d?R({x:i,y:c},d,t.rect.center):{x:i,y:c}}function W(t){return t&&t!=="none"?t:void 0}function It(t){const n=W(t.borderColor)||W(k.boothBorderColor)||k.colors.booths.default;return t.paths?.length>1&&W(t.paths[t.paths.length-1].color)||n}export function createBoothBadge(t){const n=yt(t.title||t.name),e=It(t),o=at(K(e).hex()),r=dt(),h=lt(X,r);Q.font=h;const i=Q.measureText(n).width,c=Math.ceil(i+xt*2),d=X+pt*2,a=(t.borderWidth||it.borderWidth)/2,f=c*Z,A=d*Z,y=t.rect.size.width,m=t.rect.size.height,I=s=>{const E=s?m:y,p=s?y:m;return Math.min(E>0?E*ft/f:1/0,p>0?p*gt/A:1/0)},g=V(t),_=St(g);let u=t.rotate??0,l=0,B=0,D=0,O=0;const w=()=>{const p=Tt(t,g,_,a,l===0||l===3?1:-1,l===0||l===1?1:-1);B=p.x,D=p.y;const T=I(l===1||l===3);O=At(g,_,B,D,f,A,T,u)};w();const F=(s,E)=>{const p=s/2,T=E/2,j=R({x:B+p,y:D+T},u,{x:B,y:D});return new v(j,{x:s,y:E},u,t.elevation)},$=ut(r,ot()),x=tt(F(1,1),e);x.hidden=!0,x.dim=t.skipDim?0:void 0;const S=et(nt([[n],[]],o,0,[$,$]),F(1,1),[0,0],{horizontal:"center",vertical:"center"});S.hidden=!0,S.dim=t.skipDim?0:void 0;const C={booth:t,anchor:{x:B,y:D},source:{x:f,y:A},rotation:u,maxScale:O,bg:x,text:S},b=new BoothBadgeDrawer(C);x.onScale=({pixelSize:s})=>b.layOutBg(s),S.onScale=({pixelSize:s})=>b.layOutText(s);const M=[];return M.push(P(()=>t.skipDim,s=>{x.dim=s?0:void 0,S.dim=s?0:void 0,L(x,S)})),M.push(P(()=>t.layer?.visible??!0,s=>{x.hidden=!s,S.hidden=!s,L(x,S)})),M.push(P(()=>N.mapSettings,({roll:s})=>{st(s??0)&&(x.onRoll=({roll:E,pixelSize:p})=>{const T=rt(E,u);if(T!==0)return u+=T*Math.PI/2,l=((l+T)%4+4)%4,w(),C.anchor.x=B,C.anchor.y=D,C.rotation=u,C.maxScale=O,[...b.layOutBg(p),...b.layOutText(p)]})},{fireImmediately:!0})),{bg:x,text:S,dispose:()=>{M.forEach(s=>s()),M.length=0}}}export class BoothBadgeDrawer{constructor(n){this.placement=n}layOutBg(n){const{bg:e}=this.placement;return e.shape=this.rectScaled(n),e.hidden=this.isHidden(),e.hidden?[]:[e]}layOutText(n){const{text:e,maxScale:o}=this.placement;return e.lines[0].fontSize=mt*Math.min(n,o),e.bounds=this.rectScaled(n),e.hidden=this.isHidden(),e.hidden?[]:[e]}rectScaled(n){const{anchor:e,booth:o,source:r,rotation:h,maxScale:i}=this.placement,c=Math.min(n,i),d=r.x*c,a=r.y*c,f=R({x:e.x+d/2,y:e.y+a/2},h,e);return new v(f,{x:d,y:a},h,o.elevation)}isHidden(){const{booth:n}=this.placement;return!!(n.layer&&!n.layer.visible)}}export function configBoothsBadges(t,n){const e=[],o=[],r=[];for(const i of n)if(i instanceof ct&&ht({hideExhibitorBoothNumber:U.hideExhibitorBoothNumber,hideBoothBadges:U.hideBoothBadges,hideLogoInBooth:N.hideLogoInBooth,noLabels:i.noLabels,hasExhibitors:i.exhibitors.length>0,hasLogoInBooth:i.exhibitors.some(c=>c.logoInBooth&&c.logo)})){const{bg:c,text:d,dispose:a}=createBoothBadge(i);e.push(c),o.push(d),r.push(a)}const h=()=>{r.forEach(i=>i()),r.length=0};return e.length?{layer:{name:`${t}${G}badges`,children:[{name:`${t}${G}badgeBgs`,children:e},{name:`${t}${G}badgeTexts`,children:o}]},cleanup:h}:{layer:null,cleanup:h}}