WIP, organizing weather

This commit is contained in:
Lani Aung
2025-06-10 21:47:15 -07:00
parent 28610b0c3b
commit ff945dca70
6 changed files with 2051 additions and 41 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ export default class Crack {
start(x: number, y: number, angle: number) { start(x: number, y: number, angle: number) {
this.x = x + .61 * Math.cos(angle * Math.PI / 180) this.x = x + .61 * Math.cos(angle * Math.PI / 180)
this.y = y + .61 * Math.sin(angle * Math.PI / 180) this.y = y + .61 * Math.sin(angle * Math.PI / 180)
const flip = Math.random() < 0.5 const flip = Math.random() > 0.5
this.angle = angle + (90 + Math.floor(Math.random() * 4.1 - 2)) * (flip ? -1 : 1) this.angle = angle + (90 + Math.floor(Math.random() * 4.1 - 2)) * (flip ? -1 : 1)
} }
+4 -6
View File
@@ -4,13 +4,11 @@ import Weather from "./weather"
const ready = (func: () => void) => document.readyState !== "loading" ? func() : document.addEventListener("DOMContentLoaded", func) const ready = (func: () => void) => document.readyState !== "loading" ? func() : document.addEventListener("DOMContentLoaded", func)
ready(() => { ready(() => {
new Substrate(20) new Substrate(20)
})
/* let weather: Weather
let weather: Weather navigator.geolocation.getCurrentPosition(position => {
navigator.geolocation.getCurrentPosition(position => {
weather = new Weather(position.coords.latitude, position.coords.longitude) weather = new Weather(position.coords.latitude, position.coords.longitude)
}, () => { }, () => {
weather = new Weather() weather = new Weather()
})
}) })
*/
+12 -1
View File
@@ -4,9 +4,20 @@ export default class State {
readonly canvas: HTMLCanvasElement readonly canvas: HTMLCanvasElement
readonly maxCracks: number readonly maxCracks: number
readonly grid: number[][] readonly grid: number[][]
readonly canvasColors = [
"rgb(27 27 27 / 90%)",
"rgb(90 90 90 / 90%)",
"rgb(126 126 126 / 90%)",
"rgb(180 180 180 / 90%)",
"rgb(255 255 255 / 90%)",
"rgb(180 180 180 / 90%)",
"rgb(126 126 126 / 90%)",
"rgb(90 90 90 / 90%)"
]
colors: number[] colors: number[]
seeds: {x: number, y: number}[] seeds: {x: number, y: number}[]
cracks: Crack[] cracks: Crack[]
canvasIndex: number = 0
colorIndex: number = 0 colorIndex: number = 0
constructor(colors: number[], maxCracks: number, canvas: HTMLCanvasElement) { constructor(colors: number[], maxCracks: number, canvas: HTMLCanvasElement) {
@@ -30,7 +41,7 @@ export default class State {
const height = this.canvas.height const height = this.canvas.height
const width = this.canvas.width const width = this.canvas.width
const context = this.canvas.getContext("2d") const context = this.canvas.getContext("2d")
context.fillStyle = "rgb(255 255 255 / 95%)" context.fillStyle = this.canvasColors[this.canvasIndex++ % this.canvasColors.length]
context.fillRect(0, 0, width, height) context.fillRect(0, 0, width, height)
for (let x = 0; x < width; x++) { for (let x = 0; x < width; x++) {
+111 -18
View File
@@ -1,21 +1,52 @@
import { fetchWeatherApi } from 'openmeteo' import { fetchWeatherApi } from 'openmeteo'
export default class Weather { export default class Weather {
private readonly apiUrl = "https://api.open-meteo.com/v1/forecast"
private readonly options: WeatherOptions private readonly options: WeatherOptions
private readonly dailyVariables = ["temperature_2m_max", "temperature_2m_min", "sunrise", "sunset", "uv_index_max", "precipitation_sum", "precipitation_hours", "wind_speed_10m_max", "wind_gusts_10m_max", "wind_direction_10m_dominant"]
private readonly hourlyVariables = ["temperature_2m", "precipitation", "precipitation_probability"]
private readonly currentVariables = ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "precipitation", "wind_speed_10m", "wind_gusts_10m", "wind_direction_10m"]
private lastFetched: LastFetched
current: CurrentWeather
hourly: HourlyWeather[] = []
daily: DailyWeather[] = []
constructor(latitude?: number, longitude?: number) { constructor(latitude?: number, longitude?: number) {
latitude ??= 47.61002138071677 this.options = new WeatherOptions(latitude ?? 47.61002138071677, longitude ?? -122.17906310779568)
longitude ??= -122.17906310779568
this.options = new WeatherOptions() const me = this
this.options = { ...this.options, latitude, longitude } me.getWeather().then(() => {
})
this.getWeather(this.options)
} }
async getWeather(options: WeatherOptions) { async getWeather(): Promise<void> {
const url = "https://api.open-meteo.com/v1/forecast" const me = this
const responses = await fetchWeatherApi(url, this.options) const parameters: any = { ...me.options }
if (!me.lastFetched) {
parameters["daily"] = me.dailyVariables
parameters["hourly"] = me.hourlyVariables
parameters["current"] = me.currentVariables
me.lastFetched = new LastFetched()
} else {
// Reasonable-ish timers?
if (me.lastFetched.minutesSinceCurrent() > 15) {
parameters["current"] = me.currentVariables
me.lastFetched.current = new Date()
}
if (me.lastFetched.hoursSinceHourly() > 3) {
parameters["hourly"] = me.hourlyVariables
me.lastFetched.hourly = new Date()
}
if (me.lastFetched.hoursSinceDaily() > 8) {
parameters["daily"] = me.dailyVariables
me.lastFetched.daily = new Date()
}
}
const responses = await fetchWeatherApi(me.apiUrl, parameters)
for (const response of responses) { for (const response of responses) {
// Attributes for timezone and location // Attributes for timezone and location
@@ -73,6 +104,8 @@ export default class Weather {
}, },
} }
console.log(weatherData)
// `weatherData` now contains a simple structure with arrays for datetime and weather data // `weatherData` now contains a simple structure with arrays for datetime and weather data
for (let i = 0; i < weatherData.hourly.time.length; i++) { for (let i = 0; i < weatherData.hourly.time.length; i++) {
console.log( console.log(
@@ -102,13 +135,73 @@ export default class Weather {
} }
class WeatherOptions { class WeatherOptions {
latitude: number readonly latitude: number
longitude: number readonly longitude: number
daily: string[] = ["temperature_2m_max", "temperature_2m_min", "sunrise", "sunset", "uv_index_max", "precipitation_sum", "precipitation_hours", "wind_speed_10m_max", "wind_gusts_10m_max", "wind_direction_10m_dominant"] readonly timezone: string = "America/Los_Angeles"
hourly: string[] = ["temperature_2m", "precipitation", "precipitation_probability"] "wind_speed_unit" = "mph"
current: string[] = ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "precipitation", "wind_speed_10m", "wind_gusts_10m", "wind_direction_10m"] "temperature_unit" = "fahrenheit"
timezone: string = "America/Los_Angeles" "precipitation_unit" = "inch"
"wind_speed_unit": string = "mph"
"temperature_unit": string = "fahrenheit" constructor(latitude: number, longitude: number, timezone = "America/Los_Angeles") {
"precipitation_unit": string = "inch" this.latitude = latitude
this.longitude = longitude
this.timezone = timezone
}
}
class CurrentWeather {
time: Date
temperature: number
humidity: number
feelsLike: number
precipitation: number
windSpeed: number
windGusts: number
windDirection: number
}
class DailyWeather {
hoursOfPrecipitation: number
totalPrecipitation: number
sunrise: Date
sunset: Date
maxTemperature: number
minTemperature: number
maxUV: number
prominentWindDirection: number
maxWindGusts: number
maxWindSpeed: number
asOf: Date
}
class HourlyWeather {
time: Date
precipitation: number
precipitationProbability: number
temperature: number
}
class LastFetched {
current: Date
hourly: Date
daily: Date
constructor() {
const now = new Date()
this.current = now
this.hourly = now
this.daily = now
}
minutesSinceCurrent(): number {
return 0
}
hoursSinceHourly(): number {
return 0
}
hoursSinceDaily(): number {
return 0
}
} }
+1919 -11
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long