cPiano制作笔记(二)| 重构代码使其通用化

原创 小赛艇  2017-11-30 18:09  阅读 829 次

上一篇文章【cPiano制作笔记 | javascript和css】https://xsaiting.com/cpiano.html只完成了琴键与声音的绑定功能。

那么,这次我想把它拓展到所有页面元素,任意一个网页上的元素添加了一个class之后,就可以像琴键一样,点击它或者按下指定的按键就会发声。有了这个功能之后说不定还能做音游呢~

先贴一下链接:cPiano 2.0版本地址:https://xsaiting.com/cpiano GitHub项目: https://github.com/xsaiting/cpiano

思路部分

先在笔记本上写下重构的思路

即如果一个元素添加了ckey类,那么就成为了cpiano的一个键元素。

如果再添加【ckey-key-音名-分组(可选)】就成为琴键元素,按下它的时候,播放音名所对应的声音。

如果再添加【ckey-ctrl-分组-high(升高)/low(降低)-半音数】就成为琴键控制元素,按下它时,把所有属于这个分组的琴键上升[半音数]个半音。

另一方面,如果要把页面元素与键盘上的键绑定,就添加【ckey-code-按键编号】这个按键编号可以查查javascript keycode获得对应的表格,当然为了方便使用,也可以添加【ckey-code-k-按键名】例如【ckey-code-k-Q】即代表Q键。但这只适用于字母A-Z,数字0-9

思路想好了,接下来就是去实现了。

实现部分

1、解析按下/弹起的ckey

首先,当用户按下/弹起一个ckey时,需要获取ckey的属性,知道它是一个琴键或是控制键,或者两者都是。

1.1 给ckey绑定按下/弹起的事件

1.2 获取键的信息

那么我先获取这个ckey的所有类名,记为getClass

然后再将类名转换为我自定义的一类对象ckeyClass,直接抽象成函数getClass2ckeyClass(getClass),即把getClass转换为ckeyClass,这里的ckeyClass就代表按下的一类键了。

1.3 将按下/弹起的键的ckeyClass传递给执行函数upClass,downClass

因为鼠标点击、触摸以及等下要加入的键盘按键事件都要转化为按下ckeyClass、弹起ckeyClass,所以直接抽象成函数upClass()、downClass()

 

先补全之前的点击与触摸事件:

2、 upClass和downClass

再写upClass和downClass函数,由于浏览器的特性,如果用户按紧键盘上某个键的时候,后面绑定按键后,会一直执行downClass,所以需要一个数组来记下已经按下的ckey,如果重复按这个键,就不会再执行相应的操作。

那么当按下一个新键时,如果它是一个琴键,就play这个键,如果是控制键,就执行相应控制操作;当弹起这个键的时候,一边要删除记录的已经按下的ckey,一边判断如果是琴键,就pause这个键。

ifEql()用于判断两个ckeyClass值是否相同

 

3、playClass和pauseClass

已经知道按下的是琴键了,于是把ckeyClass传递到了playClass和pauseClass两个函数来处理。

对于playClass,当然是播放声音、然后设置动画效果;pauseClass则反之,停止这个声音、把激活的样式渐变为原来未激活的样式。

将ckeyClass传给两个声音处理函数playSoundName、declineSoundName,两个动画处理函数animatePlaying、animatePausing。

这里使用try{}catch语句来判断如果没有要播放的声音,就不会播放动画效果。防止有些不正确的设置,播放不出声音又显示了动画,就会显得别扭。

 

4、playSoundName和declineSoundName

这一部分就是声音处理了,之所以要用decline而不直接停止掉声音,是因为如果直接停止,就会感觉非常别扭。

利用javascript的延迟处理函数setTimeout()来逐渐减弱声音,而当此声音还没减弱完,又要再次播放时,就用clearTimeout()来删除这个延迟执行的函数。

 

5、animatePlaying和animatePausing

这是我最绞尽脑汁的两个函数。首先说要达到的效果,animatePlaying使按下的元素立马变成激活状态的样式,animatePausing再使这个元素缓慢变回(即渐变)原来的样式。

经过一番思考,写出如下的函数:

即经过如下两个变换,达成所需的效果

这里用到的就是css3 transition,在animatePausing退回原来的样式时加入transition:all 1s;,产生1s的渐变效果。
另外,其中ckeyClass2realClass, realClass2jQSelector用于把ckeyClass转换为元素真正的类,再转换为jQuery选择器用于选择这些元素。函数及示例如下:

6、将键盘按键与ckey绑定

这一部分就很简单了,获取所有绑定了按下/弹起键的元素,即keyCode2getClasses来完成这一功能;再将getClasses中每一个getClass转化为ckeyClass传递给downClass、upClass即可。

7、控制键部分设计

这一部分由于有了getClass2ckeyClass的转化,直接选择相应的组进行处理就行了。

 

js部分就完成了,html部分就很简单了,把原来的琴键元素直接类改成【ckey ckey-key-音名-分组 ckey-code-绑定的按键keyCode】就完成了。

从构思到完成cPiano 2.0,总共花了大概两天时间,为自己的一点小想法付出点时间,完成它也是很有成就感的一件事呢~

本文地址:https://xsaiting.com/cpiano2.html
版权声明:本文为原创文章,版权归 小赛艇 所有,转载请保留出处!
喜欢请点赞/打赏/分享这篇文章哦!

发表评论


表情