J'ai une application de graphique d'accords que j'ai écrite et je voudrais permettre aux utilisateurs de transposer la clé du graphique à l'aide d'un gestionnaire onClick.

Mon graphique ressemble à ceci

{C}My name is Blanket, {F}And I can run fast

Les cordes à l'intérieur des parenthèses apparaissent au-dessus de la lettre qu'elle précède.

Je voudrais utiliser javascript ou jquery pour ce faire. Comment pourrais-je créer ce bouton de transposition? Toute aide est appréciée. Merci d'avance.

MODIFIER

Voici donc ce que j'ai trouvé ...

$('.transposeUp').click(function(){
    $('.chord').each(function(){
        var currentChord = $(this).text(); // gathers the chord being used
        if(currentChord == $(this).text()){
        var chord = $(this).text().replace("F#", "G")
        }
        //... the if statements continue though every chord
        //but I didn't place them here to save space
    });
});

Voici donc le problème ...

J'ai un accord de barre oblique dans le mixage (G / B), cela change la transposition mais parce que ça change le "B", l'accord est maintenant (G / C) qui n'est pas le même que le "currentChord" donc ça ne marche pas ne changez pas le G quand il atteint sa condition if respective. Jusqu'à ce que j'aie suffisamment transposé là où l'accord est finalement (G / G), alors le premier "G" commence à transposer en laissant le dernier "G" inchangé. Des idées? Encore une fois, vos connaissances et votre aide sont grandement appréciées. Merci d'avance.

3
Juan Gonzales 29 sept. 2011 à 00:43

3 réponses

Meilleure réponse

Vous devez faire correspondre les accords de manière séquentielle afin de pouvoir les mettre à jour un par un. Si vous essayez de tout faire correspondre à la fois, vous rencontrerez des problèmes comme vous l'avez décrit, car vous continuez à faire correspondre le même accord encore et encore.

Un bon moyen d'y parvenir serait d'utiliser des expressions régulières pour analyser et diviser l'accord. Une fois que vous avez les valeurs d'accord correspondantes, utilisez un tableau d'accords pour trouver l'accord suivant / précédent à transposer. Voici un exemple de code que j'ai développé en démo:

<p><span class="chord">{C}</span>My name is Blanket,</p>
<p><span class="chord">{G / B}</span>And I can run fast</p>

<p>
<input id="transposeDown" type="button" value="Down" /> |
<input id="transposeUp" type="button" value="Up" />
</p>

var match;
var chords =
    ['C','C#','D','Eb','E','F','F#','G','Ab','A','Bb','B','C',
     'Db','D','D#','E','F','Gb','G','G#','A','A#','C'];
var chordRegex = /C#|D#|F#|G#|A#|Db|Eb|Gb|Ab|Bb|C|D|E|F|G|A|B/g;

$('#transposeUp').click(function() {
    $('.chord').each(function() {
        var currentChord = $(this).text();
        var output = "";
        var parts = currentChord.split(chordRegex);
        var index = 0;
        while (match = chordRegex.exec(currentChord))
        {
            var chordIndex = chords.indexOf(match[0]);
            output += parts[index++] + chords[chordIndex+1];
        }
        output += parts[index];
        $(this).text(output);
    });
});

$('#transposeDown').click(function() {
    $('.chord').each(function() {
        var currentChord = $(this).text();
        var output = "";
        var parts = currentChord.split(chordRegex);
        var index = 0;
        while (match = chordRegex.exec(currentChord))
        {
            var chordIndex = chords.indexOf(match[0],1);
            output += parts[index++] + chords[chordIndex-1];
        }
        output += parts[index];
        $(this).text(output);
    });
});

Exemple de démonstration: http://jsfiddle.net/4kYQZ/2/

