缘起

由于童心未泯,之前在手机上玩过钢琴模拟App,但是手机屏幕太小,始终觉得不过瘾。其实对于我这个连基本乐理都不懂的“乐盲”来说,就算给我一台真正的钢琴,我也玩不转。不过是图个新鲜、权当娱乐罢了。最近刚好入手一台带触摸屏的Lenovo Yoga 4 Pro,这倒给了我新的想象空间:大屏幕玩起来是不是更带感?在Win10应用商店里搜了下,还真有各种模拟钢琴的应用,随便选了一款安装。结果非常令人失望,音效惨不忍听,还各种闪退。这里顺便吐槽下win10的应用商店,里面的很多应用不是经常安装失败,就是经常闪退,简直没法用啊。作为一名前端开发和坚定的Web支持者,客户端不好用果断转向Web啊。本着尽量不重造轮子的原则,先在网上搜了一下。百度的搜索结果几乎都是那一个例子,也不知道是哪位哥们写的,被到处引用。就那么几个键,怎么玩?Google的结果也不尽如人意,不是打不开就是加载半天。算了,还是自己动手吧。

准备

我们知道,HTML5有音频接口,播放声音自然不在话下。这模拟钢琴自然需要各种音阶的音频文件吧,于是在网上搜了一通,找齐了88键钢琴的音频文件。为什么钢琴有88个键?别问我,我是乐盲。看看这张钢琴示意图就知道了:

开工

最近一直在用Vue.js开发项目,配合Webpack神器构建打包,开发前端项目从来没有如此方便。在此要特别感谢Vue.js的作者Evan You尤雨溪(知乎), 给我们贡献了这么好用的框架。
新建一个Vue.js项目非常简单,可以用官方推荐的脚手架命令行工具vue-cli创建新工程。首先安装这个工具:

npm install -g vue-cli

安装好后执行命令生成工程模板:

vue init webpack piano

这里我们用webpack作为构建工具,你也可以使用browserify。
就这么简单,一个Vue.js project诞生了,而且Webpack已经配置好。接下来执行命令安装相关的node模块:

npm install

如果一切顺利的话,项目就可以跑起来了:

npm run dev

访问http://localhost:8080就可以看到默认的欢迎界面。至此,项目的搭建算是完成了。

界面

现在开始写界面。虽然是乐盲,钢琴键盘上有哪些键还是要搞清楚的。对于标准的88键钢琴,总共有88个键,其中52个白色键,36个黑色键。分为低音区、中音区和高音区,每个区有三组。对于我们画界面来说,重要的是找出其中的规律。最两端的两组先不管,其他的分组看上去都是一样的:三白夹两黑跟着四白夹三黑。

怎么实现这个界面布局呢?很简单,黑白键都用button元素表示,设置好宽高、背景色和边框。白色的自然定位并排铺开,黑色的用绝对定位,计算出对应的坐标。这里有个小细节,就是黑白键的DOM元素排列最好跟各音阶的先后顺序对应,这样在计算黑键坐标就比较方便。
既然有七个组的界面是一模一样的,我们就把一组设计成一个组件好了。用Vue.js开发组件真的是太方便了,一个.vue文件包含HTML template、script和style,就构成了一个独立的组件。每组的音阶范围不一样,通过组件的props设定。来看组件的源码文件Group.vue

