Fetch binary chunk and draw on canvas

This commit is contained in:
Guntis Smaukstelis
2025-02-03 23:33:28 +02:00
parent c1b1226678
commit df8d16ed4a
18 changed files with 898 additions and 6 deletions
+49
View File
@@ -0,0 +1,49 @@
export const fetchJson = (url: string, options = {}) => {
return fetch(url, options).then(async response => {
let responseCode = ''
if (!response.ok) {
responseCode = `error ${response.status}`
}
let data
let responseMessage = ''
try {
data = await response.json()
if (data.error) responseMessage = data.error
} catch (err) {
responseMessage = 'Invalid JSON response'
}
if (responseCode) {
if (responseMessage) throw new Error(`${responseCode}: ${responseMessage}`)
else throw new Error(responseCode)
} else if (responseMessage) {
throw new Error(responseMessage)
}
return data
})
}
export const fetchBuffer = (url: string, options = {}) => {
return fetch(url, options).then(async response => {
let responseCode = ''
if (!response.ok) {
responseCode = `error ${response.status}`
}
let data
try {
data = await response.arrayBuffer()
} catch (err) {
throw new Error('Invalid ArrayBuffer response')
}
if (responseCode) {
throw new Error(responseCode)
}
return data
})
}
+47
View File
@@ -0,0 +1,47 @@
import { ColorEntry } from '../grib/draw/constants'
type RGBu8 = [number, number, number]
type RGBAu8 = [number, number, number, number]
export function interpolateColors(value: number, a: RGBu8, b: RGBu8): RGBAu8 {
const color = a.slice(0).map((from, i) => {
const to = b[i]
const delta = (to - from) * (value/255)
return from + delta
})
return [...color, 255] as RGBAu8
}
export function valueToColorThreshold(value: number, colorArr: ColorEntry[]): [number, number, number, number] {
const entries = colorArr.filter(t => t.value <= value)
return entries.length === 0 ? colorArr[colorArr.length-1].color : entries[0].color
}
export function valueToColorInterpolated(value: number, colorArr: ColorEntry[]): [number, number, number, number] {
const minIdx = colorArr.length-1
if (value >= colorArr[0].value) return colorArr[0].color
if (value <= colorArr[minIdx].value) return colorArr[minIdx].color
let closeMax: ColorEntry = colorArr[0]
let closeMin: ColorEntry = colorArr[minIdx]
for (let i=0; i<colorArr.length; i++) {
const currentDeg = colorArr[i].value
if (currentDeg >= value && currentDeg < closeMax.value) {
closeMax = colorArr[i]
}
if (currentDeg <= value && currentDeg > closeMin.value) {
closeMin = colorArr[i]
}
}
const maxDeg = closeMax.color.slice(0, 3) as [number, number, number]
const minDeg = closeMin.color.slice(0, 3) as [number, number, number]
const scale = Math.abs(closeMax.value - closeMin.value)
const delta = 255*(value - closeMin.value)/scale
const rgba = interpolateColors(delta, minDeg, maxDeg)
return rgba
}
+19
View File
@@ -0,0 +1,19 @@
export type U8bits = [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean]
export function u8ToBits(dec: number): U8bits {
const str = (dec >>> 0).toString(2)
const str8 = leftPad(str)
const arr: U8bits = [false, false, false, false, false, false, false, false]
for (let i=0; i<8; i++) {
arr[i] = str8[i] === '1' ? true : false
}
return arr
}
function leftPad(str: string): string {
const padCount = 8 - str.length
for(let i=0; i<padCount; i++) {
str = '0' + str
}
return str
}