Files
martinfencl.eu/locenice/js/project-panel.js
T
2026-10-22 01:22:01 +02:00

21 lines
3.7 KiB
JavaScript

/** Source references and non-geodetic survey overlay. Does not alter house dimensions. */
export function installProjectPanel({resources,backend,getMode,focusSite,invalidate}){
const $=s=>document.querySelector(s),dialog=$('#projectDialog'),overlay=$('#surveyOverlay');let survey=false;
const esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
$('#projectToggle').onclick=()=>dialog.showModal();$('#projectClose').onclick=()=>dialog.close();
dialog.addEventListener('click',e=>{if(e.target===dialog){const r=dialog.getBoundingClientRect();if(e.clientX<r.left||e.clientX>r.right||e.clientY<r.top||e.clientY>r.bottom)dialog.close();}});
const photos=[['kitchen1','Kuchy\u0148 / zelen\u00e1 a dub'],['kitchen2','Kuchy\u0148 / vnit\u0159n\u00ed strana'],['view1','Ob\u00fdvac\u00ed pokoj / tr\u00e1my'],['view2','Ob\u00fdvac\u00ed pokoj / vybaven\u00ed']];
$('#projectPhotos').innerHTML=photos.map(([key,title])=>`<button type="button" data-photo="${key}"><img loading="lazy" src="${esc(resources.references[key].src)}" alt="${esc(title)}"><span>${esc(title)}</span></button>`).join('');
$('#projectPhotos').onclick=e=>{const key=e.target.closest('[data-photo]')?.dataset.photo;if(!key)return;const r=resources.references[key];dialog.close();$('#interiorReferenceTitle').textContent=r.title;$('#interiorReferenceImage').src=r.src;$('#interiorReferenceImage').alt=r.title;$('#interiorReferenceCaption').textContent=r.caption;$('#interiorReferenceDialog').showModal();};
const site=resources.site;
$('#surveyStats').innerHTML=`<div><strong>${site.cadastralAreaInProject.toLocaleString('cs-CZ')} m\u00b2</strong><span>V\u00fdm\u011bra dle geometrick\u00e9ho pl\u00e1nu</span></div><div><strong>${site.digitizedOutlineArea.toLocaleString('cs-CZ')} m\u00b2</strong><span>Obrys dosavadn\u00edho 3D modelu</span></div><div><strong>${site.referenceElevation.toLocaleString('cs-CZ',{minimumFractionDigits:3})} m</strong><span>V\u00fd\u0161kov\u00e1 nula / Bpv</span></div><div><strong>${site.surveyPoints.length} bod\u016f</strong><span>V\u00fd\u0161kopis / grafick\u00fd ode\u010det polohy</span></div>`;
$('#surveyShow').onclick=()=>{survey=!survey;$('#surveyShow').textContent=survey?'Skr\u00fdt body v\u00fd\u0161kopisu':'Zobrazit body v modelu';dialog.close();if(survey)focusSite();invalidate();};
$('#backendNote').textContent=backend.backend==='three'?'Aktivn\u00ed renderer: Three.js r180. Knihovna se na\u010d\u00edt\u00e1 z CDN; model i podklady z va\u0161eho hostingu.':'Aktivn\u00ed renderer: lok\u00e1ln\u00ed WebGL. Three.js se nepoda\u0159ilo na\u010d\u00edst nebo byl zvolen z\u00e1lo\u017en\u00ed re\u017eim. Model a konfigur\u00e1tor funguj\u00ed bez CDN.';
return {drawSurvey(project,clip,width,height){
if(!survey||getMode().enabled){overlay.style.display='none';return;}
overlay.style.display='block';overlay.setAttribute('viewBox',`0 0 ${width} ${height}`);overlay.style.width=width+'px';overlay.style.height=height+'px';
const occupied=[];
overlay.innerHTML=site.surveyPoints.map(p=>{const xyz=[p.xz[0],p.altitude-site.referenceElevation+.10,p.xz[1]],q=clip(xyz);if(q[3]<=0)return '';const [x,y]=project(xyz);if(x<0||y<0||x>width||y>height)return '';const value=p.altitude.toFixed(2).replace('.',',');let label='';for(const [dx,dy]of [[6,-6],[6,17],[-78,-6]]){const box={x:x+dx,y:y+dy-11,w:77,h:15};if(box.x<4||box.y<4||box.x+box.w>width-4||box.y+box.h>height-4)continue;if(occupied.some(b=>box.x<b.x+b.w&&box.x+box.w>b.x&&box.y<b.y+b.h&&box.y+box.h>b.y))continue;occupied.push(box);label=`<text x="${dx}" y="${dy}">${p.id} / ${value}</text>`;break;}return `<g transform="translate(${x.toFixed(1)},${y.toFixed(1)})"><title>${p.id} / ${value} m Bpv</title><circle r="3"/>${label}</g>`;}).join('');
}};
}