FIX: Junction positioning via parent's client-rects
This commit is contained in:
parent
d2311a5647
commit
7fe2e3361a
14
src/main/angular/src/app/Rect.ts
Normal file
14
src/main/angular/src/app/Rect.ts
Normal file
@ -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,
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
6
src/main/angular/src/app/selectTowardsRoot.ts
Normal file
6
src/main/angular/src/app/selectTowardsRoot.ts
Normal file
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user