mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-03-22 23:27:23 +01:00
feat: migrate label data structure from SVG to data model and update version to 1.113.0
This commit is contained in:
parent
ca6d01f4be
commit
3ab40ada5f
4 changed files with 158 additions and 3 deletions
|
|
@ -1106,4 +1106,156 @@ export function resolveVersionConflicts(mapVersion) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
if (isOlderThan("1.113.0")) {
|
||||
// v1.113.0 moved labels data from SVG to data model
|
||||
// Migrate old SVG labels to pack.labels structure
|
||||
if (!pack.labels || !pack.labels.length) {
|
||||
pack.labels = [];
|
||||
let labelId = 0;
|
||||
|
||||
// Migrate state labels
|
||||
const stateLabelsGroup = document.querySelector("#labels > #states");
|
||||
if (stateLabelsGroup) {
|
||||
stateLabelsGroup.querySelectorAll("text").forEach(textElement => {
|
||||
const id = textElement.getAttribute("id");
|
||||
if (!id || !id.startsWith("stateLabel")) return;
|
||||
|
||||
const stateIdMatch = id.match(/stateLabel(\d+)/);
|
||||
if (!stateIdMatch) return;
|
||||
|
||||
const stateId = +stateIdMatch[1];
|
||||
const state = pack.states[stateId];
|
||||
if (!state || state.removed) return;
|
||||
|
||||
const textPath = textElement.querySelector("textPath");
|
||||
if (!textPath) return;
|
||||
|
||||
const text = textPath.textContent.trim();
|
||||
const fontSizeAttr = textPath.getAttribute("font-size");
|
||||
const fontSize = fontSizeAttr ? parseFloat(fontSizeAttr) : 100;
|
||||
|
||||
pack.labels.push({
|
||||
i: labelId++,
|
||||
type: "state",
|
||||
stateId: stateId,
|
||||
text: text,
|
||||
fontSize: fontSize
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Migrate burg labels
|
||||
const burgLabelsGroup = document.querySelector("#burgLabels");
|
||||
if (burgLabelsGroup) {
|
||||
burgLabelsGroup.querySelectorAll("g").forEach(groupElement => {
|
||||
const group = groupElement.getAttribute("id");
|
||||
if (!group) return;
|
||||
|
||||
const dxAttr = groupElement.getAttribute("data-dx");
|
||||
const dyAttr = groupElement.getAttribute("data-dy");
|
||||
const dx = dxAttr ? parseFloat(dxAttr) : 0;
|
||||
const dy = dyAttr ? parseFloat(dyAttr) : 0;
|
||||
|
||||
groupElement.querySelectorAll("text").forEach(textElement => {
|
||||
const burgId = +textElement.getAttribute("data-id");
|
||||
if (!burgId) return;
|
||||
|
||||
const burg = pack.burgs[burgId];
|
||||
if (!burg || burg.removed) return;
|
||||
|
||||
const text = textElement.textContent.trim();
|
||||
// Use burg coordinates, not SVG text coordinates
|
||||
// SVG coordinates may be affected by viewbox transforms
|
||||
const x = burg.x;
|
||||
const y = burg.y;
|
||||
|
||||
pack.labels.push({
|
||||
i: labelId++,
|
||||
type: "burg",
|
||||
burgId: burgId,
|
||||
group: group,
|
||||
text: text,
|
||||
x: x,
|
||||
y: y,
|
||||
dx: dx,
|
||||
dy: dy
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Migrate custom labels
|
||||
const customLabelsGroup = document.querySelector("#labels > #addedLabels");
|
||||
if (customLabelsGroup) {
|
||||
customLabelsGroup.querySelectorAll("text").forEach(textElement => {
|
||||
const id = textElement.getAttribute("id");
|
||||
if (!id) return;
|
||||
|
||||
const group = "custom";
|
||||
const textPath = textElement.querySelector("textPath");
|
||||
if (!textPath) return;
|
||||
|
||||
const text = textPath.textContent.trim();
|
||||
const fontSizeAttr = textPath.getAttribute("font-size");
|
||||
const fontSize = fontSizeAttr ? parseFloat(fontSizeAttr) : 100;
|
||||
const letterSpacingAttr = textPath.getAttribute("letter-spacing");
|
||||
const letterSpacing = letterSpacingAttr ? parseFloat(letterSpacingAttr) : 0;
|
||||
const startOffsetAttr = textPath.getAttribute("startOffset");
|
||||
const startOffset = startOffsetAttr ? parseFloat(startOffsetAttr) : 50;
|
||||
const transform = textPath.getAttribute("transform");
|
||||
|
||||
// Get path points from the referenced path
|
||||
const href = textPath.getAttribute("href");
|
||||
if (!href) return;
|
||||
|
||||
const pathId = href.replace("#", "");
|
||||
const pathElement = document.getElementById(pathId);
|
||||
if (!pathElement) return;
|
||||
|
||||
const d = pathElement.getAttribute("d");
|
||||
if (!d) return;
|
||||
|
||||
// Parse path data to extract points (simplified - assumes M and L commands)
|
||||
const pathPoints = [];
|
||||
const commands = d.match(/[MLZ][^MLZ]*/g);
|
||||
if (commands) {
|
||||
commands.forEach(cmd => {
|
||||
const type = cmd[0];
|
||||
if (type === "M" || type === "L") {
|
||||
const coords = cmd.slice(1).trim().split(/[\s,]+/).map(Number);
|
||||
if (coords.length >= 2) {
|
||||
pathPoints.push([coords[0], coords[1]]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (pathPoints.length > 0) {
|
||||
pack.labels.push({
|
||||
i: labelId++,
|
||||
type: "custom",
|
||||
group: group,
|
||||
text: text,
|
||||
pathPoints: pathPoints,
|
||||
startOffset: startOffset,
|
||||
fontSize: fontSize,
|
||||
letterSpacing: letterSpacing,
|
||||
transform: transform || undefined
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Clear old SVG labels and redraw from data
|
||||
if (stateLabelsGroup) stateLabelsGroup.querySelectorAll("*").forEach(el => el.remove());
|
||||
if (burgLabelsGroup) burgLabelsGroup.querySelectorAll("text").forEach(el => el.remove());
|
||||
|
||||
// Regenerate labels from data
|
||||
if (layerIsOn("toggleLabels")) {
|
||||
drawStateLabels();
|
||||
drawBurgLabels();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,6 +407,7 @@ async function parseLoadedData(data, mapVersion) {
|
|||
// data[28] had deprecated cells.crossroad
|
||||
pack.cells.routes = data[36] ? JSON.parse(data[36]) : {};
|
||||
pack.ice = data[39] ? JSON.parse(data[39]) : [];
|
||||
pack.labels = data[40] ? JSON.parse(data[40]) : [];
|
||||
|
||||
if (data[31]) {
|
||||
const namesDL = data[31].split("/");
|
||||
|
|
@ -473,7 +474,7 @@ async function parseLoadedData(data, mapVersion) {
|
|||
|
||||
{
|
||||
// dynamically import and run auto-update script
|
||||
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.109.4");
|
||||
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.113.0");
|
||||
resolveVersionConflicts(mapVersion);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ function prepareMapData() {
|
|||
const routes = JSON.stringify(pack.routes);
|
||||
const zones = JSON.stringify(pack.zones);
|
||||
const ice = JSON.stringify(pack.ice);
|
||||
const labels = JSON.stringify(pack.labels || []);
|
||||
|
||||
// store name array only if not the same as default
|
||||
const defaultNB = Names.getNameBases();
|
||||
|
|
@ -158,7 +159,8 @@ function prepareMapData() {
|
|||
cellRoutes,
|
||||
routes,
|
||||
zones,
|
||||
ice
|
||||
ice,
|
||||
labels
|
||||
].join("\r\n");
|
||||
return mapData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
|
||||
*/
|
||||
|
||||
const VERSION = "1.112.1";
|
||||
const VERSION = "1.113.0";
|
||||
if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function");
|
||||
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue