Center water temperature labels in template boxes

This commit is contained in:
b0txec
2026-08-22 16:27:36 +03:00
parent 06088653b1
commit 7f09181d47
@@ -8,18 +8,25 @@ import './waterTemperature.css';
type OutputSize = '1920x1080' | '3840x1440'; type OutputSize = '1920x1080' | '3840x1440';
type WaterArea = 'Jūra' | 'Līcis' | 'Kurzeme' | 'Zemgale' | 'Vidzeme' | 'Latgale'; type WaterArea = 'Jūra' | 'Līcis' | 'Kurzeme' | 'Zemgale' | 'Vidzeme' | 'Latgale';
type RangeValue = { min: string; max: string }; type RangeValue = { min: string; max: string };
type LabelBox = { x: number; y: number; width: number; height: number };
const areaNames: WaterArea[] = ['Jūra', 'Līcis', 'Kurzeme', 'Zemgale', 'Vidzeme', 'Latgale']; const areaNames: WaterArea[] = ['Jūra', 'Līcis', 'Kurzeme', 'Zemgale', 'Vidzeme', 'Latgale'];
const layouts: Record<OutputSize, { fontSize: number; positions: Record<WaterArea, { x: number; y: number }> }> = { const layouts: Record<OutputSize, { fontSize: number; horizontalPadding: number; boxes: Record<WaterArea, LabelBox> }> = {
'1920x1080': { fontSize: 52, positions: { '1920x1080': { fontSize: 52, horizontalPadding: 20, boxes: {
'Jūra': { x: 237, y: 439 }, 'Līcis': { x: 815, y: 355 }, 'Jūra': { x: 95, y: 396, width: 282, height: 85 },
'Kurzeme': { x: 601, y: 523 }, 'Zemgale': { x: 981, y: 587 }, 'Līcis': { x: 711, y: 313, width: 288, height: 85 },
'Vidzeme': { x: 1236, y: 397 }, 'Latgale': { x: 1393, y: 673 }, 'Kurzeme': { x: 457, y: 480, width: 287, height: 85 },
'Zemgale': { x: 834, y: 544, width: 294, height: 85 },
'Vidzeme': { x: 1089, y: 354, width: 293, height: 85 },
'Latgale': { x: 1252, y: 630, width: 282, height: 85 },
} }, } },
'3840x1440': { fontSize: 88, positions: { '3840x1440': { fontSize: 88, horizontalPadding: 32, boxes: {
'Jūra': { x: 693, y: 721 }, 'Līcis': { x: 1643, y: 455 }, 'Jūra': { x: 471, y: 654, width: 443, height: 133 },
'Kurzeme': { x: 1274, y: 786 }, 'Zemgale': { x: 1815, y: 914 }, 'Līcis': { x: 1417, y: 390, width: 452, height: 133 },
'Vidzeme': { x: 2234, y: 525 }, 'Latgale': { x: 2539, y: 987 }, 'Kurzeme': { x: 1048, y: 719, width: 451, height: 133 },
'Zemgale': { x: 1649, y: 852, width: 461, height: 133 },
'Vidzeme': { x: 2003, y: 458, width: 460, height: 133 },
'Latgale': { x: 2318, y: 920, width: 442, height: 133 },
} }, } },
}; };
@@ -110,16 +117,31 @@ export function WaterTemperature() {
function drawRanges(ctx: CanvasRenderingContext2D, output: OutputSize, values: Record<WaterArea, RangeValue>) { function drawRanges(ctx: CanvasRenderingContext2D, output: OutputSize, values: Record<WaterArea, RangeValue>) {
const layout = layouts[output]; const layout = layouts[output];
ctx.textAlign = 'center'; ctx.textAlign = 'left';
ctx.textBaseline = 'middle'; ctx.textBaseline = 'alphabetic';
ctx.font = `700 ${layout.fontSize}px Monda`;
ctx.fillStyle = '#000'; ctx.fillStyle = '#000';
areaNames.forEach(name => { areaNames.forEach(name => {
const range = values[name]; const range = values[name];
if (!range.min.trim() || !range.max.trim()) return; if (!range.min.trim() || !range.max.trim()) return;
const text = `${range.min}...${range.max}`; const text = `${range.min}...${range.max}`;
const { x, y } = layout.positions[name]; const box = layout.boxes[name];
ctx.fillText(text, x, y); let fontSize = layout.fontSize;
ctx.font = `700 ${fontSize}px Monda`;
let metrics = ctx.measureText(text);
const maximumWidth = box.width - layout.horizontalPadding * 2;
const visibleWidth = metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight;
if (visibleWidth > maximumWidth) {
fontSize *= maximumWidth / visibleWidth;
ctx.font = `700 ${fontSize}px Monda`;
metrics = ctx.measureText(text);
}
const boxCenterX = box.x + box.width / 2;
const boxCenterY = box.y + box.height / 2;
const drawX = boxCenterX - (metrics.actualBoundingBoxRight - metrics.actualBoundingBoxLeft) / 2;
const drawY = boxCenterY + (metrics.actualBoundingBoxAscent - metrics.actualBoundingBoxDescent) / 2;
ctx.fillText(text, drawX, drawY);
}); });
} }