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