likes
comments
collection
share

一个简单小demo:键盘打击乐

作者站长头像
站长
· 阅读数 38

前言

好久没有写好玩的小demo了,今天来实现一个敲击键盘的打击乐小demo,具体效果如下。

一个简单小demo:键盘打击乐

代码实现原理其实很简单,给每个键盘绑定一个audio,当用户敲击键盘时,我们能够拿到一个keyCode,通过给键盘设置data-key,再写一个简单函数实现音乐播放。

下面我们直接上代码,并讲解其中一些主要的注意点。

HTML代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HTML5商业化开发细节</title>
  <link rel="stylesheet" href="./common.css">
  <script src="./index.js"></script>
</head>

<body>
  <div class="keys">
    <div class="keys1">
      <div class="key" data-key="81">
        <div>Q</div>
        <span class="sound">clap</span>
      </div>
      <div class="key" data-key="87">
        <div>W</div>
        <span class="sound">hihat</span>
      </div>
      <div class="key" data-key="69">
        <div>E</div>
        <span class="sound">kick</span>
      </div>
      <div class="key" data-key="82">
        <div>R</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="84">
        <div>T</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="89">
        <div>Y</div>
        <span class="sound">ride</span>
      </div>
      <div class="key" data-key="85">
        <div>U</div>
        <span class="sound">snare</span>
      </div>
      <div class="key" data-key="73">
        <div>I</div>
        <span class="sound">tom</span>
      </div>
      <div class="key" data-key="79">
        <div>O</div>
        <span class="sound">tink</span>
      </div>
      <div class="key" data-key="80">
        <div>P</div>
        <span class="sound">tink</span>
      </div>
    </div>
    <div class="keys2">
      <div class="key" data-key="65">
        <div>A</div>
        <span class="sound">clap</span>
      </div>
      <div class="key" data-key="83">
        <div>S</div>
        <span class="sound">hihat</span>
      </div>
      <div class="key" data-key="68">
        <div>D</div>
        <span class="sound">kick</span>
      </div>
      <div class="key" data-key="70">
        <div>F</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="71">
        <div>G</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="72">
        <div>H</div>
        <span class="sound">ride</span>
      </div>
      <div class="key" data-key="74">
        <div>J</div>
        <span class="sound">snare</span>
      </div>
      <div class="key" data-key="75">
        <div>K</div>
        <span class="sound">tom</span>
      </div>
      <div class="key" data-key="76">
        <div>L</div>
        <span class="sound">tink</span>
      </div>
    </div>
    <div class="keys3">
      <div class="key" data-key="90">
        <div>Z</div>
        <span class="sound">clap</span>
      </div>
      <div class="key" data-key="88">
        <div>X</div>
        <span class="sound">hihat</span>
      </div>
      <div class="key" data-key="67">
        <div>C</div>
        <span class="sound">kick</span>
      </div>
      <div class="key" data-key="86">
        <div>V</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="66">
        <div>B</div>
        <span class="sound">openhat</span>
      </div>
      <div class="key" data-key="78">
        <div>N</div>
        <span class="sound">ride</span>
      </div>
      <div class="key" data-key="77">
        <div>M</div>
        <span class="sound">snare</span>
      </div>
    </div>
  </div>

  <!-- 音频资源 -->
  <audio src="./sounds/clap.wav" data-key="65"></audio>
  <audio src="./sounds/hihat.wav" data-key="83"></audio>
  <audio src="./sounds/kick.wav" data-key="68"></audio>
  <audio src="./sounds/openhat.wav" data-key="70"></audio>
  <audio src="./sounds/boom.wav" data-key="71"></audio>
  <audio src="./sounds/ride.wav" data-key="72"></audio>
  <audio src="./sounds/snare.wav" data-key="74"></audio>
  <audio src="./sounds/tom.wav" data-key="75"></audio>
  <audio src="./sounds/tink.wav" data-key="76"></audio>

  <audio src="./sounds/1.wav" data-key="81"></audio>
  <audio src="./sounds/2.wav" data-key="87"></audio>
  <audio src="./sounds/3.wav" data-key="69"></audio>
  <audio src="./sounds/4.wav" data-key="82"></audio>
  <audio src="./sounds/5.wav" data-key="84"></audio>
  <audio src="./sounds/6.wav" data-key="89"></audio>
  <audio src="./sounds/7.wav" data-key="85"></audio>
  <audio src="./sounds/8.wav" data-key="73"></audio>
  <audio src="./sounds/9.mp3" data-key="79"></audio>
  <audio src="./sounds/10.mp3" data-key="80"></audio>

  <audio src="./sounds/clap.wav" data-key="90"></audio>
  <audio src="./sounds/hihat.wav" data-key="88"></audio>
  <audio src="./sounds/kick.wav" data-key="67"></audio>
  <audio src="./sounds/openhat.wav" data-key="86"></audio>
  <audio src="./sounds/boom.wav" data-key="66"></audio>
  <audio src="./sounds/ride.wav" data-key="78"></audio>
  <audio src="./sounds/snare.wav" data-key="77"></audio>
</body>

</html>

排版没什么好讲的,这里主要是介绍一下HTML5中自定义数据属性data-key。

