diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 5644960bc..dabc074ae 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -2189,8 +2189,9 @@ global 2048 × 1024 grid, each weighted by its FRP in megawatts (so heat is radiated power, and raising the FRP slider does not dim areas where strong fires burn), Gaussian-blurred, normalized on a log scale against the 99.5th percentile and mapped through the -same colors, from a faint ember edge through red, orange and gold to a pale -white-hot core. Nothing is painted where +same hues, from a bright red edge through orange and gold to a pale +white-hot core. The edge starts more than half opaque, so regions far below +the hottest ones still read over forest and savanna imagery. Nothing is painted where nothing burns (`src/data/firmsHeatRaster.js`). It is one full-globe imagery tile on the active imagery host (`src/layers/firms/heatImagery.js`), rebuilt on each data refresh or filter change (the first paint at once, later ones diff --git a/src/data/firmsHeatRaster.js b/src/data/firmsHeatRaster.js index 985699d7e..f6aadff3b 100644 --- a/src/data/firmsHeatRaster.js +++ b/src/data/firmsHeatRaster.js @@ -9,17 +9,20 @@ export const HEAT_FLOOR = 0.03; /** - * The FRP marker ramp as a continuous glow: faint ember at the edges, a - * pale white-hot core where the most power burns. + * The FRP marker ramp as a continuous glow, from a red edge through orange + * and gold to a pale white-hot core. The edge is a bright red, not the + * markers' dark ember, and starts more than half opaque: most of the world + * sits low on a scale set by the hottest regions, and a dark translucent red + * vanishes into forest and savanna imagery. */ export const HEAT_PALETTE = Object.freeze([ - { at: 0.0, rgb: [158, 42, 27], alpha: 0 }, - { at: 0.08, rgb: [158, 42, 27], alpha: 0.35 }, - { at: 0.25, rgb: [210, 64, 31], alpha: 0.55 }, - { at: 0.45, rgb: [240, 106, 40], alpha: 0.65 }, - { at: 0.65, rgb: [251, 154, 46], alpha: 0.75 }, - { at: 0.82, rgb: [253, 200, 74], alpha: 0.82 }, - { at: 1.0, rgb: [255, 243, 176], alpha: 0.9 }, + { at: 0.0, rgb: [232, 58, 30], alpha: 0 }, + { at: 0.08, rgb: [232, 58, 30], alpha: 0.58 }, + { at: 0.25, rgb: [242, 86, 34], alpha: 0.7 }, + { at: 0.45, rgb: [248, 122, 40], alpha: 0.76 }, + { at: 0.65, rgb: [252, 166, 52], alpha: 0.82 }, + { at: 0.82, rgb: [254, 208, 92], alpha: 0.87 }, + { at: 1.0, rgb: [255, 245, 190], alpha: 0.92 }, ]); export function heatColorAt(t) { diff --git a/src/data/firmsHeatRaster.test.mjs b/src/data/firmsHeatRaster.test.mjs index a5cf7eccf..25c8b61fb 100644 --- a/src/data/firmsHeatRaster.test.mjs +++ b/src/data/firmsHeatRaster.test.mjs @@ -18,7 +18,8 @@ test('palette runs ember to white-hot and starts fully transparent', () => { assert.equal(heatColorAt(0.01)[3], 0, 'below the floor nothing is painted'); const low = heatColorAt(0.15); const high = heatColorAt(1); - assert.ok(low[0] > low[1] && low[1] > low[2], 'low heat is an ember red'); + assert.ok(low[0] > low[1] && low[1] > low[2], 'low heat is red'); + assert.ok(low[3] >= 0.5 * 255, 'low heat stays visible on any imagery'); assert.ok(high[1] > low[1] && high[2] > low[2], 'the core is paler'); assert.ok(high[3] > low[3], 'hotter is more opaque'); for (let i = 1; i <= 100; i++) {