React Hooks로 피아노 만들기
10207 단어 reactwebdevtutorialjavascript
최근 기사,
TypeScript for React developers in 2020
Building Real time API using graphql subscriptions
더 진행하기 전에 데모를 볼 것입니다.
피아노를 만들 때 고려해야 할 사항은,
하나씩 분해해보도록 하겠습니다. 먼저 버튼 클릭으로 오디오를 추가하여 애플리케이션에 반응하는 방법을 살펴보겠습니다.
우리는 반응 애플리케이션의 오디오에 sound font player이라는 라이브러리를 사용할 것입니다.
npx create-react-app piano-hooks
npm i soundfont-player
완료되면 오디오 플레이어 및 오디오 컨텍스트에 대해 다음 코드를 추가합니다.
오디오 컨텍스트에는 컨텍스트가 있고 오디오 플레이어에는 setInstrument 및 playNote라는 두 가지 메서드가 있습니다.
import SoundFontPlayer from "soundfont-player";
import AudioContext from "./AudioContext";
const NullSoundFontPlayerNoteAudio = {
stop() {}
};
const NullSoundFontPlayer = {
play() {
return NullSoundFontPlayerNoteAudio;
}
};
const AudioPlayer = () => {
//Audio Context
const audioContext = AudioContext && new AudioContext();
//soundPlayer
let soundPlayer = NullSoundFontPlayer;
//setInstrument
const Player = {
setInstrument(instrumentName) {
SoundFontPlayer.instrument(audioContext, instrumentName)
.then(soundfontPlayer => {
soundPlayer = soundfontPlayer;
})
.catch(e => {
soundPlayer = NullSoundFontPlayer;
});
},
playNote(note) {
soundPlayer.play(note);
}
};
return Player;
};
export default AudioPlayer;
AudioContext.js에는 다음이 포함됩니다.
export default window.AudioContext;
그런 다음 제대로 작동하는지 테스트하고 App.js에 다음 코드를 추가하십시오.
import React, { useEffect } from "react";
import "./App.css";
import AudioPlayer from "./core/AudioPlayer";
function App() {
const audioPlayer = AudioPlayer();
useEffect(() => {
audioPlayer.setInstrument("acoustic_grand_piano");
}, []);
const handleClick = () => {
audioPlayer.playNote("C4");
};
return (
<div className="app-container">
<button onClick={handleClick}>Play</button>
</div>
);
}
export default App;
기본적으로 클릭하면 음을 재생하는 버튼이 있습니다. 여기에서 useEffect는 모든 구성 요소 마운트에서 실행되고 계측기를 이름으로 설정합니다.
키보드 - 렌더 소품
악기에서 렌더 소품 개념을 사용해 봅시다. 렌더 소품에 익숙하지 않은 경우 이 course를 확인하십시오.
주로 Instrument에는 두 가지 중요한 부분이 있습니다. Instrument 자체와 instrumentAudio입니다.
먼저 instrumentAudio를 설정하는 방법을 살펴보겠습니다. app.js 로직을 instrumentAudio로 옮길 것입니다.
InstrumentAudio.js 파일을 만들고 다음 코드를 추가합니다.
import React, { useEffect, useState } from "react";
import AudioPlayer from "./AudioPlayer";
const InstrumentAudio = ({ instrumentName, notes }) => {
const [instrumentPlayer, setInstrumentPlayer] = useState(null);
useEffect(() => {
setInstrumentPlayer(AudioPlayer());
}, []);
useEffect(() => {
if (instrumentPlayer) {
setInstrument();
playNotes();
}
}, [instrumentPlayer]);
useEffect(() => {
if (notes && notes.length > 0) {
playNotes();
}
}, [notes]);
const setInstrument = () => {
instrumentPlayer.setInstrument(instrumentName);
};
const playNotes = () => {
if (instrumentPlayer) {
instrumentPlayer.playNote(notes[0]);
}
};
return null;
};
export default InstrumentAudio;
여기에서 우리는 instrumentPlayer를 상태로 유지하고 있으므로 제어할 수 있습니다.
구성 요소가 먼저 마운트되면 setInstrument 메서드를 호출하여 이름으로 기기를 설정합니다.
그 후 notes props가 변경될 때마다 notes 종속성을 갖는 useEffect에 정의된 음을 재생합니다.
이제 Instrument 자체를 구현할 차례입니다. 악기는 소품으로 시작 음과 끝 음이 있습니다. 이를 기반으로 사이에 있는 모든 노트를 렌더링합니다.
import React, { Fragment } from "react";
import InstrumentAudio from "./Keyboard/InstrumentAudio";
import getNotesBetween from "./utils/getNotesBetween";
const Instrument = ({ instrumentName, startNote, endNote }) => {
const notes = getNotesBetween(startNote, endNote);
return (
<Fragment>
{notes.map(note => {
return <Fragment>Note is : {note}</Fragment>;
})}
<InstrumentAudio />
</Fragment>
);
};
export default Instrument;
여기에서 시작 음표와 끝 음표 사이의 모든 음표를 얻습니다. notes.js라는 파일을 만들고 다음 코드를 추가합니다.
const TONES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
const OCTAVE_NUMBERS = [1, 2, 3, 4, 5, 6, 7];
export default OCTAVE_NUMBERS.reduce((notes, octaveNumber) => {
const notesInOctave = TONES.map(tone => `${tone}${octaveNumber}`);
return [...notes, ...notesInOctave];
}, []);
그런 다음 getNotesBetween.js 파일을 만들어 시작 노트와 끝 노트 사이의 모든 노트를 가져옵니다.
import NOTES from "../constants/note";
export default function getNotesBetween(startNote, endNote) {
const startingIndex = NOTES.indexOf(startNote);
const endingIndex = NOTES.indexOf(endNote);
return NOTES.slice(startingIndex, endingIndex + 1);
}
이제 Instrument.js에 악기와 상태 노트를 추가할 시간입니다.
import React, { Fragment, useState } from "react";
import InstrumentAudio from "./Keyboard/InstrumentAudio";
import getNotesBetween from "./utils/getNotesBetween";
import isAccidentalNote from "./utils/isAccidentalNote";
const Instrument = ({
instrumentName,
startNote,
endNote,
renderPianoKey,
keyboardMap
}) => {
const notes = getNotesBetween(startNote, endNote);
const [state, setState] = useState({
notesPlaying: []
});
const onPlayNoteStart = note => {
setState({ ...state, notesPlaying: [...state.notesPlaying, note] });
};
const onPlayNoteEnd = note => {
setState({
...state,
notesPlaying: state.notesPlaying.filter(
notePlaying => notePlaying !== note
)
});
};
return (
<Fragment>
{notes.map(note => {
return (
<Fragment key={note}>
{renderPianoKey({
note,
isAccidentalNote: isAccidentalNote(note),
isNotePlaying: state.notesPlaying.includes(note),
startPlayingNote: () => onPlayNoteStart(note),
stopPlayingNote: () => onPlayNoteEnd(note),
keyboardShortcut: getKeyboardShortcutsForNote(keyboardMap, note)
})}
</Fragment>
);
})}
<InstrumentAudio
instrumentName={instrumentName}
notes={state.notesPlaying}
/>
</Fragment>
);
};
export default Instrument;
여기서 논리는 renderPianoKey는 Instrument Component의 상태를 가진 렌더링 소품입니다.
isAccidentalNote는 메모가 자연 키인지 또는 accidental 키인지 확인합니다.
isAccidentalNote.js
import NOTES from '../constants/note'
export default (note) => {
return NOTES.includes(note) && note.includes('#')
}
isNotePlaying은 음표가 음표를 연주하는 상태인지 여부를 확인합니다.
사용자가 버튼을 클릭하면 startPlayingNote 메서드가 호출되고 호출되면 특정 메모를 상태에 추가합니다.
stopPlayingNote에서 상태에서 메모를 제거합니다.
마지막으로 키보드 동작을 처리하기 위해 keydown 및 keyup과 같은 키보드 동작을 추가합니다.
useEffect(() => {
window.addEventListener("keydown", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
}, []);
const handleKeyDown = e => {
if (isRegularKey(e) && !e.repeat) {
const note = getNoteFromKeyboardKey(e.key);
if (note) {
setState({ ...state, notesPlaying: [...state.notesPlaying, note] });
}
}
};
const handleKeyUp = e => {
if (isRegularKey(e) && !e.repeat) {
const note = getNoteFromKeyboardKey(e.key);
if (note) {
setState({
...state,
notesPlaying: state.notesPlaying.filter(
notePlaying => notePlaying !== note
)
});
}
}
};
피아노
악기는 렌더링 소품을 사용하기 때문입니다. Piano.js 파일에서 악기 구성 요소를 전달해야 합니다.
여기에는 해당 메서드에서 모든 인수를 가져오는 renderPianoKey 함수가 있습니다. 우발적인 메모인 경우 우발적인 키 구성 요소를 렌더링합니다.
자연 키 노트인 경우 자연 키 구성 요소를 렌더링합니다. 또한 각 키가 피아노 음표와 매핑되는 키보드 맵을 제공해야 합니다.
완전한 소스code
Demo
Reference
이 문제에 관하여(React Hooks로 피아노 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ganeshmani/building-a-piano-with-react-hooks-3mih텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)