day1 - JavaScript Drum Kit 中文指南

Day01 – JavaScript Drum Kit 中文指南

作者:©liyuechun
简介:JavaScript30Wes Bos 推出的一个 30 天应战。项目免费供应了 30 个视频教程、30 个应战的肇端文档和 30 个应战处理方案源代码。目的是协助人们用纯 JavaScript 来写东西,不借助框架和库,也不运用编译器和援用。如今你看到的是这系列指南的第 1 篇。完全指南在 从零到壹全栈部落

简介

第一天的演习是用JS制造一个爵士鼓的页面,经由过程敲击键盘上差别的字母,会发出差别的声响,而且页面上会伴随着敲击的动画。

结果以下:

《day1 - JavaScript Drum Kit 中文指南》

想要完成以上结果,大抵思绪和处理方案以下:

  • 检测到键盘上什么键被按下–监听keydown事宜

  • 在按键被按下的时刻,播放音效–audio.play()

  • 在按键被按下的同时,播放动画–Element.classList.add('playing')

  • 在动画完毕后,移除动画,不然以后再点击不会有任何结果–Element.classList.remove('playing')

基本语法

一些 ES6 语法

  1. const :声明一个只读的常量,标识符的值只能赋值一次。

  2. `字符串 ${ 变量、属性名 } `:模板字面量(Template literals)中用于示意模板字符串的标识。特点是字符串首尾用反引号(`),内部的模板部分用 ${ } 括起来示意,详细请看MDN文档。简朴例子以下:

var a = 1;
var b = 2;
//不必模板的写法
console.log("三是" + (a + b) + "不是" + (2 * a + b)); //"三是3不是4"
//运用模板字符串的写法
console.log(`三是${a + b}不是${2 * a + b}`); //"三是3不是4"

forEach 与箭头函数

运用 document.querySelector 猎取一组相符 CSS 选择符的元素快照,范例为 NodeList(此对象是关于文档的实时运转的动态查询),对其举行遍用时可采用 forEach 要领。

// Code from http://es6-features.org/#StatementBodies

// ES6
nums.forEach(v => {
    if (v % 5 === 0)
        fives.push(v);
})

// ES5
nums.forEach(function (v) {
    if (v % 5 === 0)
        five.push(v);
})

页面基本规划

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

<head>
  <meta charset="UTF-8">
  <title>JS Drum Kit</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>


  <div class="keys">
    <div data-key="65" class="key">
      <kbd>A</kbd>
      <span class="sound">clap</span>
    </div>
    <div data-key="83" class="key">
      <kbd>S</kbd>
      <span class="sound">hihat</span>
    </div>
    <div data-key="68" class="key">
      <kbd>D</kbd>
      <span class="sound">kick</span>
    </div>
    <div data-key="70" class="key">
      <kbd>F</kbd>
      <span class="sound">openhat</span>
    </div>
    <div data-key="71" class="key">
      <kbd>G</kbd>
      <span class="sound">boom</span>
    </div>
    <div data-key="72" class="key">
      <kbd>H</kbd>
      <span class="sound">ride</span>
    </div>
    <div data-key="74" class="key">
      <kbd>J</kbd>
      <span class="sound">snare</span>
    </div>
    <div data-key="75" class="key">
      <kbd>K</kbd>
      <span class="sound">tom</span>
    </div>
    <div data-key="76" class="key">
      <kbd>L</kbd>
      <span class="sound">tink</span>
    </div>
  </div>

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

  <script>
  </script>


</body>

</html>
  • 标签定义键盘文本

说到手艺概念上的特别款式时,就要提到 标签。正如你已猜到的,它用来示意文本是从键盘上键入的。
浏览器通常常使用等宽字体来显现该标签中包括的文本。
标签经常常使用在于计算机相干的文档和手册中。比方:

键入 <kbd>quit</kbd> 来退出顺序,或许键入 <kbd>menu</kbd> 来返回主菜单。
  • 运用 data-* 属性来嵌入自定义数据

页面里经由过程data-key将页面展现的内容和audio关联起来。运用要领以下引见:

<ul>
    <li data-animal-type="bird">Owl</li>
    <li data-animal-type="fish">Salmon</li> 
    <li data-animal-type="spider">Tarantula</li> 
</ul>

① data-* 属性用于存储页面或应用顺序的私有自定义数据。
② data-* 属性给予我们在所有 HTML 元素上嵌入自定义 data 属性的才能。
③ 属性名不应该包括任何大写字母,而且在前缀 “data-” 以后必须有最少一个字符
④ 属性值可所以恣意字符串

语法:

<element data-*="somevalue">

属性值:

形貌
somevalue划定属性的值(以字符串)。

重要CSS代码

html {
  font-size: 10px;
  background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
  background-size: cover;
}
body,
html {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

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

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

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

kbd {
  display: block; 
  font-size: 4rem;
}

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

重要属性有以下几个:

  • html中有一个款式为font-size: 10px;,在本案例中,1rem就是10px,rem是以html中的font-size为参照物,1.2rem就是12px

  • transform: scale(1.1);–该属性在键盘被点击时将该元素缩放至本来的1.1倍。

  • .key{border: .4rem solid black;} .playing{border-color: #ffc600;}–这两条属性在按键点击的时刻转变边框色彩。

  • .key{text-shadow: 0 0 .5rem black;} .playing{box-shadow: 0 0 1rem #ffc600;}–这两条属性在按键点击的时刻转变暗影的结果

  • transition: all .07s ease;–定义以上动画在0.07秒内完成。
    我们注重到我们定义了.palying类,在按键按下的时侯为该元素增加playing类,在完毕后移除playing类。

JS代码

按键监听&音效播放&增加动画

function playSound(e) {
    const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
    const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
    if (!audio) return;
    
    key.classList.add('playing');
    audio.currentTime = 0;
    audio.play();
}
/**
* 监听页面的keydown事宜,触发playAudio函数。
*/
window.addEventListener('keydown', playSound);
  • 监听页面的keydown事宜,触发playAudio函数。

  • 经由过程KeyCode检测我们按下的键盘按钮是哪一个按钮。

    • A -> 65

    • B -> 66

    • C -> 67

    • D -> 68

    • E -> 69

    • F -> 70

    • G -> 71

    • H -> 72

    • I -> 73

    • J -> 74

    • K -> 75

    • L -> 76

    • M -> 77

    • N -> 78

    • O -> 79

    • P -> 80

    • Q -> 81

    • R -> 82

    • S -> 83

    • T -> 84

    • U -> 85

    • V -> 86

    • W -> 87

    • X -> 88

    • Y -> 89

    • Z -> 90

  • http://keycode.info翻开这个网站,能够轻松检察键盘的按钮对应的code。

《day1 - JavaScript Drum Kit 中文指南》

  • 在这里我们用到了ES6的模板字符串,${e.keyCode},能够动态的将按键的Keycode传过去,以使audio动态的猎取每个按键绑定的audio。须要注重的是模板字符串一定要运用”`”(Esc下面谁人键)包裹,而不是双引号。

  • 我们注重到audio.play();前面一行是audio.currentTime = 0;,这是由于,假如没有在播放音效前将该音乐重置,会发作以下状况,当我一连点击某一按键的时刻,只要第一次点击会响,第二次第三次一连的点击能够没声响。所以在每一次点击之前重置音效是很有必要的。

  • key.classList.add('playing');能够在按键点击的同时为该元素增加playing类,展现小动画。

  • if(!audio) return; if(!key) return;由于并非每个按键都有音效,当用户点击了非绑定音效按键,实时退出函数是很好的习气。

动画完毕后移除动画

function stopTransition(e) {
    if (e.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
}
  
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend',stopTransition));  
  • 监听每个按键元素的transitionend事宜,当按键元素的动画完毕后会触发stopTransition函数。

  • 首先在stopTransition函数中能够输出事宜e的内容,会输出该动画每一步详细的变化,发明个中会有propertyName属性,能够经由过程推断propertyName即是个中的一个值(比方’transform’),即是该值就移除playing类,也即移除动画。

  • 在定位元素的时刻,能够运用this也能够运用e.target,能够简朴这么明白,this值的是谁出发了此次事宜,也就是key,就等同于事宜的目的(e.target).

处理难点

怎样将键盘按键与页面按钮对应起来?

衔接的帮手是 keydown 事宜中的 keyCode 属性,keyCode 属性的值和 ASCII 编码值雷同(对应小写字母)。在这个网站能够用按键盘来检察对应的键码。

我们能猎取到的初始页面中,按钮 div 和音频 audio 标签中都增加了一个属性 data-key 用于存储对应的键码,如许做的目的是,增加键盘事宜监听后,触发键盘事宜时即可猎取事宜的 keyCode 属性值,以此为线索,操纵对应的按钮及音频。

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

怎样保证按键被按住不放时,能够立时响起一连鼓点声?

每次播放音频之前,设置播放时候戳为 0:

const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
audio.currentTime = 0;
audio.play();

怎样使页面按钮恢复原状?

应用一个叫 transitionened 的事宜,它在 CSS transition 完毕后会被触发。我们就能够应用这个事宜,在每次打鼓的结果(尺寸变大、色彩变化)完成以后,去除响应款式。

在这个页面中,发作 transition 的款式属性不止一个(box-shadow, transform, border-color),所以须要增加一个推断语句,使每发作一次按键事宜时,只去除一次款式。

funciton remove(event) {
  if (event.propertyName !== 'transform') return;
  this.classList.remove('playing');
  // event.target.classList.remove('playing');
}

完全源码

Github Source Code

扫码申请加入全栈部落
《day1 - JavaScript Drum Kit 中文指南》
    原文作者:愿码社区技术团队
    原文地址: https://segmentfault.com/a/1190000010225772
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