让我们构建一个实际工作的数字鼓套件🥁你可以用键盘演奏⌨️🤘
组装套件
我该如何玩这个?
声音检查时间
总结
是的。我已经做了一把吉他,你可以在这里找到它:
现在还有一套鼓。我是不是灵感枯竭了?嗯,也不完全是。如果你想组建一支数字摇滚乐队,你需要的乐器肯定不止一件,对吧?而且这才是第二部分,所以你还可以期待更多。
不用多说,让我们回到仪器车间开始吧!
组装套件
一套鼓有很多部件。为了把它们全部拼凑起来,并让它们看起来更美观,我使用了一些线性渐变和一个径向渐变:
<defs>
<radialGradient id="head" fx="26%" fy="26%">
<stop offset="0%" style="stop-color:#f0ede6;" />
<stop offset="100%" style="stop-color:#f5e9c9;" />
</radialGradient>
<radialGradient id="case" fx="30%" fy="30%">
<stop offset="0%" style="stop-color:#82827f;" />
<stop offset="100%" style="stop-color:#6b6b64;" />
</radialGradient>
<linearGradient id="caseColor">
<stop offset="0%" style="stop-color:#6193ba;" />
<stop offset="20%" style="stop-color:#a8c9e3;" />
<stop offset="100%" style="stop-color:#6b6b64;" />
</linearGradient>
<linearGradient id="cymbal" gradientTransform="rotate(25)">
<stop offset="0%" style="stop-color:#ede58c;" />
<stop offset="30%" style="stop-color:#f2eec4;" />
<stop offset="60%" style="stop-color:#f2eec4;" />
<stop offset="100%" style="stop-color:#ede58c;" />
</linearGradient>
</defs>
然后我添加了鼓组的各个部分,即一个低音鼓(由一个圆圈组成)、一个小军鼓和三个通鼓(椭圆形 + 两条路径)、一个踩镲(两个椭圆形 + 一条路径)和一个镲片(一个椭圆形和一条路径)。
<!-- Hi-Tom -->
<path stroke-width="20" stroke="url(#case)" d="M 1000 700 1001 1200" fill="none" />
<path stroke-width="20" stroke="url(#case)" fill="url(#caseColor)" stroke-linejoin="round" d="
M 880 700
880 820
A 1000 1900 0 0 0 1120 820
L 1120 700 Z
" />
<ellipse id="hitom" fill="url(#head)" stroke-width="20" stroke="url(#case)" cx="1000" cy="700" rx="120" ry="20" />
<!-- Mid-Tom -->
<path stroke-width="20" stroke="url(#case)" d="M 1350 700 1351 1200" fill="none" />
<path stroke-width="20" stroke="url(#case)" fill="url(#caseColor)" stroke-linejoin="round" d="
M 1220 700
1220 860
A 1000 1900 0 0 0 1480 860
L 1480 700 Z
" />
<ellipse id="midtom" fill="url(#head)" stroke-width="20" stroke="url(#case)" cx="1350" cy="700" rx="130" ry="20" />
<!-- Bass drum -->
<circle id="bass" fill="url(#head)" cx="1200" cy="1200" r="270" stroke-width="20" stroke="url(#case)" />
<!-- Snare drum -->
<path stroke-width="20" stroke="url(#case)" d="M 900 910 901 1410 780 1460 M 901 1410 1020 1460" fill="none" />
<path stroke-width="20" stroke="url(#case)" fill="url(#caseColor)" stroke-linejoin="round" d="
M 710 900
710 1050
A 950 1700 0 0 0 1110 1050
L 1110 900 Z
" />
<ellipse id="snare" fill="url(#head)" stroke-width="20" stroke="url(#case)" cx="910" cy="900" rx="200" ry="50" />
<!-- Floor tom -->
<path stroke-width="20" stroke="url(#case)" d="M 1700 1200 1740 1480 M 1500 1200 1450 1480" fill="none" />
<path stroke-width="20" stroke="url(#case)" fill="url(#caseColor)" stroke-linejoin="round" d="
M 1380 1020
1380 1350
A 950 1700 0 0 0 1820 1350
L 1820 1020 Z
" />
<ellipse id="floortom" fill="url(#head)" stroke-width="20" stroke="url(#case)" cx="1600" cy="1020" rx="220" ry="60" />
<!-- Hihat -->
<path stroke-width="20" stroke="url(#case)" d="M 500 830 500 1410 580 1460 M 500 1410 430 1460" fill="none" />
<ellipse
cx="500" cy="830" rx="200" ry="40"
fill="url(#cymbal)" stroke="#222" stroke-width="1"
/>
<ellipse
id="hihat-head"
cx="500" cy="800" rx="200" ry="40"
fill="url(#cymbal)" stroke="#222" stroke-width="1"
/>
<!-- Crash -->
<path stroke-width="20" stroke="url(#case)" d="M 1850 600 1851 1410" fill="none" />
<ellipse
id="crash"
cx="1850" cy="600" rx="300" ry="50"
fill="url(#cymbal)" stroke="#222" stroke-width="1" transform="rotate(-15 1850 600)"
/>
结果如下:
实际上只缺少踏板,但当我用键盘弹奏所有东西时,我不需要它们,对吗?
我该如何玩这个?
我需要设计一些按键的模式。我希望它听起来像一套真正的架子鼓,所以我在键盘上复制了一套架子鼓的布局:
所以基本上
Hihat open: A
Hihat closed: Shift+A
Hi tom: F
Mid tom: J
Crash cymbal: O
Snare drum: B
Bass drum/kick: Space bar
在JS中,我给窗口添加了一个事件监听器,并分析了key
该事件的属性keydown
:
let isShiftPressed = false
const hihatHead = document.querySelector('#hihat-head')
const hitom = document.querySelector('#hitom')
const midtom = document.querySelector('#midtom')
const floortom = document.querySelector('#floortom')
const snare = document.querySelector('#snare')
const crash = document.querySelector('#crash')
const bass = document.querySelector('#bass')
/**
* Finds out which drum was played.
* @param key
* @returns {string|null}
*/
const getInstrument = key => {
switch (key.toLowerCase()) {
case 'a':
return hihatHead
case 'f':
return hitom
case 'j':
return midtom
case 'l':
return floortom
case 'b':
return snare
case 'o':
return crash
case ' ':
return bass
}
return null
}
window.addEventListener('keydown', e => {
if (e.key === 'Shift') {
isShiftPressed = true
return
}
const drum = getInstrument(e.key)
if (drum === null) {
return
}
// ...
})
window.addEventListener('keyup', e => {
if (e.key === 'Shift') {
isShiftPressed = false
// ...
}
})
接下来,我添加一些动画来提供视觉反馈。我为此使用了一些 CSS 类,这些类会在超时后立即删除。这样,当我clearTimeout
快速敲鼓时就不会出现奇怪的行为了:
#hihat-head.closed {
transform: translateY(10px);
}
.played {
transform: translateY(5px);
}
#bass.played {
transform: scale(0.98);
transform-origin: 1200px 1200px;
}
#crash.played {
fill: url(#cymbal);
transform: rotate(-20deg);
transform-origin: 1850px 600px;
}
#hihat-head.played {
fill: url(#cymbal);
transform: rotate(5deg);
transform-origin: 500px 830px;
}
添加和删除类:
const timeouts = new Map()
window.addEventListener('keydown', e => {
if (e.key === 'Shift') {
isShiftPressed = true
hihatHead.classList.add('closed')
return
}
const drum = getInstrument(e.key)
if (!drum) {
return
}
drum.classList.add('played')
if (timeouts.has(drum)) {
clearTimeout(timeouts.get(drum))
}
timeouts.set(drum, setTimeout(() => {
drum.classList.remove('played')
}, 100))
})
window.addEventListener('keyup', e => {
if (e.key === 'Shift') {
isShiftPressed = false
hihatHead.classList.remove('closed')
}
})
现在演奏一段(无声)鼓独奏:
声音检查时间
我将使用 midi 字体,就像吉他一样,但是有所不同:github.com/johntu/midi-js-gm1-percussion README 告诉我哪个音符/mp3 文件对应哪个鼓,所以我创建了另一个地图:
const sounds = new Map()
sounds.set(hihatHead, {
open: new Audio('./sound/Bb2.mp3'),
closed: new Audio('./sound/Gb2.mp3'),
})
sounds.set(hitom, new Audio('./sound/D3.mp3'))
sounds.set(midtom, new Audio('./sound/B2.mp3'))
sounds.set(floortom, new Audio('./sound/G2.mp3'))
sounds.set(snare, new Audio('./sound/D2.mp3'))
sounds.set(crash, new Audio('./sound/Db3.mp3'))
sounds.set(bass, new Audio('./sound/C2.mp3'))
现在我可以调整事件监听器来实际播放声音:
window.addEventListener('keydown', e => {
// ...
const drum = getInstrument(e.key)
// ...
let sound = sounds.get(drum)
if (drum === hihatHead) {
sound = isShiftPressed ? sound.closed : sound.open
}
const audio = new Audio('./sound/' + sound + '.mp3')
audio.play()
const drum = getInstrument(e.key);
// ..
let sound = sounds.get(drum);
if (drum === hihatHead) {
sound = isShiftPressed ? sound.closed : sound.open;
}
sound.pause();
sound.currentTime = 0;
sound.play();
// ...
})
就是这样!一套可以和吉他一起演奏的鼓组就做好了!这里有一个现场演示供你演奏:
总结
现在我已经掌握了SVG乐器制作的技巧,做这个的速度快了很多。不过,做这个的过程我还是挺开心的。如果你喜欢,可以录下你最棒的独奏,并在简介里放上视频链接!
在本系列的下一篇文章中,我将连接这两种乐器,以便您最终可以组建自己的数字摇滚乐队!
希望你喜欢阅读这篇文章,就像我喜欢写它一样!如果喜欢,请留下❤️或🦄 !我空闲时间会写科技文章,偶尔也喜欢喝咖啡。
如果您想支持我的努力, 请给我买杯咖啡☕ 或 在 Twitter 上关注我🐦 !
鏂囩珷鏉yu簮锛�https://dev.to/thormeier/let-s-build-an-actual-working-digital-drum-kit-you-can-play-with-your-keyboard-2neh