Chapter 35: Play Drums using Lightning Web Component

Play drums using Lightning Web Component. In this article we we learn some new concepts in LWC with some interesting example.

Are you ready ? Let’s Begin !

 

 

playDrums.html

<template>
    <main>
      <section class="main-wrapper">
        <div class="key-map-wrapper">
          <h2>Key Mapping</h2>
          <ul class="key-map-list">
              <template for:each={SOUND_KEYS}  for:item="currentItem">
                  <li key={currentItem.code}>
                      <kbd class="key-code" >{currentItem.code}</kbd>
                      <span class="key-sound">{currentItem.sound}</span>
                  </li>
               </template>
          </ul>
        </div>
        <h1 class="main-title"> Play drums using <br/>Lightning Web Component</h1>
        <div class="drum-kit-wrapper">
          <img class="crash-ride crash-cymbal" ontransitionend={removeCrashRideTransition} src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/img/crash.png" alt="Crash cymbal">
          <img class="hihat-top hihat-top-cymbal" ontransitionend={removeHiHatTopTransition} src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/img/hihat-top.png" alt="Hi Hat cymbal">
          <!-- https://theasciicode.com.ar/  adding ascii on div using data-key -->
          <template for:each={DRUM_KEYS}  for:item="currentItem">
                  <div key= {currentItem.key} data-key={currentItem.key} ontransitionend={removeKeyTransition} class={currentItem.class}>
                      <kbd>{currentItem.kbd}</kbd>
                  </div>
          </template>
          <img class="drum-kit" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/img/drum-kit.png" alt="Drum Kit" />
        </div>
      </section>
    </main>
    <!-- one audio for one div-->
     <template for:each={SOUNDS}  for:item="currentItem">
         <audio key={currentItem.key} data-key={currentItem.key} src={currentItem.url}></audio>
     </template>
  </template>

playDrums.css

html,body {
	padding: 0;
	margin: 0;
	background-color: #fff;
}

.main-wrapper {
	margin: 30px auto 0;
	width: 1080px;
	text-align: center;
}

.main-title {
	font-family: 'Pacifico', cursive;
	text-align: center;
	font-size: 3.2em;
	color: #cb2026;
    text-shadow: 1px 1px 1px #5a0b0d;
    padding-bottom: 50px;
}

.drum-kit-wrapper {
	position: relative;
	width: 600px;
	margin: -100px auto 0;
}

.drum-kit {
	width: 100%;
	height: 520px;
	position: relative;
}

.crash-cymbal {
	position: absolute;
	top: 114px;
    left: 80px;
    transform: rotate(-7.2deg) scale(1.5);
    transition: all ease-in-out .042s;
}

.hihat-top-cymbal {
	position: absolute;
    top: 166px;
    right: 71px;
    transform: scale(1.35);
    z-index: 0;
    transition: all ease-in-out .042s;
}

.key {
	display: inline-block;
	transition: all ease-in-out .042s;
	position: absolute;
	background: #eaeaea;
    font-size: 1.5em;
    height: 32px;
    width: 32px;
    text-align: center;
    border-radius: 4px;
    border: 3px solid #aaa;
    color: #444;
    box-shadow: 1px 1px 1px rgba(0,0,0,.65);
    z-index: 2;
}

.key.kick {
	top: 355px;
    right: 250px;
}

.key.kick2 {
    top: 355px;
    right: 308px;
}

.key.snare {
	right: 145px;
    top: 280px;
}

.key.tom-high {
	right: 227px;
    top: 240px;
}

.key.tom-mid {
	left: 222px;
    top: 220px;
}

.key.tom-low {
	top: 320px;
    left: 133px;
}

.key.crash {
	top: 80px;
    left: 75px;
}

.key.ride {
	left: 165px;
    top: 87px;
}

.key.hihat-open {
	right: 165px;
    top: 144px;
}

.key.hihat-close {
	right: 60px;
    top: 150px;
}

.playing {
	transform: scale(1.12);
}

.key-map-wrapper {
	position: absolute;
    right: 0;
    top: 0;
    height: 700px;
    background: #111;
    width: 250px;
    z-index: 3;
}

.key-map-wrapper > h2 {
	color: #fff;
	font-family: 'Handlee', cursive;
	margin-bottom: 35px;
	border-bottom: 1px solid #fff;
    padding-bottom: 20px;
}

