Day1 - 原生JavaScript实现打击鼓

实现效果

在这里插入图片描述

实现思路
  • 一共要实现两个功能:

    • 按下键盘A-L的某一个键就播放对应的音频

      • 实现这个功能需要监听键盘按下的事件,用到onkeydown事件

        • 可以在控制台打印一下window,会看到他里面自带了很多的事件(以on开头)
          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7s2n3W1x-1637310099287)(C:\Users\xmydd\AppData\Roaming\Typora\typora-user-images\image-20211119152023982.png)]
      • 要实现按下按键A,然后对应的方块A就播放音频,就需要给每一个方块绑定按键A-L对应的编号

        • 比如,给方块A添加onkeydown事件后,打印一下event,可以看到event对象里有一个keyCode属性,这个属性对应的按键A的值为65
          在这里插入图片描述

        • 可以把这个65通过html的自定义属性data-*绑定到方块A上,这样在获取元素的时候直接通过event.keyCode获取到对应的元素

        • 获取到对应的音频元素后,使用play()方法播放音频

          • 这里需要注意,当按下了A-L以外的按键时,得到的audio是为空的,会报错,所以需要进行判断,为空的话就直接return,结束掉这个onkeydown事件函数,不在往下执行

          • 这里还有一个问题就是,当我们连续按下通过一个按键时,他并不是每次都从头开始播放的,而是等上一下播放结束,所以音频播放的次数,跟按键按下的次数是不相等的。可以手动将Audio对象的currentTime属性设置为0,实现每次按下按键都从头开始播放音频

            • 执行一下console.log([audio]);,可以看到他里面包含currentTime这个属性
              [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QyvAVpJs-1637310099297)(C:\Users\xmydd\AppData\Roaming\Typora\typora-user-images\image-20211119154631264.png)]
            • currentTime 属性设置或返回视频播放的当前位置(以秒计),当设置该属性时,播放会跳跃到指定的位置。
          <div data-key="65" id="clap" class="btn">
              <kbd>A</kbd>
              <span>CLAP</span>
          </div>
          <audio data-key="65" src="sounds/clap.wav"></audio>
          
          window.addEventListener('keydown', function(event){
              var audio = document.querySelector(`audio[data-key="${event.keyCode}"]`);
              var btn = document.querySelector(`div[data-key="${event.keyCode}"]`);
              
              // console.log([audio]);
              
              // 如果按下的是其他的键,就直接return
              if (!audio) return;
              audio.currentTime = 0;
              audio.play();
          
          })
          
    • 按下按键后会有一个边框样式变化的特效,而且是一闪而过的

      • 当按下按键时,就给对应的方块添加类名playing,从而实现边框样式的变化

        .playing {
            transform:scale(1.1);
            border-color:#ffc600;
            box-shadow: 0 0 10px #ffc600;
        }
        
      • 样式一闪而过的效果:

        • 给每一个方块添加transition属性,实现从样式a到样式b变化过渡

        • 对这个过渡的过程进行监听,使用transitionend事件,在过渡完成后就删除类名playing,从而移除样式

        • transitionend事件函数里打印一下event,会看到他监听了方块上所有的属性,这是因为我设置的transition值为all .07s ease;all就代表方块设置的所有样式属性

        • 但是我们只需要监听到transform属性,所以使用event.propertyName过滤掉其他的属性事件
          在这里插入图片描述

          //获取元素
          // 使用`Array.from()`将类数组转换为数组
          var btns = Array.from(document.querySelectorAll('.btn'));
          
          btns.forEach(item => item.addEventListener('transitionend', function(event){
              if (event.propertyName !== 'transform') return; // 过滤其中一种事件    
              event.target.classList.remove('playing')
          }));
          
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DrumKit</title>
    <style>
        *,html,body{
            padding: 0;
            margin: 0;
            height: 100%;
        }
        #main{
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: space-evenly;
            align-items: center;

        }
        kbd{
            height: auto;
            font-size: 2.125rem;
            font-weight: 700;
        }
        span{
            height: auto;
            display: block;
            font-size: 0.75rem;
            color: #ffc600;
            margin-top: 4px;
        }
        .btn{
            width: 100px;
            height: 100px;
            text-align: center;
            border: 6px solid #333;
            border-radius: 6px;
            box-sizing: border-box;
            padding: 12px;
            cursor: pointer;
            transition:all .07s ease;
        }
        audio{
            display: none;
        }
        .playing {
            transform:scale(1.1);
            border-color:#ffc600;
            box-shadow: 0 0 10px #ffc600;
        }
    </style>
