记录–不做码农而做 DJ 😎

  • 记录–不做码农而做 DJ 😎已关闭评论
  • 72 次浏览
  • A+
所属分类:Web前端
摘要

?Coding 一定很累吧,快来跟我一起 Djing !!!? 我的思路是通过监听键盘按下事件,在用户按下对应键时,找到相应的按键元素和音频元素,通过添加和移除 CSS 类实现按键效果,并播放关联的音频文件。同时,通过事件监听器确保在按键元素的过渡动画结束时,移除添加的类,实现按键效果的平滑消失。


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--不做码农而做 DJ 😎

?Coding 一定很累吧,快来跟我一起 Djing !!!?

 

我的思路是通过监听键盘按下事件,在用户按下对应键时,找到相应的按键元素音频元素,通过添加和移除 CSS 类实现按键效果,并播放关联的音频文件。同时,通过事件监听器确保在按键元素的过渡动画结束时,移除添加的类,实现按键效果的平滑消失

记录--不做码农而做 DJ 😎

 

话不多说,上代码!?


HTML 框架 ❤

我们在页面上添加一行按键(A-L),每个按键对应不同的乐器,再用audio元素存放音频存放地址,和对应按键的键盘码,以便于后续 JS 实现。

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>做个快乐的DJ</title>     <link rel="stylesheet" href="./common.css"> </head> <body>     <div class="keys">         <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">boom</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>     <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> <script src="./index.js"></script> </body> </html>

简单介绍一下:

  • <div class="keys"> : 包含所有敲击乐按键的容器。
  • <div class="key" data-key="xx"> : 单个按键元素,包括按键显示的字母和音频描述,data-key属性存放按键的键盘码。
  • <audio> : 包含音频文件路径和与之关联的按键。

CSS 样式 ?

CSS 样式包含两个部分,重置样式业务样式

/* CSS Reset 重置样式*/ 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; } 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('./background.png') bottom center;/*载入图片*/     background-size: cover; /*让图片覆盖窗口*/ } body, html{     font-family: sans-serif; } .keys{     display: flex;      align-items: center;     justify-content: center;/*元素居中*/     min-height: 100vh; } .key{     border: 0.4rem solid rgb(1, 60, 106);     border-radius: 0.5rem;     margin: 1rem;     font-size: 1.5rem;     padding: 1rem 0.5rem;     transition:all 0.7s ease;     width:10rem;     text-align: center;     color: rgb(6, 55, 94);     box-shadow: 0 0 2rem rgb(0, 75, 121)  } .playing{ /*触发按键效果*/     transform: scale(1.1);     border-color: rgb(248, 117, 117);     box-shadow: 0 0 2rem rgb(255, 84, 84) } .key div{     font-size: 4rem; } .sound{     font-size: 1.2rem;     text-transform: uppercase;     letter-spacing: normal;     color: rgb(0, 145, 143); }

简单介绍一下:

  1. 重置样式:

    • 设置了各种 HTML 元素的默认样式,例如清除列表项、删除引用等,以确保在不同浏览器中获得一致的基本外观。就不过多赘述了。
  2. 业务样式:

    • rem 是相对于根元素(html 元素)字体大小的单位。这里我们设置默认的根元素字体大小为 10 px,那么.key类的字体大小 1.5 rem 即为15 px。
    • .key 类定义了按键的基本样式,包括边框、圆角、阴影、字体大小等。其中transition:all 0.7s ease;这行代码表示所有样式属性在变化时都会以持续 0.7 秒的时间,并采用渐变的速度曲线,从而产生平滑的过渡效果。
    • .playing 类定义了按键在播放音频时的样式,增加了缩放和边框颜色的变化,以及阴影效果。其中transform: scale(1.1);表示将元素沿着 X 和 Y 方向同时放大到原始大小的 1.1 倍,使交互更加生动有趣。通过 JS 对这个类的添加和移除,实现按键打击效果,直接化身 DJ 。

JS 实现 ?

// 播放音频和添加按键效果的函数 function playSound(e) {     const keyCode = e.keyCode;     const key = document.querySelector(`.key[data-key="${keyCode}"]`);//匹配按键          // 如果按键存在,添加 playing 类     key && key.classList.add('playing');     const audio = document.querySelector(`audio[data-key="${keyCode}"]`);//匹配音频          // 如果音频存在,重置播放时间并播放音频     audio && (audio.currentTime = 0, audio.play()); } // 获取所有带有 .key 类的元素 const keys = Array.from(document.querySelectorAll('.key')) // 对每个按键添加 transitionend 事件监听器 keys.forEach(key => {     key.addEventListener('transitionend', function(e) {         // 如果触发的事件不是 transform,则返回         if (e.propertyName !== 'transform') return;         // 移除 playing 类         this.classList.remove('playing');     }) }) // 添加全局键盘按下事件监听器,触发 playSound 函数 window.addEventListener('keydown', playSound)

我们挑出几个重点讲讲:

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

  1. 反引号(` `) 是 ES6 引入的模板字面量。它允许你在字符串中嵌入变量。${keyCode} 就是其中的变量插值,这里用来替换为实际的按键码值。
  2. .key[data-key="${keyCode}"] 表示一个 CSS 选择器字符串。它表示选择具有 key 类且具有 data-key 属性值等于 keyCode 的元素。
  3. document.querySelector() 是一个 DOM 操作方法,用于在文档中选择第一个匹配指定选择器的元素。在这里,它选择了具有指定 data-key 属性值的按键元素。

keys.forEach(key => {...}):

  1. key.addEventListener('transitionend', function(e) {...}) :对每个按键元素添加一个事件监听器,监听过渡动画结束事件
  2. if (e.propertyName !== 'transform') return; : 判断事件的 propertyName 属性是否为 'transform',如果是,执行后续的操作,如果不是,则直接返回。
  3. this.classList.remove('playing'); : 如果过渡动画是针对 transform 属性的,那么用 classList.remove 方法从当前元素的类列表中移除名为 'playing' 的类,以使按键效果消失。

综合起来,这段代码确保在每个按键元素上的过渡动画结束时,只处理与 transform 属性相关的事件,以移除添加的 'playing' 类,从而产生按键效果的消失过渡。

最后 ?

Coding 很有趣,闲暇之余,试试 DJing 吧!

已将代码、图片及乐器 wav 文件放到 Gitee,感兴趣的同学可以自取,Coding不易,切勿白嫖!记得点亮 star !!!

本文转载于:

https://juejin.cn/post/7304615395741466676

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--不做码农而做 DJ 😎