import { Component, createEffect, createSignal, onMount } from "solid-js"; import { ResultKeyVal } from "../../consts"; import { WindInputs, WindSignals } from "./WindInputs"; import arrowUrl from "../../assets/arrow.webp"; import { cityCoords } from "../cityCoords"; import { MapResolution, resolutionProps, windProps, WindProps } from "./mapConsts"; import { CityData, drawOnMap } from "./canvasDraw"; import { IconInputs } from "../weatherIcons/IconInputs"; import { preloadWeatherIcons } from "../weatherIcons/weatherIconAssets"; import { download } from '../../helpers/download' export const MapView: Component<{ type: MapResolution, data: () => ResultKeyVal[], mode?: "temperature" | "faktiska", productionTemplate?: boolean }> = ({ type, data, mode = "temperature", productionTemplate = false }) => { const [getCanvas, setCanvas] = createSignal(); const [getImg, setImg] = createSignal(new Image()); const [fontReady, setFontReady] = createSignal(false); const [iconsReady, setIconsReady] = createSignal(mode !== "faktiska"); const weatherIconsSignal = createSignal<{[key: string]: string;}>({}); const [getWeatherIcons] = weatherIconsSignal; const [getTitle, setTitle] = createSignal(""); const [getSource, setSource] = createSignal(""); let lastCoords: CityData[] = []; const props = resolutionProps[type]; const arrowImg = new Image(); arrowImg.src = arrowUrl; const windSignals: WindSignals = { direction: createSignal(""), speed: createSignal(""), gusts: createSignal(""), roundValues: createSignal(mode === "faktiska"), } function getWindData(): [string, string, string, boolean, WindProps] { return [ windSignals.direction[0](), windSignals.speed[0](), windSignals.gusts[0](), windSignals.roundValues[0](), windProps[type], ]; } onMount(() => { void document.fonts.load(`700 ${props.fontSize}px Monda`).then(() => setFontReady(true)); if (mode === "faktiska") void preloadWeatherIcons().then(() => setIconsReady(true)); const ctx = getCanvas()!.getContext("2d")!; const img = new Image(); img.onload = () => { setImg(img); drawOnMap( ctx, [img, arrowImg], lastCoords, getWindData(), [getTitle(), getSource()], props, productionTemplate, ); }; img.src = props.map; }); createEffect(() => { fontReady(); iconsReady(); const ctx = getCanvas()!.getContext("2d")!; const weatherIcons = getWeatherIcons(); const coordsAndData: CityData[] = data() .map(([city, value]) => [ city, cityCoords[city as keyof typeof cityCoords], typeof value === "number" ? value : -99, weatherIcons[city], ]); lastCoords = coordsAndData; drawOnMap( ctx, [getImg(), arrowImg], coordsAndData, getWindData(), [getTitle(), getSource()], props, productionTemplate, ); }); const getStyleSize = () => { return { "width": "100%", "height": "auto" }; } function downloadPng() { const canvas = getCanvas()!; if (productionTemplate && (canvas.width !== props.width || canvas.height !== props.height)) { console.error(`Faktiskā export blocked: expected ${props.width} × ${props.height}, received ${canvas.width} × ${canvas.height}`); return; } const filename = productionTemplate ? `faktiska-${props.width}x${props.height}.png` : `weather-${type}.png`; canvas.toBlob(blob => blob && download(blob, filename), 'image/png') } return (
{productionTemplate ? "Kartes priekšskatījums" : "Map preview"}{props.width} × {props.height} px {productionTemplate ? "eksports" : "export"}
{productionTemplate ? "Kartes noformējums" : "Broadcast overlay controls"}{!productionTemplate && Optional manual wind and weather-symbol overrides} {!productionTemplate &&

These settings do not change the queried city values. Use them only when preparing a finished broadcast graphic.

} {!productionTemplate &&
}
{productionTemplate ? "Temperatūra un vējš" : "Value and wind settings"}
{ props.showWind && }
{mode === "faktiska" && city)} weatherIconsSignal={weatherIconsSignal} />}
); }