Quelques points à noter:

  1. J'ai pris l'idée de @ gregp d'avoir plusieurs copies de la liste des clés pour pouvoir gérer les objets tranchants et plats. La première échelle comprend le # / b préféré qui sera utilisé lors de la transposition. La deuxième échelle inclut les autres formats afin que si la musique les inclut, ils se transposeront correctement. Par exemple, puisque Eb est dans la première échelle, il sera utilisé à la place de D # pendant que vous transposez de haut en bas; cependant, s'il y a un D # dans la musique pour commencer, il se déplacera correctement en D / E (avec la mise en garde que si vous reculez, il redeviendra un Eb). N'hésitez pas à modifier l'échelle préférée - j'ai utilisé mon jugement éduqué basé sur l'expérience musicale personnelle.
  2. L'expression régulière doit d'abord avoir les clés aiguisées / aplaties, sinon un C# serait tout aussi facilement mis en correspondance qu'un C quand ce n'est pas correct.
  3. J'ai C au début et à la fin du tableau afin que je puisse commencer à n'importe quel endroit et déplacer les deux directions sans dépasser la fin du tableau. Pour que cela fonctionne, le code transposeDown a un paramètre supplémentaire dans l'appel à chords.indexOf pour commencer à la position 1 afin qu'il corresponde au dernier C du tableau au lieu du premier C . Puis, lorsqu'il tente de passer à l'élément précédent, il ne passe pas le début du tableau.
  4. Je divise également l'accord en utilisant l'expression régulière, qui est redondante, mais il est très facile de recomposer la chaîne finale - en entrelaçant les parties de la chaîne d'origine avec les touches d'accord mises à jour (n'oubliez pas la dernière pièce à la fin!).
  5. J'utilise des éléments au lieu de classes pour vos boutons.

J'espère que cela t'aides!


Mise à jour 1: Par commentaire de OP, l'utilisation de indexOf sur les tableaux n'est pas prise en charge par pre-ie9. Cela peut être résolu en utilisant une fonction d'assistance qui fait la même chose:

function arrayIndexOf(arr, match)
{
    for (var i = 0; i < arr.length; i++)
        if (arr[i] == match)
            return i;
    return -1;
}

Et cette ligne

var chordIndex = chords.indexOf(match[0]);

Serait remplacé par:

var chordIndex = arrayIndexOf(chords, match[0]);

Voir l'exemple de démonstration mis à jour: http://jsfiddle.net/4kYQZ/11/

3
mellamokb 16 janv. 2012 à 15:37

Fonction d'appel transposée vers le haut:

text = transpose(text, 1);

Fonction d'appel transposée vers le bas:

text = transpose(text, -1);

Une fonction:

function transpose(text, amount){
   var lines = new Array();
   var chord = new Array();
   var scale =  ["C","Cb","C#","D","Db","D#","E","Eb","E#","F","Fb","F#","G","Gb","G#",
                 "A","Ab","A#","B","Bb","B#"];
   var transp = ["Cb","C","C#","Bb","Cb","C","C","C#","D","Db","D","D#","C","Db","D",
                 "D","D#","E","Eb","E","F","D","Eb","E","E","E#","F#","E","F","F#", 
                 "Eb","Fb","F","F","F#","G","Gb","G","G#","F","Gb","G","G","G#","A", 
                 "Ab","A","A#", "G","Ab","A","A","A#","B","Bb","B","C","A","Bb","B",
                 "B","B#","C#"];
  var inter = '';
  var mat = '';
  lines = text.split("\n");
  for(var i in lines){
      if(i%2===0){
         chord = lines[i].split(" ");
         for(var x in chord){
             if(chord[x]!==""){
               inter = chord[x];
               var subst = inter.match(/[^b#][#b]?/g);
               for(var ax in subst){
                   if(scale.indexOf(subst[ax])!==-1){
                      if(amount>0){
                         for(ix=0;ix<amount;ix++){
                             var pos = scale.indexOf(subst[ax]);
                             var transpos = 3*pos-2+3;
                             subst[ax] = transp[transpos+1];
                         }
                      }
                      if(amount<0){
                         for(ix=0;ix>amount;ix--){
                             var pos = scale.indexOf(subst[ax]);
                             var transpos = 3*pos-2+3;
                             subst[ax] = transp[transpos-1];
                            }
                     }
                  } 
               }
               chord[x]=subst.join("");
           }
        }
       lines[i] = chord.join(" ");
    }
  }
  return lines.join("\n");
}

La première ligne est transposée et la seconde non, et séquentiellement.

1
user2813440 25 sept. 2013 à 03:20

En utilisant jQuery, vous avez l'embarras du choix pour les gestionnaires de clic de liaison. Il y a .click (), .delegate (), .live () et bien d'autres. Il ne serait pas logique de reproduire ce que les API vous disent déjà, mais je peux dire ceci: apprendre à lier le clic est la plus petite partie du problème global, et même capturer le nom de l'accord avec .text () va être trivial une fois que vous avez jeté un œil à l'API jQuery.

La partie délicate va être la logique de transposition. Vous devrez prendre les connaissances que vous avez déjà (par exemple, passer de E à F n'est qu'une demi-étape; il n'y a pas E # ou Fb) et le faire fonctionner comme du code.

Mes excuses pour des conseils généraux plutôt que des exemples de code, mais mon conseil est d'avoir deux tableaux, un contenant tous les accords en termes de dièses, un avec tous les accords en termes d'appartements.

Vous pouvez aussi faire un peu de triche: au lieu de la logique pour revenir au début (disons, C en position 0), faites simplement dupliquer vos tableaux:

["C", "C #", "D", "D #", "E", "F", "F #", "G", "G #", "A", "B", "C", " C # "," D "," D # "," E "," F "," F # "," G "," G # "," A "," B "]

Trouvez ensuite la première occurrence du nom de l'accord, avancez du nombre d'arrêts souhaité et vous aurez toujours la bonne chaîne.

3
Greg Pettit 28 sept. 2011 à 21:41