HTML5时代:探索APP开发的新节奏——打击乐的数字创新舞台

203 阅读7分钟

制作一个小demo APP下的打击乐的效果,敲动你的键盘,播放你的音乐:

大致就是这么一个效果,当你敲动你的键盘,按钮闪烁伴随着音乐,动次打次的打击感就很酷爽,话不多说,大家赶紧试试看:(http://127.0.0.1:5500/html5/audio_demo/index.html)

看看布局其实并不复杂,添加容器给上弹性布局,将对应的图标以及音乐安装上去即可,这里主要难操作的点就是background中的盒子的填充,背景图的等比例缩放如何确保图片不会失真以及CSS中的适配问题。

stylus

Stylus 是一个强大的动态 CSS 预处理器,其功能与 Sass 或 LESS 相似。它提供了许多有用的功能,如变量、混合(mixins)、嵌套规则、继承、函数等,使得编写 CSS 更加高效和可维护。Stylus 的一个显著特点是它具有可选的括号和冒号,这意味着你可以写出非常简洁的代码。

传统的CSS样式条条框框是不是太过于繁琐?构建出styl样式来简化CSS的书写,这是最近比较新颖的写法,也加强了我们的跑动效率,你可以在你的编辑器中安装如下stylus

image.png

在你的终端中输入命令行: stylus -w common.styl -o common.css 来连接CSS运行代码。

image.png

框架

在HTML5 中主体容器的搭建很简单:

1.打击乐界面:

  • 设置keys容器,包含所有的打击乐按键。
  • 每个按键都是一个 <div> 元素,具有 key 类和 data-key 属性,后者与对应的键盘按键的ASCII码相关联。
  • 每个按键内部有一个 <div> 显示键的字母,和一个 <span> 显示声音的类型。

2. 音频元素:

  • 有九个 <audio> 元素,每个都对应一个 .wav 音频文件和一个 data-key 属性,与按键的 data-key 匹配。

至于页面的美化和音频的播放,分别在相应的CSS和JS中完成点缀即可。

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML5 App打击乐</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="./common.js"></script>
</body>
</html>

CSS样式效果

image.png

搭建好这样的效果:

  1. 全局重置:

    • * 选择器重置了所有元素的 margin 和 padding 为 0,这是常见的样式重置,以确保在不同浏览器中元素的默认样式一致。
  2. HTML 样式:

    • html 选择器设置了 HTML 元素的字体大小为 10px,并且定义了背景图片。背景图片被设置为不重复,并覆盖整个可视区域。
  3. Body 和 HTML 共享样式:

    • body, html 选择器设置了 sans-serif 字体族。
  4. Body 样式:

    • body 选择器设置了元素的高度为视口的 100%(100vh),并且使用了 Flexbox 布局。它还设置了水平和垂直居中(align-items: center 和 justify-content: center)。
  5. .keys 容器样式:

    • .keys 选择器设置了 Flexbox 布局,使其子元素(即 .key)能够水平排列。
  6. .key 单个键样式:

    • .key 选择器定义了键的样式,包括外边距、边框、圆角、字体大小、内边距、宽度、文本对齐、颜色、背景和文本阴影。它还包含了一个过渡效果,当键的状态改变时,会有一个放大的动画效果。
  7. .key 内部元素的样式:

    • div 选择器在 .key 内部定义了更大的字体大小。
    • .sound 选择器设置了声音文本的样式,包括字体大小、文本转换、字母间距和颜色。
  8. .playing 状态样式:

    • .key.playing 选择器定义了当键被激活(播放)时的样式,包括放大效果(transform: scale(1.5))、边框颜色和盒阴影效果。
* {
  margin: 0;
  padding: 0;
}
html {
  font-size: 10px;
  background: url("./background.jpg") bottom center no-repeat;
  background-size: cover;
}
body,
html {
  font-family: sans-serif;
}
body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.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;
}
.keys .key div {
  font-size: 4rem;
}
.keys .key .sound {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: 1rem;
  color: #ffc660;
}
.keys .key.playing {
  transform: scale(1.5);
  border-color: #ffc600;
  box-shadow: 0 0 1rem #ffc600;
}