<template><div class="group"><button :class="{'white': whites.indexOf(n) > -1, 'black': blacks.indexOf(n) > -1}" v-for="n in 12" :style="{ left: calcLeft(n) + '%' }" data-note="{{start+n}}" @click="play(start+n)"><span v-show="n === 0">C</span></button></div>
</template><script>
import {notes} from '../notes.js';
const prefix = 'data:audio/mpeg;base64,';
const base = 3;
const keys = 12;
export default {props: {group: {type: Number,default: 0}},data() {return {// note: changing this line won't causes changes// with hot-reload because the reloaded component// preserves its current state and we are modifying// its initial state.blacks: [1, 3, 6, 8, 10],whites: [0, 2, 4, 5, 7, 9, 11]}},computed: {start() {return this.group * keys;}},methods: {play(index) {var audio = new Audio(prefix + notes[index + base]);audio.play();},calcLeft(index) {var unit = 14.29;var i = this.blacks.indexOf(index);if(i < 2) {return unit * (0.75 + i);}return unit * (1.75 + i);},click(index) {}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>.group {font-size: 0;position: relative;display: flex;flex-grow: 1;}button {width: 14.29%;flex: 1;height: 300px;display: inline-block;border: 1px solid #ccc;outline: 0;padding: 0;box-sizing: border-box;}button > span {position: absolute;bottom: 10px;}.white:active,.white.active {background: #ececec;}.white {background: #fff;}.black {background: #000;border-color: #000;height: 150px;width: 7.15%;position: absolute;}
</style>

逻辑并不复杂,关键是处理细节。按键的宽度是用百分比的,高度固定。黑键的坐标计算逻辑在方法calcLeft里,具体看代码好了,code will talk.
你可能有个疑问:音频内容哪来的?继续看。

音频处理

前面提到过,我从网上找到了钢琴的88音阶的音频文件,都是mp3格式的。但是我不想让88个音分散在88个.mp3文件里,不然在弹奏的时候一个个文件下载,可不太好。怎么办呢?我们知道图片可以转成base64的字符串显示在DOM里。其实音频文件也一样,用data:audio/mpeg;base64,XXXXXX就可以了。写了个Node程序,一次性将所有Mp3文件都转成了base64字符串数组备用:

var fs = require('fs');
var file = 'notes.json';// function to encode file data to base64 encoded string
function base64_encode(file) {// read binary datavar bitmap = fs.readFileSync(file);// convert binary data to base64 encoded stringreturn new Buffer(bitmap).toString('base64');
}fs.readdir('.', function(error, files) {var content = "";files.forEach((f, index) => {if(/^\d/.test(f)) {var data = base64_encode(f);content += `"${data}",\n`;}});fs.writeFileSync(file, content);
});

数组内容放在一个单独的文件里,作为模块引入。数组元素的顺序就是音阶从低到高的顺序。HTML5的Audio对象,支持从构造函数传入base64数据,然后调用play()就可以播放声音了。
没有触摸屏咋玩?还有键盘啊。简单起见,用三排字母按键对应中音区的三个组。监听键盘keydown事件,通过keyCode区分不同的键,播放对应的音频内容就好了。

总结

这个过程并不复杂,就是布局和音频处理需要处理一些细节。代码写得很仓促,有些地方可以重构下。完整的源码可以在我的Github找到。喜欢的欢迎star,有闲工夫也可自己改进。最终效果点击这里:http://kaysonli.github.io/piano/dist/

转载于:https://www.cnblogs.com/lzkwin/p/5794896.html

用Vue.js和Webpack开发Web在线钢琴相关推荐

  1. go html vue,用Go+Vue.js快速搭建一个Web应用(初级demo)

    Vue.js做为目前前端最热门的库之一,为快速构建并开发前端项目多了一种思维模式.本文给大家介绍用Go+Vue.js快速搭建一个Web应用(初级demo). 环境准备: 1. 安装go语言,配置go开 ...

  2. Vue.js组件化开发实践

    Vue.js组件化开发实践 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了一下的内容.首先会对使用Vue进行开发的一 ...

  3. 计算机英语介绍项目,【精品文档】614关于计算机专业Vue.js应用程序设计开发介绍简介概述的毕业设计论文英文英语外文文献翻译成品资料:了解Vue.js项目和工具(中英文双语对照)...

    1.本文是中英对照毕业设计论文外文文献翻译,下载后直接可用!省去您找文献.pdf整理成word以及翻译的时间,一辈子也就一次的事!文献引用作者出处信息:Freeman, Adam Pro Vue.js ...

  4. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(4.1-4.10)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(4.1-4.10) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://git ...

  5. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.11-3.12)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.11-3.12) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://gi ...

  6. Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台

    前言 最近在跟着Johnny的全栈之巅系列视频教程学习使用NodeJS+Express+Element-UI+MongoDB等开发王者荣耀,服务端server,移动端web,admin,学到了不少东西 ...

  7. 学习【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台笔记(1.1-2.5)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://gitee.com/blaunic ...

  8. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.6-3.10)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.6-3.10) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://git ...

  9. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.16-3.20)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.16-3.20) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://gi ...

  10. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.13-3.15)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(3.13-3.15) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://gi ...

最新文章

  1. 计量注册师考试一些关于期限、时间、机构的总结
  2. IDEA快捷键及基本使用方法
  3. spring_了解Spring Web应用程序体系结构:经典方法
  4. 河南王牌计算机专业,河南计算机专业实力突出的7所大学,郑大位列次席,榜首实至名归...
  5. c语言录像带课程设计,2019信息技术真题共16页word资料
  6. Elasticsearch 嵌套类型nested
  7. 舵机任意角度程序_【舵机初动】基于Mind+ Ardunio入门教程10
  8. java day57【 Spring 概述 、 IoC 的概念和作用、使用 spring 的 IOC 解决程序耦合 】...
  9. 拓端tecdat|R语言用神经网络改进Nelson-Siegel模型拟合收益率曲线分析
  10. java 框架_java三大主流框架是什么
  11. CentOS7或7以上,无iptable解决方法
  12. 【翻译】steam离线时通过局域网游玩L4D2(求生之路2)
  13. 2020德勤面试开始了吗_刚去四大(德勤)面试,我只说了三个字,就拿到了offer!...
  14. 英语模板作文,词组,句子,句型,开头
  15. 安装jdk在linux(2)
  16. Redis相关面试题
  17. 第一篇,从0开始安装Ubuntu
  18. 回首风雨路 笔记本二十年发展史
  19. c语言while语句1阶层加到10阶层,用C++编程:1的阶层加到10的阶层,使用For语句,还有While和Do While语句编程!!...
  20. 奥迪q5计算机控制显示,奥迪q5仪表盘功能图解,奥迪q5仪表盘怎么切换

热门文章

  1. 小程序 长按转发_小程序转发分享
  2. linux 进程的pid分配策略——pid位图算法
  3. io 流 txt本地生成
  4. jQuery操作属性的相关方法
  5. [渝粤教育] 武汉理工大学 金属工艺学B 参考 资料
  6. 【渝粤教育】国家开放大学2018年春季 0049-21T法律文书 参考试题
  7. 【渝粤教育】电大中专电子商务网站建设与维护 (17)作业 题库
  8. 【渝粤教育】广东开放大学 机械制造基础 形成性考核 (54)
  9. Python进阶(十)多进程multiprocessing和subprocess模块
  10. SVD在推荐系统中的应用【推荐】