Fix broadcast overlay scaling
This commit is contained in:
@@ -104,6 +104,8 @@ Required behavior:
|
||||
|
||||
The background, title, source, field set, and value positions remain fixed. Only the water-temperature values are routinely edited. Both output sizes are production requirements and must be validated independently; implementation must not assume that browser preview dimensions define export geometry.
|
||||
|
||||
When switching output size, the background may use the target canvas aspect ratio, but boxes, typography, and nameplate elements must scale uniformly. They must never be independently stretched on the horizontal and vertical axes.
|
||||
|
||||
Implementation status: first working version implemented. The page provides six Latvian-named manual min/max controls, automatic fixed placement, Monda rendering, explicit resolution selection, completeness validation, and Latvian PNG filenames. Pixel-level comparison and independent calibration of both output sizes remain required.
|
||||
|
||||
## Latvia overview
|
||||
@@ -136,4 +138,5 @@ Development limitation: representative forecast CSV fixtures are not currently i
|
||||
- Whether Stende and Zīlāni remain the production feeds after users test real provider data.
|
||||
- Confirm how Valmiera is named and sourced when authorized provider data is available.
|
||||
- Final pixel-level Monda export comparison against the production masters.
|
||||
- Replace Daira font-glyph rendering with a normalized SVG weather-symbol set after the design assets are supplied.
|
||||
- Required authentication and role separation for analytical, production, and administrative workspaces.
|
||||
|
||||
@@ -17,3 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
## Monda
|
||||
|
||||
The locally bundled Monda Regular and Monda Bold font files are distributed under the SIL Open Font License 1.1. The complete license text is stored at `Monda/OFL.txt`.
|
||||
|
||||
## Planned weather-symbol SVG handoff
|
||||
|
||||
The production designer will export the authorized Daira weather symbols as outlined SVG artwork for use in the web renderer. Each file should use the same transparent 256×256 artboard, contain no embedded font or raster image, use a tight but optically consistent visible scale, preserve the production stroke appearance, and have a descriptive stable filename. Licensing/authorization for those workplace graphical assets must be confirmed before external distribution.
|
||||
|
||||
@@ -120,6 +120,7 @@ Status: pending
|
||||
- [x] Add an explicit PNG download workflow for broadcast map assets.
|
||||
- [x] Implement the fixed Faktiskā station set, latest-temperature loading, manual overrides, and locked 3840×1440 export.
|
||||
- [x] Make Faktiskā weather-symbol selection manual while keeping placement automatic and badge-relative.
|
||||
- [ ] Replace Daira font glyphs in the web renderer with normalized SVG assets supplied from the production design workflow.
|
||||
- [x] Add a separate Latvian-named Ūdens temperatūra workspace with fixed manual fields.
|
||||
- [ ] Validate independent Ūdens temperatūra exports at 1920×1080 and 3840×1440 against the production specification.
|
||||
- [x] Bundle the confirmed Monda Regular/Bold files and replace temporary Rubik rendering.
|
||||
|
||||
@@ -128,7 +128,7 @@ function drawTitleOverlay(ctx: CanvasRenderingContext2D, title: string, source:
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.font = `bold ${30 * scale}px Monda`;
|
||||
const titleText = title.trim().toUpperCase();
|
||||
const titleWidth = Math.max(360 * scale, ctx.measureText(titleText).width + horizontalPadding * 2);
|
||||
const titleWidth = ctx.measureText(titleText).width + horizontalPadding * 2;
|
||||
const titleX = canvasWidth - right - titleWidth;
|
||||
|
||||
ctx.fillStyle = "#9b0008";
|
||||
@@ -139,7 +139,7 @@ function drawTitleOverlay(ctx: CanvasRenderingContext2D, title: string, source:
|
||||
if (source.trim()) {
|
||||
ctx.font = `bold ${19 * scale}px Monda`;
|
||||
const sourceText = source.trim().toUpperCase();
|
||||
const sourceWidth = Math.max(130 * scale, ctx.measureText(sourceText).width + horizontalPadding * 2);
|
||||
const sourceWidth = ctx.measureText(sourceText).width + horizontalPadding * 2;
|
||||
const sourceX = canvasWidth - right - sourceWidth;
|
||||
ctx.fillStyle = "#FFFFFF";
|
||||
ctx.fillRect(sourceX, top + titleHeight, sourceWidth, sourceHeight);
|
||||
|
||||
@@ -107,9 +107,12 @@ export function WaterTemperature() {
|
||||
function drawRanges(ctx: CanvasRenderingContext2D, width: number, height: number, values: Record<WaterArea, RangeValue>) {
|
||||
const scaleX = width / 3840;
|
||||
const scaleY = height / 1440;
|
||||
const fontSize = 88 * Math.min(scaleX, scaleY);
|
||||
const badgeHeight = 132 * scaleY;
|
||||
const padding = 56 * scaleX;
|
||||
// Backgrounds use their target aspect ratio, but production graphics scale
|
||||
// uniformly so boxes and type are never stretched vertically or horizontally.
|
||||
const graphicScale = scaleX;
|
||||
const fontSize = 88 * graphicScale;
|
||||
const badgeHeight = 132 * graphicScale;
|
||||
const padding = 56 * graphicScale;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.font = `700 ${fontSize}px Monda`;
|
||||
@@ -131,26 +134,27 @@ function drawRanges(ctx: CanvasRenderingContext2D, width: number, height: number
|
||||
function drawNameplate(ctx: CanvasRenderingContext2D, width: number, height: number) {
|
||||
const scaleX = width / 3840;
|
||||
const scaleY = height / 1440;
|
||||
const graphicScale = scaleX;
|
||||
const x = 2698 * scaleX;
|
||||
const y = 145 * scaleY;
|
||||
const titleWidth = 1062 * scaleX;
|
||||
const titleHeight = 124 * scaleY;
|
||||
const sourceWidth = 290 * scaleX;
|
||||
const sourceHeight = 60 * scaleY;
|
||||
const titleWidth = 1062 * graphicScale;
|
||||
const titleHeight = 124 * graphicScale;
|
||||
const sourceWidth = 290 * graphicScale;
|
||||
const sourceHeight = 60 * graphicScale;
|
||||
|
||||
ctx.fillStyle = '#8f090b';
|
||||
ctx.fillRect(x, y, titleWidth, titleHeight);
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.font = `700 ${56 * Math.min(scaleX, scaleY)}px Monda`;
|
||||
ctx.font = `700 ${56 * graphicScale}px Monda`;
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.fillText('ŪDENS TEMPERATŪRA', x + 66 * scaleX, y + titleHeight / 2);
|
||||
ctx.fillText('ŪDENS TEMPERATŪRA', x + 66 * graphicScale, y + titleHeight / 2);
|
||||
|
||||
const sourceX = x + titleWidth - sourceWidth;
|
||||
ctx.fillStyle = '#f4f4f4';
|
||||
ctx.fillRect(sourceX, y + titleHeight, sourceWidth, sourceHeight);
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.font = `700 ${39 * Math.min(scaleX, scaleY)}px Monda`;
|
||||
ctx.font = `700 ${39 * graphicScale}px Monda`;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('LVĢMC', sourceX + sourceWidth / 2, y + titleHeight + sourceHeight / 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user