Označovač akordů v JavaScriptu

JavaScript Označovač akordů v JavaScriptu

V tomto tutoriálu si vytvoříme JavaScriptový označovač akordů. Zadáte mu text s akordy a on je zformátuje do příjemně čitelného HTML. Pro začátek si ukážeme, čeho bychom chtěli dosáhnout:

  • nahoře je HTML kód, dole je výsledek
  • vlevo je původní kód, vpravo je upravený
  • pro ukázky jsem se rozhodl použít text skladby Sraž nás na kolena od mé oblíbené kapely Škwor
ukázka

Tak se do toho pusťme. Začneme nadpisem. Ten vygenerujeme z hodnot atributů daného elementu. K získání elementů použijeme jQuery, já ji pro jednoduchost načtu z webu Google.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>

Vytvoříme si element s textem písničky, který budeme upravovat:

<div class="song" data-song-name="Sraž nás na kolena" data-band-name="Škwor">
R:
|G#m|Sraž nás na kolena
|H|výhružka s náma nic neudělá
tak|C#|dál konec svejch dnů
hle|G#m\dám
R
1.
Zkou|H\šej jít dál tou naší
duší|C#|závislou
nej|H\si v tom sám i ostatní v
tom s|C#|námi jsou
2.
Až|H|ke hvězdám jak silný
tady|C#|zůstanou
a|H|já se ptám co pro nás
bude|C#|záchranou
co pro nás bude záchranou
R
3.
Když|H|dojde nám
zlý časy se tu|C#|rýsujou
tu|H|sílu znám
a v mozku myši|C#|fízlujou
a v mozku myši fízlujou
-()-
R
R
</div>

K html souboru si připojíme 2 další soubory - code.js a styles.css Do souboru code.js vložíme:

$(function(){
        var songs = $('.song');
        for(var s = 0; s < songs.length; s++){
                var oldStr = songs.eq(s).text();
                var b = '';
                var songName = songs.eq(s).data('song-name'), bandName = songs.eq(s).data('band-name');
                b = '<span class="band-name">' + bandName + '&nbsp;&nbsp;-&nbsp;&nbsp;</span><span class="song-name">' + songName + '</span><br /><br />';
                songs.eq(s).html(b);
        }
});

Vše se samozřejmě provede při události document.ready.

var songs = $('.song');

Nám získá všechny elementy s písničkami, ty pak projedeme cyklem.

var oldStr = songs.eq(s).text();

Zde používáme metodu .eq(index), která nám vrací jQuery objekt. Pokud bychom použili .get(index), nebo [index], dostali bychom sice objekt s elementem z DOM, ale nemohli bychom na něm volat metody z jQuery (např .text(), apod.).

var songName = songs.eq(s).data('song-name'), bandName = songs.eq(s).data('band-name');

Tohle je získání dat z atributů. K tomu se obvykle používá metoda .attr(název), ale pokud je atribut zapsán ve tvaru data-něco, můžeme použít metodu **.data(název bez "data-").

Když stránku otevřeme. mělo by se nám vypsat tohle:

Škwor  -  Sraž nás na kolena

Jistě jste si všimli, že v kódu umisťuji vygenerovaný text do elementů span s nějakými třídami. Pojďme toho využít a nastylujme si ho v souboru styles.css:

.band-name
{
        color: #648;
        font-size: 2em;
        font-weight: bold;
}
.song-name
{
        color: #488;
        font-size: 1.5em;
        font-weight: bold;
}

Pokračujeme. Nyní si konečně napíšeme označování akordů:

var newStr = '';
var bool = false;
for(var i = 0; i < oldStr.length; i++)
{
        if((oldStr[i] == '|') || (oldStr[i] == '\\'))
        {
                if(bool)
                {
                        newStr += '</sup> ';
                }
                else
                        newStr += '<sup class="chord"> ';
                bool = !bool;
        }
        else if(oldStr[i] == '\n')
                newStr += '<br />';
        else
        {
                newStr += oldStr[i];
        }
}
if(bool)
        newStr += '</sup>';

Musíme ještě upravit kód vypisující výsledek:

b = '<span class="band-name">' + bandName + '&nbsp;&nbsp;-&nbsp;&nbsp;</span><span class="song-name">' + songName + '</span><br /><br />';
b += newStr;
songs.eq(s).html(b);

Projedeme všechny znaky v řetězci a v případě nalezení znaku '|' otevřeme (či uzavřeme) element sup, který se pro akordy skvěle hodí. Pokud objevíme ukončení řádku, nahradíme ho <br />. To proto, že prohlížeč přechody na nový řádek ignoruje. Podmínka na konci je tu pro případ, že by některý z akordů nebyl uzavřený.

Akordy si samozřejmě také nějak nastylujeme, stačí je barevně odlišit:

.chord
{
        color: #C66;
}

Co kdybychom ale chtěli akordy dočasně odstranit, aby byl text čitelnější? Nejlepší řešení bude tlačítko. Přidáme si tedy tlačítko, kterým akordy zneviditelníme: HTML:

<button id="hideTabs">schovat akordy</button>

CSS:

.hidden{
        display: none;
}

JavaScript:

