forked from kimminsung/dwg-dxf-viewer-sample
feat(viewer2d): make the lineweight display scale adjustable from the toolbar
The px-per-mm mapping was a hard-coded guess twice over, and the right value depends on the monitor - AutoCAD has the same knob as the Adjust Display Scale slider. Expose it: a slider plus a number box next to the lineweight toggle, with a readout of what the drawing's own weights come out to (0.35mm -> 7px, 0.50mm -> 10px at the 20 px/mm default). The value persists in localStorage. Retuning applies to the live materials instead of rebuilding the scene. The hairline cut-off is a millimetre value, so changing the scale moves every weight by the same factor without changing which bucket a segment belongs to - each fat batch now remembers its weight in mm, and only material.linewidth is rewritten. That keeps a drag on the slider instant even on the 37 MB road drawing. Measured headless on its 0.35mm gutter line: 2-3px at scale 8, 7px at 20, 14px at 40 - matching the readout in each case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
cf1298749b
commit
a924b1ec34
6 files changed
+6086
-9
No files matched your search
+33
@@ -163,6 +163,7 @@ async function loadAndRender(buf: ArrayBuffer, name: string): Promise<CadParseRe
|
||||
viewer.load(result, { spaceHandle: def?.handleHex ?? null });
|
||||
viewer.resize();
|
||||
syncLwtBtn();
|
||||
syncLwScale();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -240,7 +241,39 @@ const syncLwtBtn = () => {
|
||||
lwtBtn.addEventListener('click', () => {
|
||||
viewer.setLineweightEnabled(!viewer.getLineweightEnabled());
|
||||
syncLwtBtn();
|
||||
syncLwScale();
|
||||
});
|
||||
|
||||
// 선가중치 표시 배율 (px per mm) — AutoCAD "표시 배율" 슬라이더에 해당.
|
||||
// 리로드 없이 즉시 반영되고, 값은 localStorage 에 남는다.
|
||||
const LW_SCALE_KEY = 'hmw:lw-scale';
|
||||
const lwScaleRange = document.getElementById('lwScale') as HTMLInputElement;
|
||||
const lwScaleNum = document.getElementById('lwScaleNum') as HTMLInputElement;
|
||||
const lwScaleOut = document.getElementById('lwScaleOut') as HTMLSpanElement;
|
||||
|
||||
/** 현재 배율에서 도면이 실제로 쓰는 굵기들이 몇 px 로 그려지는지 표기. */
|
||||
function syncLwScale() {
|
||||
const s = viewer.getLineweightScale();
|
||||
lwScaleRange.value = String(s);
|
||||
lwScaleNum.value = String(s);
|
||||
const classes = viewer.getLineweightClasses();
|
||||
lwScaleOut.textContent = classes.length
|
||||
? classes.map((mm) => `${mm.toFixed(2)}mm→${(Math.round(mm * s * 10) / 10)}px`).join(' ')
|
||||
: `0.50mm→${Math.round(0.5 * s * 10) / 10}px`;
|
||||
}
|
||||
|
||||
function applyLwScale(v: number) {
|
||||
if (!Number.isFinite(v) || v <= 0) return;
|
||||
viewer.setLineweightScale(v);
|
||||
localStorage.setItem(LW_SCALE_KEY, String(v));
|
||||
syncLwScale();
|
||||
}
|
||||
lwScaleRange.addEventListener('input', () => applyLwScale(parseFloat(lwScaleRange.value)));
|
||||
lwScaleNum.addEventListener('input', () => applyLwScale(parseFloat(lwScaleNum.value)));
|
||||
|
||||
const savedLwScale = parseFloat(localStorage.getItem(LW_SCALE_KEY) || '');
|
||||
if (Number.isFinite(savedLwScale) && savedLwScale > 0) viewer.setLineweightScale(savedLwScale);
|
||||
syncLwScale();
|
||||
document.getElementById('layersBtn')!.addEventListener('click', () => {
|
||||
layersPanel.style.display = layersPanel.style.display === 'flex' ? 'none' : 'flex';
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user