webmidi+shake+svg实现音乐可视化绘制谱曲效果代码
代码语言:html
所属分类:多媒体
代码描述:webmidi+shake+svg实现音乐可视化绘制谱曲效果代码,点击上面的曲线拖动鼠标进行音乐轨道绘制,可以切换不同的频率和声音,最终点击播放按钮可以播放自己绘制的曲谱。
代码标签: webmidi shake svg 音乐 可视化 绘制 谱曲
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
*{box-sizing:border-box}body{background:#222;margin:0;width:100vw;height:100vh;overflow:hidden}nav{background:#000;position:absolute;width:64px;bottom:0;top:0}nav svg{width:64px;height:64px}main svg{width:100%;height:100%}main{position:absolute;left:64px;top:0;cursor:crosshair;bottom:0;right:0}nav ul{z-index:2;margin:0;padding:0;width:100%;height:100%;display:flex;flex-wrap:wrap;align-items:center;align-content:center;justify-content:center;list-style:none}nav ul li{display:block}nav a.selected>svg,nav a.selected>svg{background:#333}svg.move{cursor:move}#bounds{stroke:mediumseagreen;stroke-width:1px}#cursor{stroke:white;stroke-width:1px}#grid{stroke:#333;stroke-width:1px;fill:none}.hidden{display:none}@media only screen and (orientation:landscape){nav{height:64px;width:100vw;bottom:auto}main{left:0;top:64px;right:0;bottom:0}}.overlay{position:absolute;top:0;left:0;right:0;bottom:0;display:none;background:rgba(0,0,0,0.5)}.overlay__tap2start{height:100vh;font-family:sans-serif;color:#fff;display:flex;justify-content:center;align-items:center;font-size:10vw}
</style>
</head>
<body>
<svg id="symbols"><symbol id="square" viewBox="0 0 128 128"><path style="fill:none;stroke:#aad400;stroke-width:4px;stroke-linecap:square;" d="M35,43 l0,40 l30,0 l0,-40 l30,0 l0,40" /></symbol><symbol id="sawtooth" viewBox="0 0 128 128"><path style="fill:none;stroke:#c83737;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;" d="M30,80 l30,-40 l0,40 l30,-40 l0,40"/></symbol><symbol id="triangle" viewBox="0 0 128 128"><path style="fill:none;stroke:#2a7fff;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;" d="M30,80 l17,-40 l17,40 l17,-40 l17,40"/></symbol><symbol id="sine" viewBox="0 0 128 128"><path style="fill:none;stroke:#9944ff;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;" d="M30,64 q17,-40 32,0 q17,40 32,0"/></symbol><symbol id="play" viewBox="0 0 128 128"><path style="stroke:#aad400;fill:none;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel" d="M33,30 l0,68 l68,-34z"/></symbol><symbol id="pause" viewBox="0 0 128 128"><rect style="stroke:#c83737;fill:none;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel" x="30" y="30" width="30" height="68"/><rect style="stroke:#c83737;fill:none;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;" x="68" y="30" width="30" height="68"/></symbol><symbol id="record" viewBox="0 0 128 128"><circle style="fill:#c83737" cx="64" cy="64" r="32"/></symbol><symbol id="rewind" viewBox="0 0 128 128"><path style="stroke:#4466ff;fill:none;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;" d="M30,64 l34,-34 l0,34 l34,-34 l0,68 l-34,-34 l0,34Z" /></symbol><symbol id="clrscr" viewBox="0 0 128 128"><path style="stroke:#c83737;stroke-width:4px;stroke-linecap:square;fill:none;" d="M30,30 l68,68 M30,98 l68,-68"/></symbol><symbol id="move" viewBox="0 0 128 128"><path style="stroke:#4488ff;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;fill:none;" d="M30,30 l20,0 l-20,20 l0,-20 l68,68 l0,-20 l-20,20 l 20,0 M30,98 l0,-20 l20,20 l-20,0 l68,-68 l0,20 l-20,-20 l20,0"/></symbol><symbol id="cloud" viewBox="0 0 128 128"><path style="stroke:#44ccff;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;fill:none;" d="M30,64 q12,0 12,-8 q0,-16 16,-16 q16,0 16,16 q24,0 24,16 q0,16 -16,16 l-42,0 q-16,0 -16,-18 Z"/></symbol><symbol id="disk" viewBox="0 0 128,128"><path style="stroke:#44ccff;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;fill:none;" d="M30,30 l52,0 l16,16 l0,52 l-68,0 l 0,-68 M40,30 l0,24 l36,0 l0,-24 M48,30 l0,16 l6,0 l0,-16 M40,98 l0,-30 l48,0 l0,30"/></symbol><symbol id="open" viewBox="0 0 128,128"><path style="stroke:#ffcc33;stroke-width:4px;stroke-linecap:square;stroke-linejoin:bevel;fill:none;" d="M30,98 l15,-30 l60,0 l-15,30 l-60,0 l0,-45 l8,-8 l8,0 l8,8 l36,0 l0,15"/></symbol><symbol id="noise" viewBox="0 0 128 128"><path id="p" d="M30,92.5L32,59.5L34,42L36,32.5L38,35.5L40,41.5L42,84.5L44,60.5L46,52.5L48,77.5L50,88L52,53.5L54,79L56,57.5L58,59L60,37.5L62,45.5L64,88L66,53L68,72L70,90L72,91.5L74,95.5L76,51.5L78,95.5L80,50.5L82,44.5L84,93L86,52L88,61" style="fill:none;stroke:#fff;stroke-width:4px;"></path></symbol></svg>
<nav>
<ul>
<li><a id="rewBtn" title="rewind" href="#"><svg><use xlink:href="#rewind"/></svg></a></li>
<li><a id="playBtn" title="play" href="#"><svg><use xlink:href="#play"/></svg></a></li>
<li class="hidden"><a id="pauseBtn" href="#"><svg><use xlink:href="#pause"/></svg></a></li>
<li><a role="type" href="#sine" title="sine"><svg><use xlink:href="#sine"/></svg></a></li>
<li class="hidden"><a role="type" href="#sawtooth" title="sawtooth"><svg><use xlink:href="#sawtooth"/></svg></a></li>
<li class="hidden"><a role="type" href="#triangle" title="triangle"><svg><use xlink:href="#triangle"/></svg></a></li>
<li class="hidden"><a role="type" href="#square" title="square"><svg><use xlink:href="#square"/></svg></a></li>
<li class="hidden"><a role="type" href="#noise" title="noise"><svg><use xlink:href="#noise"/></svg></a></li>
<li><a id="moveBtn" href="#move" title="move"><svg><use xlink:href="#move"/></svg></a></li>
<li><a id="clrBtn" href="#clear" title="clear screen"><svg><use xlink:href="#clrscr"/></svg></a></li>
<li><a id="dlBtn" href="#disk" title="save"><svg><use xlink:href="#disk"/></svg></a></li>
<li><a id="ulBtn" href="#disk" title="open"><svg><use xlink:href="#open"/></svg><input id="inputFile" type="file" class="hidden" accept="image/svg+xml"/></a></li>
</ul>
</nav>
<main><svg id="main"><path id="grid" /><path id="bounds"/><path id="cursor"/></svg></main>
<div class="overlay">
<div class="overlay__tap2start">tap to start </div>
</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/shake.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/webmidi.min.js"></script>
<script>
const isDebug = /debug/.test(window.location.href);
const w3 = "http://www.w3.org/";
const svgNS = w3 + "2000/svg";
const xlinkNS = w3 + "1999/xlink";
const notes = "C C# D D# E F F# G G# A A# B".split(" ");
let w, h;
let scrollX = 0,scrollY = 0,cursorX = 0;
const borders = { l: 0, r: 250 };
const borderExtend = 250;
let moveMode = null;
let playing = false;
const d = document;
const $ = document.querySelector.bind(d);
const $$ = (sel, con) => Array.prototype.slice.call((con || d).querySelectorAll(sel));
const { sqrt, min, max } = Math;
const distance = (a, b) => sqrt((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2);
const freq = y => max(880 - y, 10);
const freqToY = f => 880 - f;
const svg = $`#main`;
let masterVolume;
let AC = new AudioContext();
const defaultVolume = 0.5;
const initAudioContext = () => {
if (AC.state === "suspended") {
$`.overlay`.style.display = 'block';
$`.overlay`.addEventListener('click', () => {
$`.overlay`.style.display = 'none';
AC.resume();
});
}
masterVolume = AC.createGain();
masterVolume.gain.value = defaultVolume;
masterVolume.connect(AC.destination);
};
initAudioContext();
const music = [];
let mouseNoise = null;
let touchNoises = [];
let midiNoises = {};
let currentType = "sine";
let clientRect = svg.getBoundingClientRect();
Array.prototype.avg = function () {
let r = 0,i = 0;
for (i = 0; i < this.length; i++)
r += this[i];
return r / this.length;
};
const typeColors = {
"sine": "#9944ff",
"square": "#aad400",
"sawtooth": "#c83737",
"triangle": "#2a7fff",
"noise": "#ffffff" };
const noteToFreq = (note, octave) => {
const n = typeof note === "string" ? notes.indexOf(note.replace(/_/, '')) : n;
const f = 110 * 2 ** octave * 2 ** ((n + 3) / 12);
return f;
};
const hexColor = c => {
if (c.slice(0) === '#') return c;
if (c.slice(0, 4) === 'rgb(') {
return "#" + c.slice(4, -1).split(",")..........完整代码请登录后点击上方下载按钮下载查看
网友评论0