Day01 是實作用鍵盤模擬打鼓的題目,當使用者按下對應的按鍵,就會播放對應的鼓聲,以下就讓我們來製作 React 的版本ㄅ (之後每天的示範樣式都會使用 TailwindCSS)
drumMap
,用來存放每個按鍵對應的聲音檔名:const drumMap = [
{ key: "A", code: 65, sound: "clap" },
{ key: "S", code: 83, sound: "hihat" },
{ key: "D", code: 68, sound: "kick" },
{ key: "F", code: 70, sound: "openhat" },
{ key: "G", code: 71, sound: "boom" },
{ key: "H", code: 72, sound: "ride" },
{ key: "J", code: 74, sound: "snare" },
{ key: "K", code: 75, sound: "tom" },
{ key: "L", code: 76, sound: "tink" },
];
onKeyDown
和 tabIndex
屬性,來讓元素聚焦並處理鍵盤事件。當使用者按下按鍵時,handleKeyDown
函式會被觸發:const handleKeyDown = (e: { key: string }) => {
const targetKey = drumMap.find((drum) => drum.key === e.key.toUpperCase());
if (!targetKey) {
return;
}
playDrum(targetKey);
};
useState
來管理目前按下的按鍵,同時用來處理讓畫面有亮燈的效果。當使用者點擊或按下對應的按鍵時,playDrum
函式會被觸發,播放對應的鼓聲:const [activeKey, setActiveKey] = useState<string>("");
const playDrum = (targetKey: { key: string; sound: string }) => {
const audio = new Audio(
`https://github.com/wesbos/JavaScript30/raw/master/01%20-%20JavaScript%20Drum%20Kit/sounds/${targetKey.sound}.wav`
);
audio.currentTime = 0;
audio.play();
setActiveKey(targetKey.key);
};
const handleClear = () => {
setActiveKey("");
};
return (
<main className="bg-[url('https://raw.githubusercontent.com/wesbos/JavaScript30/master/01%20-%20JavaScript%20Drum%20Kit/background.jpg')] bg-cover bg-center h-screen w-full">
<div
className="flex flex-wrap justify-center items-center min-h-screen gap-2"
tabIndex={0}
onKeyDown={handleKeyDown}
onKeyUp={handleClear}
>
{drumMap.map((drum) => (
<div
key={drum.key}
onClick={() => playDrum(drum)}
onMouseLeave={handleClear}
className={`${
activeKey === drum.key
? "border-yellow-500 shadow-2xl transform scale-110"
: "border-black"
} w-20 h-20 flex flex-col justify-center items-center bg-black bg-opacity-60 text-white rounded-lg border-4 transition-all hover:border-yellow-500 hover:shadow-2xl hover:transform hover:scale-110 hover:cursor-pointer`}
>
<kbd className="text-2xl">{drum.key}</kbd>
<p className="text-sm text-yellow-500">
{drum.sound.toUpperCase()}
</p>
</div>
))}
</div>
</main>
);
使用 new Audio()
建立聲音物件
設定 audio.currentTime = 0
可以讓聲音從頭播放
利用 onKeyDown
、onKeyUp
、onMouseLeave
等事件來處理使用者互動
在 TailwindCSS 中,可以使用 bg-[url('...')]
的語法來設定背景圖片
bg-[url('https://raw.githubusercontent.com/wesbos/JavaScript30/master/01%20-%20JavaScript%20Drum%20Kit/background.jpg')]