727e82c8fe
Alle 14 neuen Glossar-Begriffe bebildert (gpt-image-1, Flat-Scandinavian- Stil, 1600x914 webp wie Bestand) + image_path-SQL. Hintergrundmusik- Standardlautstaerke auf 1/4 (0.09statt 0.35), gespeicherte Nutzerwerte bleiben unangetastet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
2.6 KiB
JavaScript
78 lines
2.6 KiB
JavaScript
// Hintergrundmusik-Player: spielt die Lieder aus assets/music/
|
||
// (HTML5-Audio). Die Original-Dateinamen sind kryptisch – hier bekommen
|
||
// sie stimmige Titel fürs Tal.
|
||
|
||
const DIR = 'assets/music/';
|
||
|
||
export const TRACKS = [
|
||
{ file: 'Geluk op de Piste.mp3', title: 'Glück auf der Piste' },
|
||
{ file: 'Sur les skis en Autriche.mp3', title: 'Auf Skiern durch Österreich' },
|
||
{ file: 'ski rock 1.mp3', title: 'Pistenrock' },
|
||
{ file: 'När jag var liten i Österrike SW.mp3', title: 'Heimweh nach dem Tal' },
|
||
{ file: 'När jag var liten i Österrike SW (1).mp3', title: 'Kindheit in den Bergen' },
|
||
{ file: 'När jag var liten i Österrike SW (2).mp3', title: 'Almsommer' },
|
||
{ file: 'sweet cold tunes.mp3', title: 'Schneegestöber' },
|
||
{ file: 'sweet cold tunes (1).mp3', title: 'Erster Schnee' },
|
||
{ file: 'sweet cold tunes 2.mp3', title: 'Gipfelmelodie' },
|
||
{ file: 'sweet cold tunes 3.mp3', title: 'Winterruhe' },
|
||
{ file: 'sweet cold tunes 3 (1).mp3', title: 'Spuren im Pulverschnee' },
|
||
{ file: 'sweet cold tunes 3 (2).mp3', title: 'Hüttenabend' },
|
||
{ file: 'sweet cold tunes 3 (3).mp3', title: 'Talstation um sieben' },
|
||
{ file: 'sweet cold tunes 3 (4).mp3', title: 'Nordwandlicht' },
|
||
{ file: 'sweet cold tunes 3 (5).mp3', title: 'Seilbahnschweben' },
|
||
{ file: 'sweet cold tunes 3 (6).mp3', title: 'Föhn überm Grat' },
|
||
];
|
||
|
||
export const player = {
|
||
el: null, // HTMLAudioElement
|
||
idx: 0,
|
||
playing: false,
|
||
onChange: null, // UI-Callback bei jedem Zustandswechsel
|
||
|
||
init() {
|
||
this.el = new Audio();
|
||
this.el.volume = Number(localStorage.getItem('tt_volume') ?? 0.09); // Standard leise (1/4 von frueher)
|
||
this.idx = Number(localStorage.getItem('tt_track') ?? 0) % TRACKS.length;
|
||
this.el.addEventListener('ended', () => this.next());
|
||
this._load();
|
||
},
|
||
|
||
_load() {
|
||
this.el.src = DIR + encodeURIComponent(TRACKS[this.idx].file);
|
||
localStorage.setItem('tt_track', this.idx);
|
||
},
|
||
|
||
_notify() { this.onChange?.(); },
|
||
|
||
current() { return TRACKS[this.idx]; },
|
||
|
||
play() {
|
||
this.el.play().then(() => {
|
||
this.playing = true;
|
||
this._notify();
|
||
}).catch(() => { /* Autoplay blockiert – Nutzer startet manuell */ });
|
||
},
|
||
|
||
pause() {
|
||
this.el.pause();
|
||
this.playing = false;
|
||
this._notify();
|
||
},
|
||
|
||
toggle() { this.playing ? this.pause() : this.play(); },
|
||
|
||
next() { this.select((this.idx + 1) % TRACKS.length); },
|
||
prev() { this.select((this.idx - 1 + TRACKS.length) % TRACKS.length); },
|
||
|
||
select(i) {
|
||
this.idx = i % TRACKS.length;
|
||
this._load();
|
||
if (this.playing) this.play(); else this._notify();
|
||
},
|
||
|
||
setVolume(v) {
|
||
this.el.volume = v;
|
||
localStorage.setItem('tt_volume', v);
|
||
},
|
||
};
|