diff --git a/web/src/cities/map/MapView.tsx b/web/src/cities/map/MapView.tsx index addca84..cdbdd4f 100644 --- a/web/src/cities/map/MapView.tsx +++ b/web/src/cities/map/MapView.tsx @@ -1,34 +1,12 @@ import { Component, createEffect, createSignal, onMount } from "solid-js"; import { ResultKeyVal } from "../../consts"; -import { drawRotatedImage, getAngleFromString } from "./windAngles"; import { WindInputs, WindSignals } from "./WindInputs"; -import map_1920x1080 from "../../assets/map_1920x1080.webp"; -import map_1920x1080_wind from "../../assets/map_1920x1080_wind.webp"; -import map_3840x1440 from "../../assets/map_3840x1440.webp"; -import map_3840x1440_wind from "../../assets/map_3840x1440_wind.webp"; import arrowUrl from "../../assets/arrow.webp"; import { cityCoords } from "../../components/cityCoords"; - -type MapResolution = "map_1920x1080" | "map_1920x1080_wind" | "map_3840x1440" | "map_3840x1440_wind"; - -type ResolutionPropsValue = { - offsetX: number; - offsetY: number; - width: number; - height: number; - scale: number; - showWind: boolean; - map: string; -}; - -const resolutionProps: Record = { - "map_1920x1080": { offsetX: 90, offsetY: 120, width: 1920, height: 1080, scale: 1.35, showWind: false, map: map_1920x1080 }, - "map_1920x1080_wind": { offsetX: 90, offsetY: 120, width: 1920, height: 1080, scale: 1.35, showWind: true, map: map_1920x1080_wind }, - "map_3840x1440": { offsetX: 800, offsetY: 120, width: 3840, height: 1440, scale: 2.2, showWind: false, map: map_3840x1440 }, - "map_3840x1440_wind": { offsetX: 800, offsetY: 120, width: 3840, height: 1440, scale: 2.2, showWind: true, map: map_3840x1440_wind }, -} +import { MapResolution, resolutionProps, ResolutionPropsValue, windProps, WindProps } from "./mapConsts"; +import { drawOnMap } from "./canvasDraw"; export const MapView: Component<{ type: MapResolution, data: () => ResultKeyVal[] }> = ({ type, data }) => { const [getCanvas, setCanvas] = createSignal(); @@ -46,12 +24,13 @@ export const MapView: Component<{ type: MapResolution, data: () => ResultKeyVal[ roundValues: createSignal(false), } - function getWindData(): [string, string, string, boolean] { + function getWindData(): [string, string, string, boolean, WindProps] { return [ windSignals.direction[0](), windSignals.speed[0](), windSignals.gusts[0](), windSignals.roundValues[0](), + windProps[type], ]; } @@ -91,7 +70,7 @@ export const MapView: Component<{ type: MapResolution, data: () => ResultKeyVal[ return ( <> - + { props.showWind && } ResultKeyVal[ ); } - -function drawOnMap( - ctx: CanvasRenderingContext2D, - imgArr: [HTMLImageElement, HTMLImageElement], - coords: [string, {x: number, y: number }, number][], - windData: [string, string, string, boolean], - props: ResolutionPropsValue, -): void { - const boxSize = 80; - - const [windDirection, windSpeed, windGusts, roundValues] = windData; - const [bgImg, arrowImg] = imgArr; - - // bg - ctx.drawImage(bgImg, 0, 0); - - // city boxes - ctx.fillStyle = "#FFFFFF"; - coords.forEach(([, {x, y}, value]) => { - const localX = props.offsetX + x * props.scale; - const localY = props.offsetY + y * props.scale; - - ctx.beginPath(); - ctx.fillStyle = "#FFFFFF"; - ctx.rect(localX-boxSize/2, localY-boxSize/2, boxSize, boxSize); - ctx.fill(); - }); - ctx.fill(); - - // weather values - ctx.font = "bold 30px Rubik"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - coords.forEach(([, {x, y}, value]) => { - const localX = props.offsetX + x * props.scale; - const localY = props.offsetY + y * props.scale; - - ctx.fillStyle = "#000000"; - const numericValue = roundValues ? Math.round(value) : value; - const stringValue = numericValue.toString().replace(".", ","); - ctx.fillText(stringValue, localX, localY); - }); - - if (!props.showWind) return; - - // wind values - ctx.font = "bold 45px Rubik"; - ctx.textAlign = "left"; - ctx.textBaseline = "top"; - ctx.fillStyle = "#FFFFFF"; - const boxMiddleX = 1675; - - const directionWidth = ctx.measureText(windDirection).width; - ctx.fillText(windDirection, boxMiddleX - directionWidth / 2 + 30, 370); - const angleInDegrees = getAngleFromString(windDirection); - drawRotatedImage(ctx, arrowImg, boxMiddleX - directionWidth / 2 - 30, 370, angleInDegrees); - - const speedWidth = ctx.measureText(windSpeed).width; - ctx.fillText(windSpeed, boxMiddleX - speedWidth / 2 - 30, 575); - ctx.font = "bold 25px Rubik"; - ctx.fillText("M/S", boxMiddleX + speedWidth / 2 - 22, 590); - - ctx.font = "bold 45px Rubik"; - const gustsWidth = ctx.measureText(windGusts).width; - ctx.fillText(windGusts, boxMiddleX - gustsWidth / 2 - 30, 790); - ctx.font = "bold 25px Rubik"; - ctx.fillText("M/S", boxMiddleX + gustsWidth / 2 - 22, 805); -} \ No newline at end of file diff --git a/web/src/cities/map/canvasDraw.ts b/web/src/cities/map/canvasDraw.ts new file mode 100644 index 0000000..0e0f63c --- /dev/null +++ b/web/src/cities/map/canvasDraw.ts @@ -0,0 +1,70 @@ +import { ResolutionPropsValue, WindProps, windProps } from "./mapConsts"; +import { drawRotatedImage, getAngleFromString } from "./windAngles"; + +export function drawOnMap( + ctx: CanvasRenderingContext2D, + imgArr: [HTMLImageElement, HTMLImageElement], + coords: [string, {x: number, y: number }, number][], + windData: [string, string, string, boolean, WindProps], + props: ResolutionPropsValue, +): void { + const boxSize = 80; + + const [windDirection, windSpeed, windGusts, roundValues, windProp] = windData; + const [bgImg, arrowImg] = imgArr; + + // bg + ctx.drawImage(bgImg, 0, 0); + + // city boxes + ctx.fillStyle = "#FFFFFF"; + coords.forEach(([, {x, y}, value]) => { + const localX = props.offsetX + x * props.scale; + const localY = props.offsetY + y * props.scale; + + ctx.beginPath(); + ctx.fillStyle = "#FFFFFF"; + ctx.rect(localX-boxSize/2, localY-boxSize/2, boxSize, boxSize); + ctx.fill(); + }); + ctx.fill(); + + // weather values + ctx.font = "bold 30px Rubik"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + coords.forEach(([, {x, y}, value]) => { + const localX = props.offsetX + x * props.scale; + const localY = props.offsetY + y * props.scale; + + ctx.fillStyle = "#000000"; + const numericValue = roundValues ? Math.round(value) : value; + const stringValue = numericValue.toString().replace(".", ","); + ctx.fillText(stringValue, localX, localY); + }); + + if (!props.showWind) return; + + // wind values + ctx.font = "bold 45px Rubik"; + ctx.textAlign = "left"; + ctx.textBaseline = "top"; + ctx.fillStyle = "#FFFFFF"; + const boxMiddleX = 1675; + + const directionWidth = ctx.measureText(windDirection).width; + ctx.fillText(windDirection, windProp.offsetX + boxMiddleX - directionWidth / 2 + 30, (windProp.offsetY + 370)*windProp.scaleY); + const angleInDegrees = getAngleFromString(windDirection); + drawRotatedImage(ctx, arrowImg, windProp.offsetX + boxMiddleX - directionWidth / 2 - 30, (windProp.offsetY + 370)*windProp.scaleY, angleInDegrees); + + const speedWidth = ctx.measureText(windSpeed).width; + ctx.fillText(windSpeed, windProp.offsetX + boxMiddleX - speedWidth / 2 - 30, (windProp.offsetY + 575)*windProp.scaleY); + ctx.font = "bold 25px Rubik"; + ctx.fillText("M/S", windProp.offsetX + boxMiddleX + speedWidth / 2 - 22, (windProp.offsetY + 590)*windProp.scaleY); + + ctx.font = "bold 45px Rubik"; + const gustsWidth = ctx.measureText(windGusts).width; + ctx.fillText(windGusts, windProp.offsetX + boxMiddleX - gustsWidth / 2 - 30, (windProp.offsetY + 790)*windProp.scaleY); + ctx.font = "bold 25px Rubik"; + ctx.fillText("M/S", windProp.offsetX + boxMiddleX + gustsWidth / 2 - 22, (windProp.offsetY + 805)*windProp.scaleY); +} diff --git a/web/src/cities/map/mapConsts.ts b/web/src/cities/map/mapConsts.ts new file mode 100644 index 0000000..00d267c --- /dev/null +++ b/web/src/cities/map/mapConsts.ts @@ -0,0 +1,34 @@ +import map_1920x1080 from "../../assets/map_1920x1080.webp"; +import map_1920x1080_wind from "../../assets/map_1920x1080_wind.webp"; +import map_3840x1440 from "../../assets/map_3840x1440.webp"; +import map_3840x1440_wind from "../../assets/map_3840x1440_wind.webp"; + +export type MapResolution = "map_1920x1080" | "map_1920x1080_wind" | "map_3840x1440" | "map_3840x1440_wind"; + +export type ResolutionPropsValue = { + offsetX: number; + offsetY: number; + width: number; + height: number; + scale: number; + showWind: boolean; + map: string; +}; + +export const resolutionProps: Record = { + "map_1920x1080": { offsetX: 290, offsetY: 120, width: 1920, height: 1080, scale: 1.35, showWind: false, map: map_1920x1080 }, + "map_1920x1080_wind": { offsetX: 90, offsetY: 120, width: 1920, height: 1080, scale: 1.35, showWind: true, map: map_1920x1080_wind }, + "map_3840x1440": { offsetX: 800, offsetY: 120, width: 3840, height: 1440, scale: 2.2, showWind: false, map: map_3840x1440 }, + "map_3840x1440_wind": { offsetX: 800, offsetY: 120, width: 3840, height: 1440, scale: 2.2, showWind: true, map: map_3840x1440_wind }, +} + +export type WindProps = { + offsetX: number; + offsetY: number; + scaleY: number; +}; + +export const windProps: Record = { + "map_1920x1080_wind": { offsetX: 0, offsetY: 0, scaleY: 1, }, + "map_3840x1440_wind": { offsetX: 1610, offsetY: 80, scaleY: 1.24, }, +}