UNPKG

@expofp/floorplan

Version:

Interactive floor plan library for expos and events

2 lines (1 loc) • 8.03 kB
import{Rect as _}from"@expofp/geometry";import{update as U}from"@expofp/renderer";import{FONT_WEIGHT_PRIMARY_BOOTH as V,FONT_WEIGHT_PRIMARY_EXHIBITOR as Z,FONT_WEIGHT_SECONDARY_BOOTH as X,FONT_WEIGHT_SECONDARY_EXHIBITOR as G}from"../../../../constants";import c from"../../../../data";import{createShapeDot as Y,createTextDef as Q,createTextDefLines as $,SHAPE_DOT_CSS_PX as b}from"../../../../engine/defs";import{DEFAULT_FONT_LIGHT_URL as q,DEFAULT_FONT_URL as B,loadCustomFontsUrls as j}from"../../../../engine/fonts";import{getQuarterTurns as k,getRollValue as J,rotateRectByQuarters as K,rotateTextDefByQuarters as tt,updateLinesScale as et}from"../../../../engine/update-def";import{boothStore as it,layersStore as st,uiState as p}from"../../../../store";import{RegularBooth as nt,SpecialBooth as ot}from"../../../../store/BoothStore";import D from"../../../../tools/settings";import{t as F}from"../../../../utils/i18n";import rt from"../../../../utils/is-mobile";import at from"../../../../utils/is-webview";import{planReaction as M}from"../../../../utils/plan-reactions.js";import{isArabicText as ht}from"../../../../utils/rtl";import{BoothDrawerBaseWithoutPainter as lt}from"./BoothDrawerBase";import{getFont as W}from"./canvases";import{getLabelBorderInset as ct}from"./label-inset.js";function I(){return D.EXPO==="tqs2021"?"#000":D.boothLabelColor}const x=rt||at,v=o=>o.replace(" ","").substring(0,4).replace(/[0-9]/g,"3").replace(/[A-Z]/gi,"A"),C=document.createElement("canvas").getContext("2d");export default function mt(o){if(!(!(o instanceof nt)||o.noLabels))return new BoothLabelDrawer(o)}export function getMinZoomFactorForDot(o){return Array.isArray(o)&&o.length>0?Math.max(...o.map(t=>t)):typeof o=="number"?o:-0}export const isDirectionsMode=()=>!!(p.selectedRoute?.from&&p.selectedRoute?.to);export function getFontUrlByWeight(o,t=[],e="normal"){return[...t,{weight:500,url:B,style:"normal"},{weight:300,url:q,style:"normal"}].find(s=>+s.weight===o&&s.style===e)?.url||B}function L(o,t){return Number(getComputedStyle(document.body).getPropertyValue(o))||t}export function getBoothLabelWeights(){return{main:L(V,500),details:L(X,300)}}export function getExhibitorLabelWeights(){return{main:L(Z,500),details:L(G,300)}}export function getBadgeFontWeight(){return getBoothLabelWeights().main}const y="Details";export class BoothLabelDrawer extends lt{constructor(t){super(t),this.minZoomDotVisible=0,this.maxZoomDotVisible=0,this.exh=[],this.shapeLabel=void 0,this.shapeDot=void 0,this.fontSizes=[[],[]],this.lines=[[],[]],this.fontUrls=["",""],this.canvasRect=new _(t.rect.center,t.rect.size,t.rotate,t.elevation),this.paddingScaled=[4,4],this.padding=ct(t.borderWidth||it.borderWidth,t.rect.size),this.topLeftAlignment={horizontal:p.rtl?"right":"left",vertical:"top"},this.centerAlignment={horizontal:"center",vertical:"center"},this.prefixes=x?[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:16,name:y,short:!1}]:[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:12,name:"M",short:!0},{fontSize:14,name:"L",short:!0},{fontSize:18,name:y,short:!1}],!(t instanceof ot)&&(this.exh=c.hideExhibitors?[]:c.onlyFeaturedExhibitors?t.exhibitors.filter(e=>e.featured):t.exhibitors,x&&this.optimizationLevel()>=3&&(this.prefixes=this.prefixes.filter(e=>e.name!=="S")),this.createLines(),this.calculateFontSizeFactors(),this.shapeLabel=Q($(this.lines,this.booth.labelColor||I(),0,this.fontUrls),new _(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),[...this.paddingScaled],{horizontal:"left",vertical:"top"}),this.shapeLabel.onScale=({pixelSize:e})=>this.layOutLabel(e),this.getShapeDot(),M(()=>st.layersLoaded&&this.booth.skipDim===!0,e=>{this.shapeLabel.dim=e?0:void 0,this.shapeDot.dim=e?0:void 0,U(this.shapeLabel,this.shapeDot)}),M(()=>p.mapSettings,({roll:e})=>{J(e??0)&&(this.shapeLabel.onRoll=({roll:i,pixelSize:a})=>{const s=k(i,this.shapeLabel.bounds.rotation);if(s===0)return;const{size:r}=this.canvasRect;return this.shapeLabel=tt(this.shapeLabel,s),!this.shapeLabel.hidden&&!this.exh.length&&r.x!==r.y&&(this.canvasRect=K(this.canvasRect,s),this.calculateFontSizeFactors(),this.layOutLabel(a),this.layOutDot(a)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0}))}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const e=this.lines[1]??[],i=this.fontSizes[1]??[];if(D.EXPO!=="wineparis2026"){const s=this.exh.length?this.topLeftAlignment:e.length?t<i[i.length-1].scaleFactor?this.topLeftAlignment:this.centerAlignment:this.topLeftAlignment;this.shapeLabel.alignment=s}return et(this.shapeLabel.lines,t,this.fontSizes)?(this.shapeLabel.padding[0]=this.paddingScaled[0]*t+this.padding,this.shapeLabel.padding[1]=this.paddingScaled[1]*t+this.padding,[this.shapeLabel]):[]}layOutDot(t){const e=t>=this.minZoomDotVisible&&t<=this.maxZoomDotVisible;if(!e&&this.shapeDot.hidden)return[];const i=this.shapeDot.bounds;return i.scale({x:b*t/i.size.x,y:b*t/i.size.y},i.center,i),this.shapeDot.hidden=!e,[this.shapeDot]}getShapeDot(){this.shapeDot=Y(this.canvasRect,this.booth.labelColor||I()),this.shapeDot.hidden=!0,this.shapeDot.onScale=({pixelSize:t})=>this.layOutDot(t),this.maxZoomDotVisible=Math.min(this.canvasRect.size.x/b,this.canvasRect.size.y/b)}createLines(){const t=this.booth,e=[],i=[],a=x&&this.optimizationLevel()>=3?1:3;if(this.exh.length){const s=t.exhibitors.filter(n=>n.order===0),r=t.exhibitors.filter(n=>n.order);if(s.length>0)e.push(...s.map(n=>n.name));else if(c.onlyFeaturedExhibitors)e.push(...t.exhibitors.filter(n=>n.featured).map(n=>n.name));else if(r.length>0){e.push(...r.map(m=>m.name));const n=t.exhibitors.filter(m=>m.order===void 0);n.length>0&&e.push(F("and {{moreCount}} more",{moreCount:n.length}))}else t.exhibitors.length>a?e.push(`${t.exhibitors.length} ${c.exhibitorTermPlural}`):e.push(...t.exhibitors.map(n=>n.name));i.push(t.title||t.name)}else{const s=!!t.exhibitors.length;e.push(t.title||t.name),t.onHold?i.push(F("On Hold")):t.reserved?i.push(F("Reserved")):s||i.push(...t.exhibitors.map(r=>r.name).sort((r,n)=>r>n?1:-1)),t.size&&i.push(t.size.indexOf("/")>-1?t.size.substring(0,t.size.indexOf("/")).trim():t.size),t.price&&t.price!=="0"&&!p.previewMode&&i.push(t.price)}p.rtl&&e.forEach((s,r)=>{(s.endsWith(".")||s.endsWith("!")||s.endsWith("?"))&&(e[r]=e[r]+"\u200F"),ht(s)&&(e[r]=e[r]+" ")}),this.lines=[e,i]}calculateFontSizeFactors(){const t=this.lines[0];let e;const i=this.canvasRect,a=[],s=[],r=this.prefixes.slice(0,this.exh.length?this.prefixes.length:this.prefixes.length-1),{main:n,details:m}=this.exh.length?getExhibitorLabelWeights():getBoothLabelWeights();for(const{fontSize:l,short:u}of r){const f=l,S=.9*l,d=W(f,n),O=W(S,m),R=c.hideExhibitorBoothNumber||u;let w,A,z,g;if(this.exh.length)e=u?[]:this.lines[1],z=Math.max(...t.map(h=>this.measureText(h,d).width),...e.map(h=>this.measureText(h,O).width)),w=Math.max(...t.map(h=>this.exh.length?this.measureText(v(h),d).width:this.measureText(v(h),d).width+3+3),...e.map(h=>this.measureText(v(h),O).width)),g=f*t.length+S*e.length+(t.length+e.length)+3,A=R?g/t.length:null;else{const h=t[0].replace(/[0-9]/g,"3").replace(/[A-Z]/g,"A"),P=4;z=this.measureText(h,d).width+3+3,g=f+P}const H=i.size.x/(w||z),N=i.size.y/(A||g),E=Math.min(H,N);a.push({scaleFactor:E,value:f,lines:[]}),R||s.push({scaleFactor:E,value:S,lines:[]})}if(!this.exh.length){const l=a[a.length-1],u=this.prefixes.find(f=>f.name===y);u&&(a.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize,lines:[]}),s.push({scaleFactor:l.scaleFactor/1.8,value:u.fontSize*(x?1:.9),lines:[]}))}const T=j();this.fontUrls=[getFontUrlByWeight(n,T),getFontUrlByWeight(m,T)],this.minZoomDotVisible=getMinZoomFactorForDot(a.map(l=>l.scaleFactor)),this.fontSizes=[a,s]}calcArea(t,e){return Math.floor(Math.max(0,t)*Math.max(0,e)/1e3)}optimizationLevel(){return Math.min(c.viewOptimizationLevel?c.viewOptimizationLevel:Math.floor(this.calcArea(this.canvasRect.size.x,this.canvasRect.size.y)/5e3),3)}measureText(t,e){return C.font=e,C.measureText(t)}}