Herzlich willkommen zum SELF-Treffen 2026
vom 24.04. – 26.04.2026 in Halle (Saale)

Beispiel:Karaoke-5.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

<!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">
dd
123
AA
FFF
DD
aa
123
AA
FFF
DD
efe
123
GG
EEE
CC
d
123
AA
FFF
DD
ac
123
AA
FFF
DD
dc
123
AA
FFF
DD
abg
123
dd
BBB
GG
a
123
AA
FFF
DD
d
123
AA
FFF
DD
dd
123
AA
FFF
DD
ca
123
cc
AAA
FF
agf
123
cc
AAA
FF
ec
123
GG
EEE
CC
123
GG
EEE
CC
da
123
AA
FFF
DD
gf
123
dd
BBB
GG
edc
123
A
d
123
AA
FFF
DD
123
AA
FFF
DD
123
A
F
D
 </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>