Back to Guitar School

In this example below you will see how to do a Back to Guitar School with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by steffenreichelt, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright steffenreichelt ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Back to Guitar School</title>
  
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <!-- Use A,S,D,F,G,H Keys to play the strings -->
<div>
  <div class="wrapper">
    <svg class="guitar string1" viewBox="0 0 102 891">
      <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
      </svg>
    <svg class="guitar string2" viewBox="0 0 102 891">
        <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
    </svg>
    <svg class="guitar string3" viewBox="0 0 102 891">
      <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
    </svg>
    <svg class="guitar string4" viewBox="0 0 102 891">
      <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
    </svg>
    <svg class="guitar string5" viewBox="0 0 102 891">
      <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
    </svg>
    <svg class="guitar string6" viewBox="0 0 102 891">
      <path d="M51,0c-0.163,297.036 -0.162,594.036 0,891" style="fill:none;stroke:#000;stroke-width:7px;" pathdata:idzero="M51,0c-0.163,297.036 -0.162,594.036 0,891" pathdata:idone="M51,0c-35.84,294.767 -35.857,591.766 0,891" pathdata:idtwo="M51,0c35.84,294.767 35.857,591.766 0,891" />
    </svg>
    </div>
  <a href="http://s-r.me/" target="_blank">by Steffen Reichelt</a>
</div>
  <script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.js'></script>
<script src='https://surikov.github.io/webaudiofontdata/sound/0241_JCLive_sf2_file.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/steffenreichelt/back-to-guitar-school-rzQWgo */
/*Use A,S,D,F,G,H Keys to play the strings 
  */
body{
  margin:0
}
.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
}

.guitar {
  height: 100vh;
  transition: filter 0.08s;
}

.playing {
  filter: blur(1vmin);
}

a,a:visited{
  position: absolute;
  right:0.66em;
  bottom:0.25em;
  color:black;
  text-decoration:none;
  font-family:"Trebuchet MS", Helvetica, sans-serif;
}

/*Downloaded from https://www.codeseek.co/steffenreichelt/back-to-guitar-school-rzQWgo */
var _stringIds;

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

//Use A,S,D,F,G,H Keys to play the strings 

var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContextFunc();
var player = new window.WebAudioFontPlayer();

var guitar1 = _tone_0241_JCLive_sf2_file;

var tones = { 'c': 0, 'c#': 1, 'd': 2, 'd#': 3, 'e': 4, 'f': 5, 'f#': 6, 'g': 7, 'g#': 8, 'a': 9, 'a#': 10, 'b': 11 };
var stringNames = ['string1', 'string2', 'string3', 'string4', 'string5', 'string6'];

var keysdown = {}; // Stores which keys are pressed
var stringEls = {};

var stringIds = (_stringIds = {}, _defineProperty(_stringIds, stringNames[5], { tone: 'e', octave: 4 }), _defineProperty(_stringIds, stringNames[4], { tone: 'b', octave: 3 }), _defineProperty(_stringIds, stringNames[3], { tone: 'g', octave: 3 }), _defineProperty(_stringIds, stringNames[2], { tone: 'd', octave: 3 }), _defineProperty(_stringIds, stringNames[1], { tone: 'a', octave: 2 }), _defineProperty(_stringIds, stringNames[0], { tone: 'e', octave: 2 }), _stringIds);

var keyboardStringMap = {
  'KeyA': stringNames[0],
  'KeyS': stringNames[1],
  'KeyD': stringNames[2],
  'KeyF': stringNames[3],
  'KeyG': stringNames[4],
  'KeyH': stringNames[5]
};

function startWaveTableNow(pitch) {
  player.queueWaveTable(audioContext, audioContext.destination, guitar1, audioContext.currentTime + 0, pitch, 0.4);
}

function getPitch(toneName, octave) {
  return tones[toneName] + Object.keys(tones).length * octave;
}

for (var key in stringIds) {
  stringIds[key].octave += 1;
  var pitch = getPitch(stringIds[key].tone, stringIds[key].octave);
  player.queueWaveTable(audioContext, audioContext.destination, guitar1, audioContext.currentTime + 0, pitch, 0.4);
}

var myTimelines = {};
var animTime = 15;

function getTimelineForString(stringId) {
  var tm = anime.timeline({
    loop: 5,
    autoplay: false,
    complete: function complete() {
      stringEls[stringId].parentNode.classList.remove('playing');
    }
  });
  tm.add({
    targets: stringEls[stringId],
    duration: animTime,
    d: stringEls[stringId].getAttribute('pathdata:idone'),
    easing: 'linear'
  });
  tm.add({
    targets: stringEls[stringId],
    duration: animTime,
    d: stringEls[stringId].getAttribute('pathdata:idzero'),
    easing: 'linear'
  });
  tm.add({
    targets: stringEls[stringId],
    duration: animTime,
    d: stringEls[stringId].getAttribute('pathdata:idtwo'),
    easing: 'linear'
  });
  tm.add({
    targets: stringEls[stringId],
    duration: animTime,
    d: stringEls[stringId].getAttribute('pathdata:idzero'),
    easing: 'linear'
  });

  return tm;
}

function triggerString(stringId) {
  var stringData = stringIds[stringId];
  stringEls[stringId].parentNode.classList.add('playing');
  if (!(stringId in myTimelines)) {
    myTimelines[stringId] = getTimelineForString(stringId);
  }

  var pitch = getPitch(stringData.tone, stringData.octave);
  startWaveTableNow(pitch);
  myTimelines[stringId].play();
}

function releaseString(stringId) {
  myTimelines[stringId].restart();
  myTimelines[stringId].pause();
  myTimelines[stringId].seek(0);
  stringEls[stringId].parentNode.classList.remove('playing');
}

function onKeyUp(event) {
  if (event.code in keyboardStringMap) {
    releaseString(keyboardStringMap[event.code]);
  }
  delete keysdown[event.key];
}

function onKeyDown(event) {
  if (event.key in keysdown) {
    return;
  }
  keysdown[event.key] = true;
  if (event.code in keyboardStringMap) {
    triggerString(keyboardStringMap[event.code]);
  }
}

for (var stringId in stringIds) {
  stringEls['' + stringId] = document.querySelector('.' + stringId + ' path');
}

window.addEventListener('keyup', onKeyUp);
window.addEventListener('keydown', onKeyDown);

Comments