Drumpad Component
import PubSub from 'pubsub-js';
import React,{useState,useEffect,useRef} from 'react';
import {bankOne,bankTwo} from './Bank.js';
import './Drumpad.scss';
const Drumpad = () =>{
const [bank,setBank] = useState(bankOne);
const [isPowered, setIsPowered] = useState(false);
const [soundName, setSoundName] = useState("");
useEffect(
()=>{
const mySub = PubSub.subscribe('changeBank',chooseBank);
const mySecondSub = PubSub.subscribe('powerStatus',changePowerStatus);
return () => {
PubSub.unsubscribe(mySub);
PubSub.unsubscribe(mySecondSub);
};
},[]
);
document.addEventListener('keydown', handleKeyPress);
const chooseBank = (changeBank,{bankName}) => {
bankName === 'Heater 1' ? setBank(bankOne) : setBank(bankTwo);
};
console.log(isPowered);
const changePowerStatus = (powerStatus,{isOn}) =>{
setIsPowered (isOn);
}
const handleClick = (event) => {
if(isPowered){
const audio = event.target.children[0];
audio.play();
audio.currentTime=0;
const name = event.target.id;
setSoundName(name);
pubInfo();
}
};
function handleKeyPress(event) {
const key = event.key.toUpperCase();
console.log(isPowered);
if ("QWEASDZXC".includes(key) && isPowered) {
document.getElementById(key).play();
document.getElementById(key).currentTime = 0;
const name = document.getElementById(key).parentElement.id;
setSoundName(name);
pubInfo();
};
};
const pubInfo = () =>{
PubSub.publish("updateInfo",{soundName});
}
return bank.map(sound =>{
return <li key={sound.keyTrigger} className="Key">
<button className="drum-pad" id={sound.id} onClick={handleClick}>
<audio className="clip" id={sound.keyTrigger} src={sound.url}/>
{sound.keyTrigger}
</button>
</li>
})
}
export default Drumpad;
DrumControl Component
import PubSub from 'pubsub-js';
import React,{useState,useEffect} from 'react';
import './DrumControl.scss';
import { Switch } from 'antd';
import 'antd/dist/antd.css';
const DrumControl = () => {
const [isOn,setIsOn] = useState(false);
const [bankName,setBankName] = useState("Heater 1");
const [info,setInfo] = useState("");
useEffect(
()=> {
pubPower();
const myInfo = PubSub.subscribe("updateInfo",soundNameUpdate);
return () => {
PubSub.unsubscribe(myInfo);
};
}
);
const soundNameUpdate = (updateInfo,{soundName}) =>{
setInfo(soundName);
}
const onOff = () =>{
isOn ? setIsOn(false) : setIsOn(true);
setInfo("");
}
const changeBankName = ()=>{
bankName === "Heater 1" ? setBankName("Piano") : setBankName("Heater 1");
setInfo(bankName);
pubBank();
}
const pubBank = () =>{
PubSub.publish('changeBank',{bankName});
}
const pubPower = () =>{
PubSub.publish('powerStatus',{isOn});
}
const onclick = () =>{
isOn ? changeBankName() : setInfo("");
}
return (
<div className="drum-control">
<header>
<a className="navbar-brand text-dark" href="#">
Sean Liu
</a>
</header>
<p className="text-dark fw-bold">Power</p>
<Switch onClick={onOff}/>
<p id="display">{info}</p>
<input type="range" className="form-range" min="0" max="100" id="volume-control"/>
<p className="text-dark fw-bold">Bank</p>
<Switch onClick={onclick}/>
</div>
);
}
export default DrumControl;
App.js
import './App.scss';
import DrumControl from './components/DrumControl';
import Drumpad from './components/Drumpad';
function App() {
return (
<div className="App">
<div className="App-content" id="drum-machine">
<div className="drum-keys">
<Drumpad />
</div>
<DrumControl />
</div>
</div>
);
}
export default App;
A really fun project, Finally sort out most questions, but now I am stuck at one bug, once I press one key it will return multiple times console log, and it makes my display not accurate. Please help