WIP, organizing weather
This commit is contained in:
+1
-1
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user