mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-03-23 23:57:23 +01:00
refactor: improve code formatting and organization in labels and renderers
This commit is contained in:
parent
6d99d8260d
commit
6fa3f786dc
4 changed files with 48 additions and 56 deletions
|
|
@ -79,15 +79,17 @@ class LabelsModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
getBurgLabel(burgId: number): BurgLabelData | undefined {
|
getBurgLabel(burgId: number): BurgLabelData | undefined {
|
||||||
return pack.labels.find(
|
return pack.labels.find((l) => l.type === "burg" && l.burgId === burgId) as
|
||||||
(l) => l.type === "burg" && l.burgId === burgId,
|
| BurgLabelData
|
||||||
) as BurgLabelData | undefined;
|
| undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
addStateLabel(
|
addStateLabel(data: Omit<StateLabelData, "i" | "type">): StateLabelData {
|
||||||
data: Omit<StateLabelData, "i" | "type">,
|
const label: StateLabelData = {
|
||||||
): StateLabelData {
|
i: this.getNextId(),
|
||||||
const label: StateLabelData = { i: this.getNextId(), type: "state", ...data };
|
type: "state",
|
||||||
|
...data,
|
||||||
|
};
|
||||||
pack.labels.push(label);
|
pack.labels.push(label);
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
@ -98,10 +100,12 @@ class LabelsModule {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
addCustomLabel(
|
addCustomLabel(data: Omit<CustomLabelData, "i" | "type">): CustomLabelData {
|
||||||
data: Omit<CustomLabelData, "i" | "type">,
|
const label: CustomLabelData = {
|
||||||
): CustomLabelData {
|
i: this.getNextId(),
|
||||||
const label: CustomLabelData = { i: this.getNextId(), type: "custom", ...data };
|
type: "custom",
|
||||||
|
...data,
|
||||||
|
};
|
||||||
pack.labels.push(label);
|
pack.labels.push(label);
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
@ -123,8 +127,7 @@ class LabelsModule {
|
||||||
|
|
||||||
removeByGroup(group: string): void {
|
removeByGroup(group: string): void {
|
||||||
pack.labels = pack.labels.filter(
|
pack.labels = pack.labels.filter(
|
||||||
(l) =>
|
(l) => !((l.type === "burg" || l.type === "custom") && l.group === group),
|
||||||
!((l.type === "burg" || l.type === "custom") && l.group === group),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +148,7 @@ class LabelsModule {
|
||||||
clear(): void {
|
clear(): void {
|
||||||
pack.labels = [];
|
pack.labels = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate state labels data entries for each state.
|
* Generate state labels data entries for each state.
|
||||||
* Only stores essential label data; raycast path calculation happens during rendering.
|
* Only stores essential label data; raycast path calculation happens during rendering.
|
||||||
|
|
@ -153,52 +156,52 @@ class LabelsModule {
|
||||||
*/
|
*/
|
||||||
generateStateLabels(list?: number[]): void {
|
generateStateLabels(list?: number[]): void {
|
||||||
if (TIME) console.time("generateStateLabels");
|
if (TIME) console.time("generateStateLabels");
|
||||||
|
|
||||||
const { states } = pack;
|
const { states } = pack;
|
||||||
|
|
||||||
// Remove existing state labels that need regeneration
|
// Remove existing state labels that need regeneration
|
||||||
if (list) {
|
if (list) {
|
||||||
list.forEach((stateId) => this.removeStateLabel(stateId));
|
list.forEach((stateId) => this.removeStateLabel(stateId));
|
||||||
} else {
|
} else {
|
||||||
this.removeByType("state");
|
this.removeByType("state");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new label entries
|
// Generate new label entries
|
||||||
for (const state of states) {
|
for (const state of states) {
|
||||||
if (!state.i || state.removed || state.lock) continue;
|
if (!state.i || state.removed || state.lock) continue;
|
||||||
if (list && !list.includes(state.i)) continue;
|
if (list && !list.includes(state.i)) continue;
|
||||||
|
|
||||||
this.addStateLabel({
|
this.addStateLabel({
|
||||||
stateId: state.i,
|
stateId: state.i,
|
||||||
text: state.name!,
|
text: state.name!,
|
||||||
fontSize: 100,
|
fontSize: 100,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TIME) console.timeEnd("generateStateLabels");
|
if (TIME) console.timeEnd("generateStateLabels");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate burg labels data from burgs.
|
* Generate burg labels data from burgs.
|
||||||
* Populates pack.labels with BurgLabelData for each burg.
|
* Populates pack.labels with BurgLabelData for each burg.
|
||||||
*/
|
*/
|
||||||
generateBurgLabels(): void {
|
generateBurgLabels(): void {
|
||||||
if (TIME) console.time("generateBurgLabels");
|
if (TIME) console.time("generateBurgLabels");
|
||||||
|
|
||||||
// Remove existing burg labels
|
// Remove existing burg labels
|
||||||
this.removeByType("burg");
|
this.removeByType("burg");
|
||||||
|
|
||||||
// Generate new labels for all active burgs
|
// Generate new labels for all active burgs
|
||||||
for (const burg of pack.burgs) {
|
for (const burg of pack.burgs) {
|
||||||
if (!burg.i || burg.removed) continue;
|
if (!burg.i || burg.removed) continue;
|
||||||
|
|
||||||
const group = burg.group || "unmarked";
|
const group = burg.group || "unmarked";
|
||||||
|
|
||||||
// Get label group offset attributes if they exist (will be set during rendering)
|
// Get label group offset attributes if they exist (will be set during rendering)
|
||||||
// For now, use defaults - these will be updated during rendering phase
|
// For now, use defaults - these will be updated during rendering phase
|
||||||
const dx = 0;
|
const dx = 0;
|
||||||
const dy = 0;
|
const dy = 0;
|
||||||
|
|
||||||
this.addBurgLabel({
|
this.addBurgLabel({
|
||||||
burgId: burg.i,
|
burgId: burg.i,
|
||||||
group,
|
group,
|
||||||
|
|
@ -209,11 +212,9 @@ class LabelsModule {
|
||||||
dy,
|
dy,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TIME) console.timeEnd("generateBurgLabels");
|
if (TIME) console.timeEnd("generateBurgLabels");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.Labels = new LabelsModule();
|
window.Labels = new LabelsModule();
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,7 @@
|
||||||
import { curveNatural, line, max, select } from "d3";
|
import { curveNatural, line, max, select } from "d3";
|
||||||
import {
|
|
||||||
findClosestCell,
|
|
||||||
minmax,
|
|
||||||
rn,
|
|
||||||
round,
|
|
||||||
splitInTwo,
|
|
||||||
} from "../utils";
|
|
||||||
import type { StateLabelData } from "../modules/labels";
|
import type { StateLabelData } from "../modules/labels";
|
||||||
import {
|
import { findClosestCell, minmax, rn, round, splitInTwo } from "../utils";
|
||||||
raycast,
|
import { ANGLES, findBestRayPair, raycast } from "./label-raycast";
|
||||||
findBestRayPair,
|
|
||||||
ANGLES,
|
|
||||||
} from "./label-raycast";
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var drawStateLabels: (list?: number[]) => void;
|
var drawStateLabels: (list?: number[]) => void;
|
||||||
|
|
@ -57,8 +47,11 @@ const stateLabelsRenderer = (list?: number[]): void => {
|
||||||
// Get labels to render
|
// Get labels to render
|
||||||
const labelsToRender = list
|
const labelsToRender = list
|
||||||
? Labels.getAll()
|
? Labels.getAll()
|
||||||
.filter((l) => l.type === "state" && list.includes((l as StateLabelData).stateId))
|
.filter(
|
||||||
.map((l) => l as StateLabelData)
|
(l) =>
|
||||||
|
l.type === "state" && list.includes((l as StateLabelData).stateId),
|
||||||
|
)
|
||||||
|
.map((l) => l as StateLabelData)
|
||||||
: Labels.getByType("state").map((l) => l as StateLabelData);
|
: Labels.getByType("state").map((l) => l as StateLabelData);
|
||||||
|
|
||||||
const letterLength = checkExampleLetterLength();
|
const letterLength = checkExampleLetterLength();
|
||||||
|
|
@ -67,7 +60,10 @@ const stateLabelsRenderer = (list?: number[]): void => {
|
||||||
// restore labels visibility
|
// restore labels visibility
|
||||||
labels.style("display", layerDisplay);
|
labels.style("display", layerDisplay);
|
||||||
|
|
||||||
function drawLabelPath(letterLength: number, labelDataList: StateLabelData[]): void {
|
function drawLabelPath(
|
||||||
|
letterLength: number,
|
||||||
|
labelDataList: StateLabelData[],
|
||||||
|
): void {
|
||||||
const mode = options.stateLabelsMode || "auto";
|
const mode = options.stateLabelsMode || "auto";
|
||||||
const lineGen = line<[number, number]>().curve(curveNatural);
|
const lineGen = line<[number, number]>().curve(curveNatural);
|
||||||
|
|
||||||
|
|
@ -78,8 +74,7 @@ const stateLabelsRenderer = (list?: number[]): void => {
|
||||||
|
|
||||||
for (const labelData of labelDataList) {
|
for (const labelData of labelDataList) {
|
||||||
const state = states[labelData.stateId];
|
const state = states[labelData.stateId];
|
||||||
if (!state.i || state.removed)
|
if (!state.i || state.removed) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// Calculate pathPoints using raycast algorithm (recalculated on each draw)
|
// Calculate pathPoints using raycast algorithm (recalculated on each draw)
|
||||||
const offset = getOffsetWidth(state.cells!);
|
const offset = getOffsetWidth(state.cells!);
|
||||||
|
|
@ -161,16 +156,16 @@ const stateLabelsRenderer = (list?: number[]): void => {
|
||||||
textElement.insertAdjacentHTML("afterbegin", spans.join(""));
|
textElement.insertAdjacentHTML("afterbegin", spans.join(""));
|
||||||
|
|
||||||
const { width, height } = textElement.getBBox();
|
const { width, height } = textElement.getBBox();
|
||||||
textElement.setAttribute("href", `#textPath_stateLabel${labelData.stateId}`);
|
textElement.setAttribute(
|
||||||
|
"href",
|
||||||
|
`#textPath_stateLabel${labelData.stateId}`,
|
||||||
|
);
|
||||||
|
|
||||||
const stateIds = pack.cells.state;
|
const stateIds = pack.cells.state;
|
||||||
if (mode === "full" || lines.length === 1) continue;
|
if (mode === "full" || lines.length === 1) continue;
|
||||||
|
|
||||||
// check if label fits state boundaries. If no, replace it with short name
|
// check if label fits state boundaries. If no, replace it with short name
|
||||||
const [[x1, y1], [x2, y2]] = [
|
const [[x1, y1], [x2, y2]] = [pathPoints.at(0)!, pathPoints.at(-1)!];
|
||||||
pathPoints.at(0)!,
|
|
||||||
pathPoints.at(-1)!,
|
|
||||||
];
|
|
||||||
const angleRad = Math.atan2(y2 - y1, x2 - x1);
|
const angleRad = Math.atan2(y2 - y1, x2 - x1);
|
||||||
|
|
||||||
const isInsideState = checkIfInsideState(
|
const isInsideState = checkIfInsideState(
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,7 @@ export function raycast({
|
||||||
const stateIds = cells.state;
|
const stateIds = cells.state;
|
||||||
let ray = { length: 0, x: x0, y: y0 };
|
let ray = { length: 0, x: x0, y: y0 };
|
||||||
|
|
||||||
for (
|
for (let length = LENGTH_START; length < LENGTH_MAX; length += LENGTH_STEP) {
|
||||||
let length = LENGTH_START;
|
|
||||||
length < LENGTH_MAX;
|
|
||||||
length += LENGTH_STEP
|
|
||||||
) {
|
|
||||||
const [x, y] = [x0 + length * dx, y0 + length * dy];
|
const [x, y] = [x0 + length * dx, y0 + length * dy];
|
||||||
// offset points are perpendicular to the ray
|
// offset points are perpendicular to the ray
|
||||||
const offset1: [number, number] = [x + -dy * offset, y + dx * offset];
|
const offset1: [number, number] = [x + -dy * offset, y + dx * offset];
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import type { Burg } from "../modules/burgs-generator";
|
import type { Burg } from "../modules/burgs-generator";
|
||||||
import type { Culture } from "../modules/cultures-generator";
|
import type { Culture } from "../modules/cultures-generator";
|
||||||
import type { PackedGraphFeature } from "../modules/features";
|
import type { PackedGraphFeature } from "../modules/features";
|
||||||
|
import type { LabelData } from "../modules/labels";
|
||||||
import type { Province } from "../modules/provinces-generator";
|
import type { Province } from "../modules/provinces-generator";
|
||||||
import type { River } from "../modules/river-generator";
|
import type { River } from "../modules/river-generator";
|
||||||
import type { Route } from "../modules/routes-generator";
|
import type { Route } from "../modules/routes-generator";
|
||||||
import type { State } from "../modules/states-generator";
|
import type { State } from "../modules/states-generator";
|
||||||
import type { LabelData } from "../modules/labels";
|
|
||||||
import type { Zone } from "../modules/zones-generator";
|
import type { Zone } from "../modules/zones-generator";
|
||||||
|
|
||||||
type TypedArray =
|
type TypedArray =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue