diff --git a/src/main/angular/src/app/Rect.ts b/src/main/angular/src/app/Rect.ts new file mode 100644 index 0000000..8cc0210 --- /dev/null +++ b/src/main/angular/src/app/Rect.ts @@ -0,0 +1,14 @@ +export class Rect { + + static readonly ZERO: Rect = new Rect(0, 0, 0, 0); + + constructor( + readonly x: number, + readonly y: number, + readonly w: number, + readonly h: number, + ) { + // + } + +} diff --git a/src/main/angular/src/app/editor/circuit/Parts.ts b/src/main/angular/src/app/editor/circuit/Parts.ts index 11fc626..7975ace 100644 --- a/src/main/angular/src/app/editor/circuit/Parts.ts +++ b/src/main/angular/src/app/editor/circuit/Parts.ts @@ -26,6 +26,7 @@ export class Parts { if (this.dragStartPart !== null && this.dragCursor !== null) { this.dragStartPart.rasterCenterX = Math.floor(this.dragCursor.x / RASTER); this.dragStartPart.rasterCenterY = Math.floor(this.dragCursor.y / RASTER); + this.dragStartPart.updateJunctionPositions(); } } diff --git a/src/main/angular/src/app/editor/junction/Junction.ts b/src/main/angular/src/app/editor/junction/Junction.ts index b62b53a..8989bb8 100644 --- a/src/main/angular/src/app/editor/junction/Junction.ts +++ b/src/main/angular/src/app/editor/junction/Junction.ts @@ -1,5 +1,7 @@ import {Wire} from "../wire/Wire"; import {Part} from '../parts/Part'; +import {Rect} from '../../Rect'; +import {selectTowardsRoot} from '../../selectTowardsRoot'; export const JUNCTION_RADIUS_PERCENT = 15; @@ -13,16 +15,14 @@ export class Junction { readonly wires: Wire[] = []; + private _rect: Rect | null = null; + voltage: number | null = null; minCircuitVoltage: number | null = null; maxCircuitVoltage: number | null = null; - get fullName(): string { - return `'${this.part.name}' '${this.name}'`; - } - constructor( public readonly part: Part, percentX: number, @@ -32,24 +32,16 @@ export class Junction { this.percentY = percentY - JUNCTION_RADIUS_PERCENT; } - toString(): string { - return `${this.name}`; - } - - private mapRect(next: (b: DOMRect) => number): number { - const rect = document.getElementById(this.uuid)?.getBoundingClientRect(); - if (!rect) { - return 0; - } - return next(rect); + get fullName(): string { + return `'${this.part.name}' '${this.name}'`; } get pixelX(): number { - return this.mapRect(b => b.x + b.width / 2); + return this.rect.x + this.rect.w / 2; } get pixelY(): number { - return this.mapRect(b => b.y + b.height / 2); + return this.rect.y + this.rect.h / 2; } get percentW(): number { @@ -60,6 +52,21 @@ export class Junction { return (JUNCTION_RADIUS_PERCENT * 2); } + get rect(): Rect { + if (this._rect === null) { + this._rect = this.findRect(); + } + return this._rect; + } + + toString(): string { + return `${this.name}`; + } + + updatePosition() { + this._rect = this.findRect(); + } + sumAllBut(plus: Junction) { return this.wires .filter(wire => wire.traverse(this) !== plus) @@ -67,4 +74,25 @@ export class Junction { .reduce((a, b) => a + b, 0); } + private findRect(): Rect { + const child = document.getElementById(this.uuid); + if (!child) { + throw Error(`No HTMLElement found for Junction: uuid=${this.uuid}, name=${this.name}`); + } + + const parent = selectTowardsRoot(child, "svg.circuit"); + if (!parent) { + throw Error(`No parent matching "svg.circuit" found for: ${child}`); + } + + const childRect = child.getBoundingClientRect(); + const parentRect = parent.getBoundingClientRect(); + return { + x: childRect.left - parentRect.left, + y: childRect.top - parentRect.top, + w: childRect.width, + h: childRect.height, + }; + } + } diff --git a/src/main/angular/src/app/editor/parts/Part.ts b/src/main/angular/src/app/editor/parts/Part.ts index 4835ac1..6e5780f 100644 --- a/src/main/angular/src/app/editor/parts/Part.ts +++ b/src/main/angular/src/app/editor/parts/Part.ts @@ -7,40 +7,60 @@ export abstract class Part { readonly uuid: string = self.crypto.randomUUID(); - x: number; + private _x: number; - y: number; + private _y: number; - w: number; + private readonly _w: number; - h: number; + private readonly _h: number; protected constructor( readonly type: PartType, readonly name: string, rasterX: number, rasterY: number, - rasterW: number = 3, - rasterH: number = 3, + rasterW: number = 1, + rasterH: number = 1, ) { - this.x = rasterX * RASTER; - this.y = rasterY * RASTER; - this.w = rasterW * RASTER; - this.h = rasterH * RASTER; + this._x = rasterX * 3 * RASTER; + this._y = rasterY * 3 * RASTER; + this._w = rasterW * 3 * RASTER; + this._h = rasterH * 3 * RASTER; } abstract get junctions(): Junction[]; + get x(): number { + return this._x; + } + + get y(): number { + return this._y; + } + + get w(): number { + return this._w; + } + + get h(): number { + return this._h; + } + + set rasterCenterX(rx: number) { + this._x = rx * RASTER - this._w / 2; + } + + set rasterCenterY(ry: number) { + this._y = ry * RASTER - this._h / 2; + } + toString(): string { return this.name; } - set rasterCenterX(rx: number) { - this.x = rx * RASTER - this.w / 2; - } - - set rasterCenterY(ry: number) { - this.y = ry * RASTER - this.h / 2; + updateJunctionPositions() { + this.junctions.forEach(junction => junction.updatePosition()); } } diff --git a/src/main/angular/src/app/selectTowardsRoot.ts b/src/main/angular/src/app/selectTowardsRoot.ts new file mode 100644 index 0000000..ab02834 --- /dev/null +++ b/src/main/angular/src/app/selectTowardsRoot.ts @@ -0,0 +1,6 @@ +export function selectTowardsRoot(element: HTMLElement | null, parentSelector: string): HTMLElement | null { + while (!!element && !element.matches(parentSelector)) { + element = element.parentElement || null; + } + return element; +}