Skip to content

Commit 07690ff

Browse files
committed
better working window
1 parent 6fccbfe commit 07690ff

1 file changed

Lines changed: 40 additions & 8 deletions

File tree

src/marineMap.svelte

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,13 @@
8484
// 3 h step so changes line up with both wind + wave file cadences.
8585
let weatherForecastHour = $state(0);
8686
let weatherRunTime = $state<string | null>(null);
87-
let weatherLoading = $state(false);
87+
// Per-layer fetch state. Default true because both setupWeatherLayer
88+
// calls fire at mount; flipped false in each .finally below. Reused
89+
// for refetches (model swap, forecast-hour scrub) so the spinner in
90+
// the forecast bar covers both initial load and subsequent fetches.
91+
let windLoading = $state(true);
92+
let waveLoading = $state(true);
93+
let weatherLoading = $derived(windLoading || waveLoading);
8894
// First forecast hour ≥ "now", computed from the GFS run time. Used
8995
// as the slider minimum so the user can't scrub back into already-
9096
// expired analysis hours.
@@ -3036,6 +3042,9 @@
30363042
})
30373043
.catch((err) => {
30383044
console.warn("wind layer disabled:", err);
3045+
})
3046+
.finally(() => {
3047+
windLoading = false;
30393048
});
30403049
// Wave overlay: ol-wind particle animation driven by Thgt+Tdir
30413050
// from PacIOOS WaveWatch III, fetched server-side via OPeNDAP
@@ -3076,6 +3085,9 @@
30763085
})
30773086
.catch((err) => {
30783087
console.warn("wave layer disabled:", err);
3088+
})
3089+
.finally(() => {
3090+
waveLoading = false;
30793091
});
30803092
// Populate the model picker. Failures are non-fatal — the picker
30813093
// just stays at the bundled defaults (GFS + PacIOOS) if the
@@ -4860,7 +4872,7 @@
48604872
value={windModel}
48614873
onchange={async (e) => {
48624874
const next = (e.currentTarget as HTMLSelectElement).value;
4863-
weatherLoading = true;
4875+
windLoading = true;
48644876
setWeatherError(null);
48654877
try {
48664878
const err = await windHandle?.setModel(next);
@@ -4884,7 +4896,7 @@
48844896
mapGlobal.map?.render();
48854897
}
48864898
} finally {
4887-
weatherLoading = false;
4899+
windLoading = false;
48884900
}
48894901
}}
48904902
>
@@ -4904,7 +4916,7 @@
49044916
value={waveModel}
49054917
onchange={async (e) => {
49064918
const next = (e.currentTarget as HTMLSelectElement).value;
4907-
weatherLoading = true;
4919+
waveLoading = true;
49084920
setWeatherError(null);
49094921
try {
49104922
const err = await swapWaveModel(next);
@@ -4916,7 +4928,7 @@
49164928
(e.currentTarget as HTMLSelectElement).value = waveModel;
49174929
}
49184930
} finally {
4919-
weatherLoading = false;
4931+
waveLoading = false;
49204932
}
49214933
}}
49224934
>
@@ -4940,7 +4952,9 @@
49404952
{:else}
49414953
+{weatherForecastHour}h
49424954
{/if}
4943-
{#if weatherLoading}…{/if}
4955+
{#if weatherLoading}
4956+
<span class="wind-forecast-bar-spinner" aria-label="loading" title="loading"></span>
4957+
{/if}
49444958
</label>
49454959
<div class="wind-forecast-bar-slider-wrap">
49464960
{#each dayMarkers as m (m.pct)}
@@ -4971,7 +4985,8 @@
49714985
// re-render at the stale old value and snap the thumb back
49724986
// to the slider's min.
49734987
weatherForecastHour = v;
4974-
weatherLoading = true;
4988+
if (windHandle) windLoading = true;
4989+
if (waveHandle) waveLoading = true;
49754990
// Hide both data layers while we refetch so the user doesn't
49764991
// see the previous forecast hour's pixels under the new
49774992
// forecast-hour label — purely visual, the OL layers stay
@@ -5001,7 +5016,8 @@
50015016
}
50025017
mapGlobal.map?.render();
50035018
} finally {
5004-
weatherLoading = false;
5019+
windLoading = false;
5020+
waveLoading = false;
50055021
windLayer?.setVisible?.(true);
50065022
waveLayer?.setVisible?.(true);
50075023
}
@@ -6464,6 +6480,22 @@
64646480
min-width: 70px;
64656481
text-align: right;
64666482
}
6483+
.wind-forecast-bar-spinner {
6484+
display: inline-block;
6485+
width: 12px;
6486+
height: 12px;
6487+
margin-left: 6px;
6488+
vertical-align: -2px;
6489+
border: 2px solid rgba(0, 0, 0, 0.18);
6490+
border-top-color: #0a66c2;
6491+
border-radius: 50%;
6492+
animation: wind-forecast-bar-spin 0.7s linear infinite;
6493+
}
6494+
@keyframes wind-forecast-bar-spin {
6495+
to {
6496+
transform: rotate(360deg);
6497+
}
6498+
}
64676499
.wind-forecast-bar input[type="range"] {
64686500
width: 240px;
64696501
display: block;

0 commit comments

Comments
 (0)