Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026
in Halle (Saale)
Beispiel:Karaoke-5.html
<!doctype html> <html lang="de"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" media="screen" href="./Beispiel:Grundlayout.css"> <title>Scarborough Fair – Boomwhacker-Player</title> <style>
.d, .D { background: #f89c1c; }
.e, .E { background: #fff229; }
.f, .F { background: #d4e05a; }
.g, .G { background: #009c95; color: #fff; }
.a, .A { background: #5d4fa1; color: #fff; }
.b, .B { background: #ce3895; color: #fff; }
.c, .C { background: #e31a47; color: #fff; }
:root {
--line: #888;
--highlight: #fff27a;
}
* { box-sizing: border-box; }
body { font-family: sans-serif;
max-width: 55em;
margin: auto;
padding: .5em;
}
.chips {
display: inline-flex;
flex-wrap: wrap;
gap: .35em;
vertical-align: middle;
}
.score {
margin-top: 1.5em;
}
.system {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
margin-bottom: 1em;
}
.measure {
flex: 0 1 13em;
min-width: 13em;
padding: 0 0 .5em .5em;
margin-bottom: 2em;
border-left: thin solid var(--line);
border-bottom: thin solid var(--line);
transition: background-color .18s ease, box-shadow .18s ease;
}
.part {
display: grid;
grid-template-columns: repeat(6, 1.5em);
justify-content: start;
align-items: center;
column-gap: .5em;
min-height: 2em;
}
.beats {
display: grid;
grid-template-columns: repeat(3, 1fr);
margin: .2em 0 0 .5em;
text-align: left;
min-height: 1.7em;
}
.melody {
min-height: 3em;
}
.note {
grid-column: var(--c);
justify-self: center;
inline-size: 2em;
block-size: 2em;
aspect-ratio: 1 / 1;
border: 1px solid rgba(0, 0, 0, .35);
border-radius: 50%;
display: grid;
place-items: center;
font-weight: 700;
line-height: 1;
}
.sm {
inline-size: 1.8em;
block-size: 1.8em;
font-size: .95em;
}
@media screen {
.measure.active {
background: var(--highlight);
box-shadow: inset 0 0 0 .08em rgba(0, 0, 0, .08);
}
}
audio {
position: sticky;
top: 0;
z-index: 10;
background: #fff;
padding: .5em 0;
}
.flex-spacer {
flex: 99;
visibility: hidden;
}
@media print {
body {
max-width: 100%;
margin-left: 1cm;
font-size: .7em;
}
audio,
button {
display: none;
}
}
</style> </head> <body>
Scarborough Fair, Boomwhacker in D <button onclick="window.print()">Seite drucken</button>
Abgeleitet von <a href="https://lernumgebungen.ch/aufgabenstellung/scarborough-fair-wer-hat-es-erfunden" target="_blank" rel="noopener noreferrer"> CC BY SA 2020 – Annina Hauser</a>
<audio id="player" controls>
<source src="/images/c/c5/Scarborough_Fair_Boomwhacker.mp3" type="audio/mpeg">
Dein Browser unterstützt das Audio-Element nicht.
</audio>
Alle Takte stehen im Dreivierteltakt. Jeder Takt ist in sechs Rasterfelder unterteilt, damit Töne auch zwischen zwei Schlägen platziert werden können. Die obere Zeile zeigt die Melodie, die unteren die bis zu dreistimmige Begleitung.
<section class="score" aria-label="Melodie und Begleitung im Takt-Raster">
</section>
<script>
document.addEventListener('DOMContentLoaded', () => {
const audio = document.getElementById('player');
const measures = Array.from(document.querySelectorAll('.measure'));
const BPM = 160;
const BEATS_PER_BAR = 3;
const COUNT_IN_BEATS = 3;
const EARLY_OFFSET = 0.5;
const secondsPerBeat = 60 / BPM;
const secondsPerBar = secondsPerBeat * BEATS_PER_BAR;
const firstBarStart = secondsPerBeat * COUNT_IN_BEATS - EARLY_OFFSET;
const totalBarsPerCycle = measures.length;
let activeMeasureIndex = -1;
function clearActiveMeasure() {
if (activeMeasureIndex < 0) return;
measures[activeMeasureIndex].classList.remove('active');
activeMeasureIndex = -1;
}
function getMeasureIndex(currentTime) {
if (currentTime < firstBarStart) return -1;
const barIndexFromStart = Math.floor((currentTime - firstBarStart) / secondsPerBar);
return ((barIndexFromStart % totalBarsPerCycle) + totalBarsPerCycle) % totalBarsPerCycle;
}
function updateActiveMeasure() {
const nextIndex = getMeasureIndex(audio.currentTime);
if (nextIndex === activeMeasureIndex) return;
clearActiveMeasure();
if (nextIndex < 0) return;
measures[nextIndex].classList.add('active');
measures[nextIndex].scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
activeMeasureIndex = nextIndex;
}
['timeupdate', 'seeked', 'play', 'pause'].forEach(eventName => {
audio.addEventListener(eventName, updateActiveMeasure);
});
updateActiveMeasure(); }); </script>
</body> </html>