diff --git a/src/app/app.component.ts b/src/app/app.component.ts index fabdee03..75bec503 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -8,7 +8,7 @@ import { CanvasComponent } from './canvas/canvas.component'; import { Image } from './image'; import { UploadImageComponent } from './upload-image/upload-image.component'; import { ConfigService } from './config.service'; - +import { browserComputePathBoundingBox } from './svg-bbox'; @Component({ selector: 'app-root', @@ -280,16 +280,12 @@ export class AppComponent implements AfterViewInit { if (this.cfg.viewPortLocked) { return; } - let xmin = 0; - let ymin = 0; - let xmax = 10; - let ymax = 10; - if (this.targetPoints.length > 0) { - xmin = Math.min(...this.targetPoints.map( it => it.x )); - ymin = Math.min(...this.targetPoints.map( it => it.y )); - xmax = Math.max(...this.targetPoints.map( it => it.x )); - ymax = Math.max(...this.targetPoints.map( it => it.y )); - } + const bbox = browserComputePathBoundingBox(this.rawPath); + let xmin = bbox.x; + let ymin = bbox.y; + let xmax = bbox.width - bbox.x; + let ymax = bbox.height - bbox.y; + const k = this.canvasHeight / this.canvasWidth; let w = xmax - xmin + 2; let h = ymax - ymin + 2; diff --git a/src/app/export/export.component.ts b/src/app/export/export.component.ts index cf82191b..1260455e 100644 --- a/src/app/export/export.component.ts +++ b/src/app/export/export.component.ts @@ -3,6 +3,7 @@ import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialo import { ExportConfigService } from '../config.service'; import { StorageService } from '../storage.service'; import { Svg } from '../svg'; +import { browserComputePathBoundingBox } from '../svg-bbox'; interface DialogData { path: string; @@ -61,10 +62,12 @@ export class ExportDialogComponent { const p = new Svg(this.data.path); const locs = p.targetLocations(); if (locs.length > 0) { - this.x = locs.reduce((acc, pt) => Math.min(acc, pt.x), Infinity); - this.y = locs.reduce((acc, pt) => Math.min(acc, pt.y), Infinity); - this.width = locs.reduce((acc, pt) => Math.max(acc, pt.x), -Infinity) - this.x; - this.height = locs.reduce((acc, pt) => Math.max(acc, pt.y), -Infinity) - this.y; + const bbox = browserComputePathBoundingBox(this.data.path); + + this.x = bbox.x; + this.y = bbox.y; + this.width = bbox.width; + this.height = bbox.height; if (this.cfg.stroke) { this.x -= this.cfg.strokeWidth; this.y -= this.cfg.strokeWidth; diff --git a/src/app/svg-bbox.ts b/src/app/svg-bbox.ts new file mode 100644 index 00000000..05906105 --- /dev/null +++ b/src/app/svg-bbox.ts @@ -0,0 +1,23 @@ + +function round(val: number) : number{ + return Math.round(val * 1e5) / 1e5; +} + +export function browserComputePathBoundingBox(path: string): DOMRect { + const svgNS = 'http://www.w3.org/2000/svg'; + const svgEl = document.createElementNS(svgNS, 'svg'); + svgEl.style.position = 'absolute'; + svgEl.style.width = '0px'; + svgEl.style.height = '0px'; + const pathEl = document.createElementNS(svgNS, 'path'); + pathEl.setAttributeNS(null, 'd', path); + svgEl.appendChild(pathEl); + document.body.appendChild(svgEl); + const result = pathEl.getBBox(); + svgEl.remove(); + result.x = round(result.x); + result.y = round(result.y); + result.width = round(result.width); + result.height = round(result.height); + return result; +}