.key-map-list {
	list-style: none;
	color: #fff;
	text-align: left;
}

.key-map-list > li {
	margin-bottom: 25px;
}

.key-code {
	color: #444;
    background-color: #eaeaea;
    font-size: 1.25em;
    padding: 5px 10px;
    border-radius: 4px;
    border: 3px solid #aaa;
}

.key-sound {
	font-size: 1.2em;
	margin-left: 10px;
	font-family: 'Handlee', cursive;
	vertical-align: middle;
}

playDrums.js

import { LightningElement } from 'lwc';
const SOUNDS = [
    { key: "74", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/snare.wav"},
    { key: "66", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/kick.wav" },
    { key: "86", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/kick.wav" },
    { key: "72", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-high.wav" },
    { key: "71", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-mid.wav" },
    { key: "70", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-low.wav" },
    { key: "69", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/crash.wav" },
    { key: "82", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/ride.wav" },
    { key: "73", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/hihat-open.wav" },
    { key: "75", url:"https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/hihat-close.wav" }
  ]
const SOUND_KEYS = [{ "code": "E", "sound": "Crash" }, { "code": "R", "sound": "Ride" }, { "code": "F", "sound": "Floor tom" }, { "code": "G", "sound": "Mid tom" }, { "code": "H", "sound": "High tom" }, { "code": "V", "sound": "B" }, { "code": "J", "sound": "Snare" }, { "code": "I", "sound": "Hi-Hat Open" }, { "code": "K", "sound": "Hi-Hat Closed" }]
const DRUM_KEYS =
  [{ "key": "74", "class": "key snare", "kbd": "J" }, { "key": "66", "class": "key kick", "kbd": "B" }, { "key": "86", "class": "key kick2", "kbd": "V" }, { "key": "72", "class": "key tom-high", "kbd": "H" }, { "key": "71", "class": "key tom-mid", "kbd": "G" }, { "key": "70", "class": "key tom-low", "kbd": "F" }, { "key": "69", "class": "key crash", "kbd": "E" }, { "key": "82", "class": "key ride", "kbd": "R" }, { "key": "73", "class": "key hihat-open", "kbd": "I" }, { "key": "75", "class": "key hihat-close", "kbd": "K" }]

export default class App extends LightningElement {
    
playingClass = 'playing';
        SOUND_KEYS= SOUND_KEYS
        DRUM_KEYS = DRUM_KEYS
        SOUNDS = SOUNDS
    connectedCallback(){
         window.addEventListener('keydown', this.playSound);
    }


 playSound = e => {
  const keyCode = e.keyCode;
   console.log('keycode',keyCode);
  var keyElement = this.template.querySelector(`div[data-key="${keyCode}"]`);
  console.log('keyElement',keyElement);
  const audioElement = this.template.querySelector(`audio[data-key="${keyCode}"]`);

   audioElement.currentTime = 0;
  audioElement.play();

  switch(keyCode) {
    case 69:
    case 82:
      this.animateCrashOrRide();
      break;
    case 73:
    case 75:
      this.animateHiHatClosed();
      break;
  }

  keyElement.classList.add(this.playingClass);
};
animateCrashOrRide()  {
  console.log('inside animatedcrash ride');  
   this.template.querySelector('.crash-ride').style.transform = "rotate(0deg) scale(1.5)";

};

animateHiHatClosed() {
 console.log('inside animateHiHatClosed');
 this.template.querySelector('.hihat-top').style.top = "171px";
 //hiHatTop.style.top = '171px';
};

 removeCrashRideTransition = e =>  {
  console.log('inside removeCrashRideTransition');

  if(e.propertyName !== 'transform') return;

  e.target.style.transform = 'rotate(-7.2deg) scale(1.5)';
};

 removeHiHatTopTransition = e => {
  console.log('inside removeHiHatTopTransition');
  if(e.propertyName !== 'top') return;

  e.target.style.top = '166px';
};  

 removeKeyTransition = e => {
  console.log('inside removeKeyTransition');

  if(e.propertyName !== 'transform') return;

e.target.classList.remove(this.playingClass);
};


}

 

Did you enjoy this article?
Signup today and receive free updates straight in your inbox.
I agree to have my personal information transfered to MailChimp ( more information )
50% LikesVS
50% Dislikes