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) {
|
if (this.dragStartPart !== null && this.dragCursor !== null) {
|
||||||
this.dragStartPart.rasterCenterX = Math.floor(this.dragCursor.x / RASTER);
|
this.dragStartPart.rasterCenterX = Math.floor(this.dragCursor.x / RASTER);
|
||||||
this.dragStartPart.rasterCenterY = Math.floor(this.dragCursor.y / RASTER);
|
this.dragStartPart.rasterCenterY = Math.floor(this.dragCursor.y / RASTER);
|
||||||
|
this.dragStartPart.updateJunctionPositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import {Wire} from "../wire/Wire";
|
import {Wire} from "../wire/Wire";
|
||||||
import {Part} from '../parts/Part';
|
import {Part} from '../parts/Part';
|
||||||
|
import {Rect} from '../../Rect';
|
||||||
|
import {selectTowardsRoot} from '../../selectTowardsRoot';
|
||||||
|
|
||||||
export const JUNCTION_RADIUS_PERCENT = 15;
|
export const JUNCTION_RADIUS_PERCENT = 15;
|
||||||
|
|
||||||
@ -13,16 +15,14 @@ export class Junction {
|
|||||||
|
|
||||||
readonly wires: Wire[] = [];
|
readonly wires: Wire[] = [];
|
||||||
|
|
||||||
|
private _rect: Rect | null = null;
|
||||||
|
|
||||||
voltage: number | null = null;
|
voltage: number | null = null;
|
||||||
|
|
||||||
minCircuitVoltage: number | null = null;
|
minCircuitVoltage: number | null = null;
|
||||||
|
|
||||||
maxCircuitVoltage: number | null = null;
|
maxCircuitVoltage: number | null = null;
|
||||||
|
|
||||||
get fullName(): string {
|
|
||||||
return `'${this.part.name}' '${this.name}'`;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly part: Part,
|
public readonly part: Part,
|
||||||
percentX: number,
|
percentX: number,
|
||||||
@ -32,24 +32,16 @@ export class Junction {
|
|||||||
this.percentY = percentY - JUNCTION_RADIUS_PERCENT;
|
this.percentY = percentY - JUNCTION_RADIUS_PERCENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString(): string {
|
get fullName(): string {
|
||||||
return `${this.name}`;
|
return `'${this.part.name}' '${this.name}'`;
|
||||||
}
|
|
||||||
|
|
||||||
private mapRect(next: (b: DOMRect) => number): number {
|
|
||||||
const rect = document.getElementById(this.uuid)?.getBoundingClientRect();
|
|
||||||
if (!rect) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return next(rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get pixelX(): number {
|
get pixelX(): number {
|
||||||
return this.mapRect(b => b.x + b.width / 2);
|
return this.rect.x + this.rect.w / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
get pixelY(): number {
|
get pixelY(): number {
|
||||||
return this.mapRect(b => b.y + b.height / 2);
|
return this.rect.y + this.rect.h / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
get percentW(): number {
|
get percentW(): number {
|
||||||
@ -60,6 +52,21 @@ export class Junction {
|
|||||||
return (JUNCTION_RADIUS_PERCENT * 2);
|
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) {
|
sumAllBut(plus: Junction) {
|
||||||
return this.wires
|
return this.wires
|
||||||
.filter(wire => wire.traverse(this) !== plus)
|
.filter(wire => wire.traverse(this) !== plus)
|
||||||
@ -67,4 +74,25 @@ export class Junction {
|
|||||||
.reduce((a, b) => a + b, 0);
|
.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();
|
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(
|
protected constructor(
|
||||||
readonly type: PartType,
|
readonly type: PartType,
|
||||||
readonly name: string,
|
readonly name: string,
|
||||||
rasterX: number,
|
rasterX: number,
|
||||||
rasterY: number,
|
rasterY: number,
|
||||||
rasterW: number = 3,
|
rasterW: number = 1,
|
||||||
rasterH: number = 3,
|
rasterH: number = 1,
|
||||||
) {
|
) {
|
||||||
this.x = rasterX * RASTER;
|
this._x = rasterX * 3 * RASTER;
|
||||||
this.y = rasterY * RASTER;
|
this._y = rasterY * 3 * RASTER;
|
||||||
this.w = rasterW * RASTER;
|
this._w = rasterW * 3 * RASTER;
|
||||||
this.h = rasterH * RASTER;
|
this._h = rasterH * 3 * RASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract get junctions(): Junction[];
|
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 {
|
toString(): string {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
set rasterCenterX(rx: number) {
|
updateJunctionPositions() {
|
||||||
this.x = rx * RASTER - this.w / 2;
|
this.junctions.forEach(junction => junction.updatePosition());
|
||||||
}
|
|
||||||
|
|
||||||
set rasterCenterY(ry: number) {
|
|
||||||
this.y = ry * RASTER - this.h / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
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