考点

  • background

  • 盒子的大小 body 高和宽是不定的 图片 px是绝对大小

    • no-repeat 不会平铺

    • 如何铺满整个的盒子?

    • background-position bottom center

    • 大大 等比例缩放 确保图片不失真

    • contain 只在一个方向上填充满box,另一个方向空着,背景优先

    • cover 容器优先

  1. background: url('./background.jpg') bottom center no-repeat; 设置背景图片位置、不平铺及覆盖 ,以底部效果为主,当然你也可以试试top以及全局。
  2. background-size: cover; 背景图片按比例缩放以完全覆盖容器,而同样的一个属性contain能够显示全部背景图,但并不能实现对键盘的覆盖。
  • 相对单位
  1. height: 100vh; 高度占满全屏视口,对于vh这个单位,100vh就是代表整体,之后再按百分比逐个去拿

  2. .keys { display: flex; } keys的弹性布局就是为了使.key子元素在一行内显示

  3. rem html font-size 均是等比例变化 只要跟html 一个元素进行等比例

  4. px是绝对单位,移动端不适用

JS中播放效果

当用户按下键盘上的相应按键时,会在网页上触发对应音效并显示视觉反馈。

function playSound(e) {
    // console.log(e.keyCode, '////');
    let keyCode = e.keyCode
    const key = document.querySelector(`.key[data-key="${keyCode}"]`)
    const audio = document.querySelector(`audio[data-key="${keyCode}"]`)
    // console.log(audio);
    if (!key) return
    key.classList.add('playing')
    audio.play()

    // 65 -> A playing 
}
window.addEventListener('keydown', playSound)   

const keys = document.querySelectorAll('.key')
// 不需要i 语义化
// es6 可读性 
function removeTransition(e) {
    if (e.propertyName != 'transform') return
    // console.log(e.target);
    e.target.classList.remove('playing')
}
for (let key of keys) {
    key.addEventListener('transitionend',removeTransition)
}

playSound 函数

这个函数作为事件处理程序,被绑定到窗口的 keydown 事件上。当用户按下键盘上的任意键时,该函数会被调用。

  • 获取按键值:通过 e.keyCode 获取用户按下的键盘按键码。
  • 查找对应的DOM元素:使用 document.querySelector 方法根据按键码找到页面上对应的 .key 元素和关联的 <audio> 标签。.key 元素应包含一个 data-key 属性,其值与键盘按键码匹配,以便正确关联视觉效果和音频。
  • 播放音效并添加视觉效果:如果找到了对应的 .key 元素,则为其添加 playing 类(可能用于改变样式以指示按键被按下),并播放与之关联的音频文件。
  • 日志注释:代码中有被注释掉的日志输出,用于调试目的,可以用来查看按键码和音频元素是否正确获取。

removeTransition 函数

此函数用于移除按键在播放音效时添加的 playing 类,一旦过渡动画(如按键放大效果的结束)完成,该函数就会被调用。

  • 监听过渡结束事件:通过检查 e.propertyName 是否为 'transform' 来确定是否是期望的过渡效果结束,如果是,则从目标元素(按键)移除 playing 类,恢复其原始样式。

事件绑定循环

最后的 for...of 循环遍历所有 .key 元素,并为每个元素绑定一个 transitionend 事件监听器,当这些元素的过渡效果结束时,自动调用 removeTransition 函数。

通俗的来讲就是:

选取页面中所有的.key元素,定义removeTransition函数,当元素的过渡效果结束时触发。

循环变量命名考虑了语义化和ES6的可读性,未使用传统的'i'作为迭代变量,而function

removeTransition(e) { 如果过渡的属性名不是'transform'(即非我们关心的过渡效果),则直接返回。

移除触发事件的元素上的'playing'类,通常是过渡动画结束后恢复元素初始状态。

最后在遍历keys数组,为每一个.key元素添加transitionend事件监听器,当过渡效果结束时调用removeTransition函数

到这里差不多实现了基本的效果:

image.png

随着你的敲打来实现闪烁以及播放

image.png

建议大家体验试试看。

总结

在stylus下编写样式更能够简单化,加快代码的效率,再是位置的设立考虑布局的覆盖问题。

一起实操看看吧!