Canvas钢琴琴键弹起来

753 阅读4分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

前情回顾

在之前曾经写过《canvas 制作钢琴琴键》一文,在那篇文章当中,已经使用canvas绘制出来了钢琴的琴键,并且能够通过鼠标点击白键来改变白键的颜色。

1.gif

不过光是点击白键还不够,钢琴也是需要点击黑键的,并且最重要的是钢琴怎么能够没有声音呢!

项目Gitee的地址gitee.com/wzckongchen…



再起

因为之前已经写过白键的点击方法,所以本次就用只需要稍作改变,即可完成黑键的点击。

首先对鼠标点击位置的(x, y)进行判断,下面由于代码过长,就不准备粘贴了。大家如果想看可以去上面Gitee上main.ts中查看

image.png

因为是在TypeScript中编写的,所以会有类型定义,xy是之前定义的坐标类型

type xy = {
    x: number,
    y: number
}

通过这一步,能够做到不同类别的按键判断。

其中的whiteKeyClick是白键按下的方法,白键和黑键按下在类中都有pressDown按下事件,各自会重写一下此方法

image.png

当前的效果是鼠标点击黑键和白键都会变色

80901.gif



钢琴音效

钢琴如果没有琴键的声音又怎么能称为钢琴呢,所以每一个按键都要有对应的声音,一共88个琴键,就要有88中音效。

说实话,找这些音效资源花费了我很久的时间......

image.png

最后经过一系列的寻找,还是被我找到了

地址就在上面的项目中, gitee.com/wzckongchen…

注意: 我使用audio标签去播放音乐,由于音频的资源比较大,所以我就不存放在前端项目中了,把这些音频资源放在我平时练习的node里,使用node来给出url去调用音频。

node运行命令: nodemon IO.js

image.png

这样测试一下,在网页中输入URL: http://localhost:3001/music/8A.mp3 。 发现能够访问到音频了

image.png

之后就可以在钢琴按下事件中调用音频调用方法了,注意这里需要根据不同的index去判断调用不同琴键的音效。

下面是白键的音调判断方法:

image.png

黑键判断:

image.png


当然了,这些判断需要对钢琴有一定了解,钢琴中是存在不同分区的。下图很重要,这也是我在编写时的重要依据:

可以看出,钢琴琴键排布具有如下特点。

  • 1、共有52个白键和36个黑键。
  • 2、黑键的长度和宽度均小于白键。
  • 3、每个黑键都位于两个白键中间(但不一定是正中间)。
  • 4、琴键分为若干组,每组有12个琴键(7个白键和5个黑键)。
  • 5、最左边的组只有3个琴键(2个白键和1个黑键),最后边的组只有1个琴键(1个白键),这两个组都是不完整的组。 每组的这12个琴键中,7个白键从左向右依次为do、re、mi、fa、sol、la、si,5个黑键从左向右依次为升do(降re)、升re(降mi)、升fa(降sol)、升sol(降la)、升la(降si)。

图中的那些汉字是每组的名称(从左向右依次为大字二组、大字一组、大字组、小字组、小字一组、小字二组、小字三组、小字四组、小字五组,其中大字二组和小字五组是不完全音组)

image.png

经过这一系列的操作之后,点击琴键就能发出不同的音效声音了。



键盘绑定

做到这里,突然觉得还是有些美中不足。 光是使用鼠标点击好像有些过于单调了,那么让打键盘变成弹钢琴

将键盘上的按键对应钢琴的琴键匹配绑定起来。

这里的内容我主要写在keyWord.ts当中了,使用export抛出

使用Map定义的keyWord来存放对应的联系

interface keyObj {
    keyname: string;
    type: number;  // 0:白键  1:黑键
    index: number;   // 对应的黑键和白键index
    represent: string
}
let keyWord:Map<string|number, keyObj> = new Map();

keyWord中的内容:

image.png

通过回调函数来设置电脑键盘的按下与抬起事件对应的操作,这里设置的依据是根据键盘按下的键值,每个按键按下都会有不同的键值:

键盘键值表.png

// 监听键盘点击
function keyWordDown(callback:Function, callback2:Function) {    
    document.onkeydown = (event)=>{ 
        let e = event || window.event;
        callback(e.keyCode)
    }    
    document.onkeyup = ()=>{ 
        callback2();
    }   
}

export { keyWord, keyWordDown, keyObj }

之后回到main.ts对应的回调方法写入即可。

image.png



完成

当然下面的GIF中是没有声音的,挺可惜的,毕竟重点就本文在于钢琴能响了

键盘弹奏:

80901.gif