Add drawing workspace feature
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
ad73ddec2b
commit
a5cc458252
78 files changed
+35740
-6
No files matched your search
+43
@@ -0,0 +1,43 @@
|
||||
import { referenceLayer, REFERENCE_ACI, aciPaper } from './cad-style';
|
||||
import { LAYERS, type DrawingDocument, type Entity, type Layer, type ViewId } from './types';
|
||||
import { sheetFrame, viewPaperEntities } from './sheet';
|
||||
import { entityBox } from './occupancy';
|
||||
export { paperPoint } from './presentation';
|
||||
export const escapeXml=(value:string):string=>value.replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!));
|
||||
|
||||
function renderEntity(e:Entity,height:number):string {
|
||||
const coord=(p:readonly number[])=>`${p[0].toFixed(4)},${(height-p[1]).toFixed(4)}`;
|
||||
if(e.kind==='text'){
|
||||
const [x,y]=[e.point[0],height-e.point[1]];
|
||||
return `<text x="${x}" y="${y}" stroke="none" fill="${aciPaper(e.cad?.color??REFERENCE_ACI[referenceLayer(e)]??7)}" font-size="${e.height}" text-anchor="${e.align==='center'?'middle':e.align==='right'?'end':'start'}"${e.rotation?` transform="rotate(${-e.rotation} ${x} ${y})"`:''}>${escapeXml(e.text)}</text>`;
|
||||
}
|
||||
if(e.kind==='circle')return `<circle cx="${e.center[0]}" cy="${height-e.center[1]}" r="${e.radius}"/>`;
|
||||
if(e.kind==='line')return `<polyline points="${coord(e.a)} ${coord(e.b)}"/>`;
|
||||
if(e.kind==='polyline')return `<${e.closed?'polygon':'polyline'} points="${e.points.map(coord).join(' ')}"/>`;
|
||||
if(e.kind==='hatch'){
|
||||
const fill=e.color&&/^#[0-9a-f]{6}$/i.test(e.color)?e.color:'#cbd1d6';
|
||||
const d=[e.points,...e.holes??[]].map(loop=>`M${loop.map(coord).join('L')}Z`).join('');
|
||||
if(e.pattern==='SOLID')return `<path d="${d}" fill-rule="evenodd" fill="${fill}" stroke="none"/>`;
|
||||
const id=`hz-${Math.abs(Math.round((e.points[0]?.[0]??0)*10000))}-${Math.abs(Math.round((e.points[0]?.[1]??0)*10000))}-${e.source.member}-${e.source.index}`.replace(/[^a-z0-9-]/gi,'');
|
||||
const spacing=Math.max(.1,e.spacing);
|
||||
return `<defs><pattern id="${id}" width="${spacing}" height="${spacing}" patternUnits="userSpaceOnUse" patternTransform="rotate(${-e.angle})"><path d="M0 0H${spacing}" stroke="${fill}" stroke-width=".13"/></pattern></defs><path d="${d}" fill-rule="evenodd" fill="url(#${id})" stroke="none"/>`;
|
||||
}
|
||||
throw new Error('Expand CAD dimensions before paper rendering');
|
||||
}
|
||||
export function drawingSvg(doc:DrawingDocument,visible:ReadonlySet<Layer>,interactive=false,selected?:ViewId):string {
|
||||
const {width,height}=doc.paper;
|
||||
const render=(e:Entity,view:string,index:number)=>{
|
||||
if(!visible.has(e.layer))return'';
|
||||
const style={...LAYERS[e.layer],color:aciPaper(e.cad?.color??REFERENCE_ACI[referenceLayer(e)]??7)};
|
||||
const issue=interactive&&doc.quality?.issues.some(i=>i.view===view&&i.first===index),b=issue?entityBox(e):undefined;
|
||||
const marker=b?`<rect class="ga-issue-box" x="${b.minX}" y="${height-b.maxY}" width="${b.maxX-b.minX}" height="${b.maxY-b.minY}" fill="#ffeded88" stroke="#d52d2d" stroke-width=".2"/>`:'';
|
||||
return `<g fill="none" stroke="${style.color}" stroke-width="${style.weight}"${style.dash?` stroke-dasharray="${style.dash}"`:''}${interactive&&index>=0?` data-entity="${view}:${index}"`:''}><title>${escapeXml(`${e.source.pier} / ${e.source.member} ${e.source.index+1} / ${e.layer}`)}</title>${marker}${renderEntity(e,height)}</g>`;
|
||||
};
|
||||
let body=`<rect width="${width}" height="${height}" fill="white"/>`;
|
||||
if(!selected)body+=sheetFrame(doc).map(e=>render(e,'sheet',-1)).join('');
|
||||
for(const view of doc.views){
|
||||
if(selected?view.id!==selected:['section','heights'].includes(view.id))continue;
|
||||
body+=`<g data-view="${view.id}" aria-label="${escapeXml(view.title)}">${viewPaperEntities(doc,view).map(({entity,index})=>render(entity,view.id,index)).join('')}</g>`;
|
||||
}
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}mm" height="${height}mm" viewBox="0 0 ${width} ${height}" role="img" aria-label="${escapeXml(doc.pier)} 교각 일반도" style="font-family:'Gulim','굴림','Malgun Gothic','Noto Sans KR',sans-serif">${body}</svg>`;
|
||||
}
|
||||
Reference in new issue
Block a user