搞代码的也能玩音乐--一起来写一个电子琴页面
效果演示
今天写一个有意思的界面,用键盘玩音乐 我们先看下效果
根据结果,我们来进行代码解释
HTML
<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/A.mp3" data-key="81"></audio>
<audio src="./sounds/aa.mp3" data-key="87"></audio>
<audio src="./sounds/B.mp3" data-key="69"></audio>
<audio src="./sounds/b1.mp3" data-key="82"></audio>
<audio src="./sounds/c1.mp3" data-key="84"></audio>
<audio src="./sounds/d1.mp3" data-key="89"></audio>
<audio src="./sounds/e1.mp3" data-key="85"></audio>
<audio src="./sounds/f1.mp3" data-key="73"></audio>
<audio src="./sounds/g1.mp3" data-key="79"></audio>
<audio src="./sounds/ee.mp3" data-key="80"></audio>
<audio src="./sounds/A.mp3" data-key="90"></audio>
<audio src="./sounds/aa.mp3" data-key="88"></audio>
<audio src="./sounds/b1.mp3" data-key="67"></audio>
<audio src="./sounds/B.mp3" data-key="86"></audio>
<audio src="./sounds/c1.mp3" data-key="66"></audio>
<audio src="./sounds/d1.mp3" data-key="78"></audio>
<audio src="./sounds/g1.mp3" data-key="77"></audio>
字母ASCII码
这个html文件看起来长,其实分开看就好,一个keys里有三排key(keys1,key2,key3)里面再继续划分,然后就是audio地址配对。
这段代码我个人认为比较麻烦的就是记不住字母编码
这里我也截几张图
CSS
* {
margin: 0;
padding: 0;
}
- 外边距0,内边距0
html {
font-size: 10px;
background: url("./background.jpg") bottom center no-repeat;
background-size: cover;
}
-
font-size
设置整个文档默认字体为10像素; -
bottom center
表示背景图像在页面底部居中显示,而no-repeat
表示图像不会在水平或垂直方向上重复平铺; -
background-size: cover;
:这个属性确保背景图像将覆盖整个页面区域,同时保持图像的宽高比。如果图像的宽高比与页面不同,某些区域可能会被留白,以确保图像完整显示
body,
html {
font-family: sans-serif;
}
font-family
定义字体
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
height: 100vh;
让body
占满整个浏览器窗口的高度。display: flex;
启用Flexbox布局,使子元素可以灵活排列。align-items: center;
垂直居中Flex容器内的子元素。justify-content: center;
水平居中Flex容器内的子元素。
.keys {
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: #fff;
background: rgba(0,0,0,0.4);
text-shadow: 0 0 0.5rem #000;
transition: all 0.07s ease;
}
margin
:外边距为1rem。border
:黑色实线边框,宽度为0.4rem。border-radius1
:边框圆角为0.5rem。font-size
:字体大小为1.5rem。padding
:内边距为1rem(垂直)和0.5rem(水平)。widtn
:固定宽度为10rem。teat-align
:文本水平居中。color
:文本颜色为白色。background: rgba(0,0,0,0.4);
:设置.key
元素的背景颜色为半透明的黑色(0.4的alpha值意味着60%的透明度)。text-shadow
:文本阴影,增强对比度。transition
:过渡效果为所有属性,持续时间为0.07秒,过渡方式为ease。
.keys .key div {
font-size: 4rem;
}
font-size: 4rem;
:将.key
元素内部div
的字体大小设置为4rem
rem
rem
是CSS中的一种相对单位,它代表“root em”,即相对于根元素(通常是html
元素)的字体大小的单位。当你使用rem
作为尺寸单位时,其数值是相对于根元素的font-size
属性的值来计算的。
例如:
- 如果
html
元素的font-size
被设置为16px
(这是浏览器的默认值),那么1rem
就等于16px
。 - 如果你将
html
元素的font-size
设置为10px
,那么1rem
就等于10px
。
.keys .key .sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: 0.1rem;
color: #ffc600;
}
text-transform: uppercase;
文本转换为大写。letter-spacing: 0.1rem;
字母间距设为0.1rem,增加文字间的空隙
.keys .key.playing {
transform: scale(1.5);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
transform: scale(1.5);
:使用transform
属性将元素的尺寸放大到原来的1.5倍,让按键看起来被"按下"。box-shadow: 0 0 1rem #ffc600;
:添加一个黄色的阴影效果,增强按键被按下时的立体感和视觉效果。阴影尺寸为1rem,颜色与边框颜色相同。
JS
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)
}
-
播放声音的函数:这一个叫做
playSound
的特殊功能,当它运行时,它会做以下几件事:- 它先看看你按下了键盘上的哪个键,并且记下这个键的编号(
keyCode
)。 - 然后,它在网页上查找一个和这个键相对应的模拟按键(
.key
),以及一个音频文件(audio
)。 - 如果找到了模拟按键,它就会让这个按键看起来像是被按下了(通过添加一个叫
playing
的特殊效果),并且播放对应的音频文件。
- 它先看看你按下了键盘上的哪个键,并且记下这个键的编号(
-
键盘事件监听器:告诉电脑,当键盘上的任何键被按下时(
keydown
事件),playSound
这个功能就会被触发。 -
查找所有模拟按键:查找网页上所有的模拟按键,并将它们存储起来,这样我们可以对它们进行操作。
-
移除动画效果的函数:还有一个叫做
removeTransition
的功能,它的作用是检查当模拟按键的动画效果结束后,就移除那个表示按键被按下的效果(移除playing
类)。 -
为每个模拟按键添加事件监听:这里对每一个模拟按键都添加了一个监听器,这样当按键的动画效果结束时,
removeTransition
功能就会被调用。
附加
这里我下载了一些钢琴音阶音源,需要的小伙伴可以去这个大佬的链接下载: piano-sound-samples/sound_keyboard_staff/A.mp3 at master · Leethring/piano-sound-samples · GitHub
如果懒得一个个下也可以直接用我的文件,地址:gitee.com/alozzhi/lhj…
转载自:https://juejin.cn/post/7379494133292875776