音乐键盘:独属于程序员的浪漫

音乐键盘

呈现效果:当敲击键盘中的字母按键时会发出不同的声音,并且还有动画效果。

这个案例分为HTML部分、CSS部分和JavaScript部分。在CSS部分中使用Stylus编译器将.styl文件编译为标准的.css文件,然后将生成的.css文件链接到HTML文档中,以便浏览器可以加载并应用样式。

HTML部分

html 复制代码
<div class="keys">
    <div class="key1">
        <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="key2">
        <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="key3">
        <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="81"></audio>
<audio src="./sounds/hihat.wav" data-key="87"></audio>
<audio src="./sounds/kick.wav" data-key="69"></audio>
<audio src="./sounds/openhat.wav" data-key="82"></audio>
<audio src="./sounds/clap.wav" data-key="84"></audio>
<audio src="./sounds/ride.wav" data-key="89"></audio>
<audio src="./sounds/snare.wav" data-key="85"></audio>
<audio src="./sounds/tom.wav" data-key="73"></audio>
<audio src="./sounds/tink.wav" data-key="79"></audio>
<audio src="./sounds/tink.wav" data-key="80"></audio>

<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/clap.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/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/clap.wav" data-key="66"></audio>
<audio src="./sounds/ride.wav" data-key="78"></audio>
<audio src="./sounds/snare.wav" data-key="77"></audio>

用一个类名为keys的大盒子包裹3个子盒子,分别对应键盘的三行字母按键。

其中每一个子盒子里的元素都有一个key类和一个特定的 data-key 属性用于标识对应的键盘按键,并且内部都一个显示字母的div标签和描述声音的span标签。

还有一系列的 audio 标签,每一个音频都是通过 data-key 属性和按键进行对应。也可以根据自己的喜好设置不一样的音频。

你会好奇data-key的值是怎么来的吗?在JavaScript部分会揭秘。

CSS部分

css 复制代码
* {
  margin: 0;
  padding: 0;
}

html {
  font-size: 10px;
  background: url("./background1.jpg") top center no-repeat;
  background-size: cover;
}

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

body {
  height: 100vh;
}

.keys {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  min-height: 100vh;
}

.key1,
.key2,
.key3 {
  display: flex;
}

.keys .key {
  margin: 1rem;
  bordeR: 0.4rem solid #000;
  border-radius: 0.5rem;
  font-size: 1.5rem;
  padding: 1rem 0.5rem;
  width: 10rem;
  text-align: center;
  color: #c8e6ff;
  background: rgba(0, 0, 0, 0.4);
  text-shadow: 0 0 0.5rem #000;
  transition: all 0.7s ease;
}

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

.keys .key .sound {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: 0.1rem;
  color: #87ceeb;
}

.keys .key.playing {
  transform: scale(1.3);
  border-color: #87ceeb;
  box-shadow: 0 0 1rem #87ceeb;
}

CSS部分通过将编写.styl文件后编译为标准的.css文件,这样可以减少代码量。

CSS部分:

  1. 清除页面里所有的默认内外边距。
  2. html元素设置了字体大小样式,这样是为了在后续使用rem单位提供一个基准;设置了一个背景图片,并且要求图片在垂直方向上头部对齐,水平方向居中对齐,图片不重复平铺;为了让图片不失真可以通过设置background-size样式,再根据容器和图片的优先程度选择相应的属性。
  3. .keys类选择器元素设置为Flex 布局,将三行字母按键进行垂直方向排列,并且在垂直和水平方向上面进行居中对齐。
  4. .key1.key2key3类选择器也设置为Flex 布局,这样可以使按键元素保持水平方向排列。
  5. .keys容器内每个类名为.key的子元素进行样式定义。
  6. 设置.playing类的特定样式,通过JavaScript的监听器动态增加和删除该类名达到用户按下对应按键后得到视觉反馈的动画。

小tips

  1. background-size样式中:

    1. cover属性可以确保背景图片在填充元素区域时,会等比例缩放图片以完全覆盖整个区域。这样是以容器为优先选择的。
  1. contain属性会保持图像的宽高比,将图像缩放至能够完全包含在背景区域内。也就是说图像可能会在背景区域内留下空白,但其内容会完整显示。这样是以图片为优先选择的。
  1. CSS中的常见单位:

    1. 绝对单位:
      • px:在屏幕上显示时,一个像素通常对应屏幕上的一个物理像素点,是最常用的固定尺寸单位。
    2. 相对单位:
      • % :通常是相对于父元素的某个尺寸的比例。比如,如果父元素宽度为 100px,子元素宽度设置为 50%,则子元素宽度为 50px。
      • em:相对于当前元素的字体大小。如果未设置,则继承自父元素。它的值取决于当前元素的字体大小。如果当前元素字体大小为 16px,那么 1em 就等于 16px。
      • rem:相对于根元素(通常是<html>元素)的字体大小,提供了一致的尺寸缩放基础。
      • vw/vh:分别表示可视窗口的宽度和可视窗口的高度的1%。例如,1vw等于可视窗口宽度的1%。

JavaScript部分

javascript 复制代码
function playSound(e) {
    let keyCode = e.keyCode;
    const key = document.querySelector(`.key[data-key="${keyCode}"]`);
    const audio = document.querySelector(`audio[data-key="${keyCode}"]`);
    if (!key) return;
    key.classList.add('playing');
    audio.play();
}
window.addEventListener('keydown', playSound)
const keys = document.querySelectorAll('.key');
function removeTransition(e) {
    if (e.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
}
for (let key of keys) {
    key.addEventListener('transitionend', removeTransition)
}

代码逻辑:

  1. 通过在窗口上添加一个键盘按下的事件监听器监听用户的按键操作。
  2. 当用户按键盘后调用playSound函数。
    • e.keyCode表示触发事件时按下的键对应的键码。通过键码获取对应的key元素和audio元素,如果按错了按键就获取不了key元素,就直接结束,如果没有按错按键就为其对应的key元素添加playing类实现动画效果,并且通过获取到的audio元素播放对应的音效。
  3. 获取页面上所有拥有 class 名称为 key 的元素,并且对其进行for of循环遍历操作,为每个元素添加了一个事件监听器监听 transitionend 事件。
  4. 当触发了key 元素的监听器后调用removeTransition函数移除对应的key元素中的playing类。

你可以自己动手将喜欢的音频绑定到相应的键盘按键上制作一个属于你自己的专属音乐键盘。

相关推荐
shyi3 分钟前
基于Uniapp App-Plus Honeywell EDA51 PDA手持 广播扫码实现
前端
JYeontu3 分钟前
语音指令怎么避免同音词干扰?
前端·javascript
羊聪4 分钟前
《前端实时媒体流:MediaSource 与 SSE 解析》
前端
需要兼职养活自己4 分钟前
手把手教你搭建微前端qiankun
前端
逆袭的小黄鸭5 分钟前
JavaScript 异步操作入门指南与基础实践
前端·javascript
意桉6 分钟前
Element Plus 去掉表格外边框
前端·vue.js·elementui·element plus
J船长6 分钟前
gRPC基础,区别REST,使用教程 (Flutter)
前端
cock6 分钟前
JS 数据类型
前端
逾明7 分钟前
使用js创建img加载阿里云oss图片跨域的问题
前端·javascript·浏览器
芝麻糊冲呀9 分钟前
JavaScript 数组方法全解析:从基础到高阶应用
前端