var boolean = false;
$('#hideTabs').click(function(){
        if(boolean)
        {
                $('.chord').removeClass('hidden');
                $('#hideTabs').text('schovat akordy');
                boolean = false;
        }
        else
        {
                $('.chord').addClass('hidden');
                $('#hideTabs').text('zobrazit akordy');
                boolean = true;
        }
});

Můžete si vyzkoušet, že vše funguje. Jedna chyba se ale přeci jen najde. Pokud je akord uvnitř slova, zbude po něm při stisknutí tlačítka mezera. Právě proto jsou některé akordy (ty uvnitř slov) ukončené znakem '\' místo'|'. Podmínku if si tedy rozdělíme:

if(oldStr[i] == '|')
{
        if(bool)
        {
                newStr += '</sup> '; // mezera mimo element sup
        }
        else
                newStr += '<sup class="chord"> ';
        bool = !bool;
}
else if(oldStr[i] == '\\')
{
        if(bool)
        {
                newStr += ' </sup>'; // mezera uvnitř elementu sup
                bool = false;
        }
}

Problému jsme se zbavili. Další, co bychom mohli udělat, je seznam akordů v písničce. Kód tedy znovu rozšíříme:

var tabs = new Array(); // pole s akordy
for(var i = 0; i < oldStr.length; i++)
{
        if(oldStr[i] == '|')
        {
                if(bool)
                {
                        newStr += '</sup> ';
                        if(tabs.indexOf(b) == -1) // akord v poli není (každý má být v seznamu jen jednou)
                                tabs.push(b); // přidání
                        b = ''; // vyprázdnění řetězce
                }
                else
                        newStr += '<sup class="chord"> ';
                bool = !bool;
        }
        else if(oldStr[i] == '\\')
        {
                if(bool)
                {
                        newStr += ' </sup>';
                        if(tabs.indexOf(b) == -1) // akord v poli není (každý má být v seznamu jen jednou)
                                tabs.push(b); // přidání
                        b = '';
                        bool = false;
                }
        }
        else if(oldStr[i] == '\n')
                newStr += '<br />';
        else
        {
                if(bool)
                        b += oldStr[i];
                newStr += oldStr[i];
        }
}
if(bool)
        newStr += '</sup>';
b = '<span class="band-name">' + bandName + '&nbsp;&nbsp;-&nbsp;&nbsp;</span><span class="song-name">' + songName + '</span><br /><br />Akordy: <span class="chords">';
for(var i = 0; i < tabs.length; i++) // výpis akordů oddělených čárkami
        b += tabs[i] + ((i < tabs.length -1)?', ':'');
b += '</span>' + newStr + '<br /><br />';
songs.eq(s).html(b);

CSS:

.chords
{
        color: #C66;
        font-weight: bold;
}

Nakonec dopíšeme zvýraznění čísel slok, písmene R (refrén), r: (nahradíme za Rec:) a -()-, což se vypíše jako ~mezihra~. Tyto věci přidáme do procházení textu:

JS:

else if(oldStr[i] == 'R')
{// Refrén
        if((i < (oldStr.length - 2)) && (oldStr[i + 1] == ':') && (oldStr[i + 2] == '\n'))
        {
                newStr += '<br /><span class="verse">R:</span>';
                i++;
        }
        else if((i < (oldStr.length - 1)) && (oldStr[i + 1] == '\n'))
        {
                newStr += '<br /><span class="verse">R</span>';
        }
}
else if((oldStr[i] == 'r') && (i < (oldStr.length - 1)) && (oldStr[i + 1] == ':'))
{// Recitativ
        newStr += '<br /><span class="verse">Rec:</span>';
        i++;
}
else if((!isNaN(parseInt(oldStr[i]))) && (i < (oldStr.length - 1)) && (oldStr[i + 1] == '.'))
{// číslo sloky
        newStr += '<br /><span class="verse">' + oldStr[i] + '.</span>';
        i++;
}
else if((oldStr[i] == '-') && (i < (oldStr.length - 3)) && (oldStr[i + 1] == '(') && (oldStr[i + 2] == ')') && (oldStr[i + 3] == '-'))
{// mezihra
        newStr += '<br /><span class="verse">~mezihra~</span>';
        i += 3;
}

CSS:

.verse
{
        color: #44F;
        font-weight: bold;
}

A to by bylo vše, pokud vám něco nefunguje, zkuste se podívat do souborů na stažení, nebo se zeptejte v komentářích.


 

Stáhnout

Staženo 249x (2.06 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

  Aktivity (1)

Článek pro vás napsal Zdeněk Pavlátka
Avatar
Autor se věnuje spoustě zajímavých věcí :)

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 


Miniatura
Všechny články v sekci
JavaScript

 

 

Komentáře

Avatar
Michal Žůrek (misaz):

Hudebku moc nemusím, takže jestli to chápu dobře je to syntax highlighter pro nějaký hudební zápis?

Odpovědět 28.2.2014 21:26
Nesnáším {}, proto se jim vyhýbám.
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na Michal Žůrek (misaz)
Zdeněk Pavlátka:

Jde o akordy ke kytaře. Máš je vypsané nad textem, hraješ podle nich a zpíváš podle textu. Takže máš celkem pravdu. Je to lepší než zpěvníky (já na kytaru hraju, proto to původně vzniklo a nechtěl jsem si to nechávat pro sebe) .

Odpovědět  +1 1.3.2014 7:43
Kolik jazyků umíš, tolikrát jsi programátor.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.