</head>
<body>
    <div id="main">
        <div data-key="65" id="clap" class="btn">
            <kbd>A</kbd>
            <span>CLAP</span>
        </div>
        <div data-key="83" id="hihat" class="btn">
            <kbd>S</kbd>
            <span>HIHAT</span>
        </div>
        <div data-key="68" id="kick" class="btn">
            <kbd>D</kbd>
            <span>KICK</span>
        </div>
        <div data-key="70" id="openhat" class="btn">
            <kbd>F</kbd>
            <span>OPENHAT</span>
        </div>
        <div data-key="71" id="boom" class="btn">
            <kbd>G</kbd>
            <span>BOOM</span>
        </div>
        <div data-key="72" id="ride" class="btn">
            <kbd>H</kbd>
            <span>RIDE</span>
        </div>
        <div data-key="74" id="snare" class="btn">
            <kbd>J</kbd>
            <span>SNARE</span>
        </div>
        <div data-key="75" id="tom" class="btn">
            <kbd>K</kbd>
            <span>TOM</span>
        </div>
        <div data-key="76" id="tink" class="btn">
            <kbd>L</kbd>
            <span>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>
        // 按照目标要求,我们要实现按下按键A-L对应的方块就能发出对应的声音
        // 那么代码就需要实现两个部分
            // 1. 按下按键音频能够播放 --> 解决怎么知道按下A要播放那个音频? --> 
                // 解决办法:按下按键触发事件,那必然用到`onkeydown`键盘事件,这个事件有一个属性`keyCode`记录着每一个按键对应的编码
                // 将这个编码绑定到音频标签上(使用HTML自定义属性`data-*`),这样每次按下按键A,就获取A对应编码的音频,调用`play()`函数,播放他即可

            // 2. 播放音频的同时方块边框有特效并且播放结束特效消失 --> 解决如何实现播放结束特效就消失 -->
                // 解决办法:一播放方块边框样式就要变化,那么就事先写好一个样式,并且也给方块绑定按键编码,一按下按键就给边框添加样式
                // 给边框样式变化前后添加一个过渡属性`transition`,监听这个过渡的过程,过渡一完成就移除添加的样式

        
        // 实现
        // 需求1:按下按键音频能够播放
        window.addEventListener('keydown',function(event){
            // 根据keyCode获取对应的音频元素和方块元素
            const btn = document.querySelector(`div[data-key="${event.keyCode}"]`);
            const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`);

            // 避免按下除A-L以外的按键抛出错误,当遇到audio为空时,直接结束函数
            if (!audio) return;
            // 设置每次按下按键音频都从头开始播放
            audio.currentTime = 0;
            // 播放音频
            audio.play();

            // 给方块添加样式
            btn.classList.add('playing');
        });

        // 需求2:播放音频的同时方块边框有特效并且播放结束特效消失
        // 获取所有的方块
        const btns = [...document.querySelectorAll('.btn')];
        btns.forEach(item => item.addEventListener('transitionend', function(event){
            if (event.propertyName !== 'transform') return;
            event.target.classList.remove('playing');
        }))

        // 实现点击方块播放音频
        const audios = document.querySelectorAll('audio');
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click', function(){
                // 设置每次按下按键音频都从头开始播放
                audios[i].currentTime = 0;
                // 播放音频
                audios[i].play();
                // 给方块添加样式
                this.classList.add('playing');
            })
        }

    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值