data-key

  • data-key 是HTML5中的自定义数据(data-*)属性之一,用于在HTML标签上存储自定义数据。在 HTML 中,你可以通过在标签上添加 data- 前缀来定义自定义数据属性。在上述应用中,我们使用每个按键的 data-key 属性存储了对应的键码(keyCode)。你可以使用任意合法的属性名来代替*部分。例如,data-colordata-user-id 等。这个属性是我们实现键盘交互非常重要的元素。

CSS部分

/* 业务样式 */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,
acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,
strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,
table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,
header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,
video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}

/* HTML5 display-role reset for older browsers */
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,
section {
    display: block;
}

body {
    line-height: 1;
}

ol,ul {
    list-style: none;
}

blockquote,q {
    quotes: none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
    content: '';
    content: none;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

html {
    height: 100vh;
    font-size: 10px;
    background: url('./2.jpg') bottom center;
    background-size: cover;
}

body,html {
    font-family: sans-serif;
}

.keys {
    /* 水平垂直居中 */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    min-height: 100vh;
}

.keys1,
.keys2,
.keys3 {
    display: flex;
}

.key {
    border: .4rem solid #000;
    border-radius: .5rem;
    margin: 1rem;
    font-size: 1.5rem;
    padding: 1rem .5rem;
    transition: all .07s ease;
    width: 10rem;
    text-align: center;
    color: white;
    text-shadow: 0 0 .5rem black;
}

.key:hover {
    border-color: red;
}

.playing {
    transform: scale(1.1);
    border-color: #ffc600;
    box-shadow: 0 0 1rem #ffc600;
}

.key div {
    font-size: 4rem;
}

.sound {
    font-size: 1.2rem;
    text-transform: uppercase;
    letter-spacing: normal;
    color: #ffc600;
}

对于还没去过企业上班或者实习的掘友(比如博主本人^-^)来说,可能不明白为什么最开始为什么要把基本上所有标签全列出来,在大学的学习中,或者自己自学在网上上网课,大部分老师通常都是像下面这样设置。

*{
  padding: 0;
  margin: 0;
}

的确很省事,对吧,不过一般企业开发却都不会使用上面这种简单的,它带来的性能是不好的。我去查询了几家大厂的网页源码,无一例外,他们都是按第一种来设置的。

豆瓣

一个简单小demo:键盘打击乐

腾讯

一个简单小demo:键盘打击乐

不过平时书写代码不太关心性能问题,我们按第二种设置也省事,不过第二种的设置我们还是需要了解的。第一种的代码可以在网上搜到,网址,reset.css,不用自己书写。

一个简单小demo:键盘打击乐

JS部分

function playSound(e) {
  const keyCode = e.keyCode;
  // 标签的数据属性
  const key = document.querySelector(`
    .key[data-key="${keyCode}"]
  `)
  key && key.classList.add('playing');

  const keys = document.querySelectorAll('.key');
  // console.log(keys)
  keys.forEach((key) => {
    key.addEventListener('transitionend', function (e) {
      if (e.propertyName != 'transform') return;
      this.classList.remove('playing');
    })
  })

  const audio = document.querySelector(`
    audio[data-key="${keyCode}"]
  `)

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

}
window.addEventListener('keydown', playSound)

解释:

    • playSound 函数接受一个事件对象 e,代表键盘按下事件。
    • 通过 e.keyCode 获取按下的键码。
    • 使用 document.querySelector 选择器找到拥有对应键码的 .key 元素,并添加 'playing' 类,触发样式效果。
    • 通过 document.querySelectorAll 获取所有 .key 元素,为每个元素添加 transitionend 事件监听器,确保在过渡结束时移除 'playing' 类。playing类为我们之前写的样式,点击某个按钮后会呈现一种放大的样式。
    • 通过 document.querySelector 找到对应键码的音频元素,将音频的播放时间重置为 0,并播放音频。
  1. window.addEventListener('keydown', playSound):

    • playSound 函数绑定到全局 window 对象的 keydown 事件上,即当用户按下键盘上的任意键时,触发 playSound 函数。
  2. 解释细节:

  • 添加 'playing' 类使得按下的键在页面上有一个瞬时的样式效果。
  • 通过监听 transitionend 事件,确保样式效果在过渡结束后被移除,避免样式效果持续存在。
  • 通过选择器找到对应的音频元素,将播放时间重置为 0,以确保每次按下键时都从音频的起始位置开始播放。

解释一下下面这段代码,可能有些人不太了解

keys.forEach((key) => {
    key.addEventListener('transitionend', function (e) {
      if (e.propertyName != 'transform') return;
      this.classList.remove('playing');
    })
})

key.addEventListener('transitionend', ...) 添加了一个事件监听器,用来监听过渡结束事件。e.propertyName 是用来检查触发过渡结束的 CSS 属性的名称。通过if (e.propertyName != 'transform') return; 判断只有当触发事件的属性是 'transform' 时才执行后续的代码。这是因为键盘按键的样式变化主要涉及到 CSS 的 transform 属性。

留言

感兴趣的掘友们可以去试试哦。本人GitHub链接,里面有音频可以下载哦♥(ˆ◡ˆԅ)。

转载自:https://juejin.cn/post/7312658500144300032
评论
请登录