Arthur Alunts Asked:2020-03-18 22:45:19 +0000 UTC2020-03-18 22:45:19 +0000 UTC 2020-03-18 22:45:19 +0000 UTC 是否有可能用 javascript 激发这样一个项目?[关闭] 772 Portal - Still Alive 你能给出至少一些库的链接吗? javascript 1 个回答 Voted Best Answer Опан 2020-03-19T03:23:30Z2020-03-19T03:23:30Z 能。我想用 JavaScript 和 CSS 提供一架钢琴。您可以使用鼠标或计算机键盘进行游戏,也可以自动进行。钢琴上的琴键与电脑上的琴键的对应关系以符号的形式显示在钢琴的虚拟琴键上。不要长时间按住电脑键盘上的按键,因为会出现重复按下的情况,就像在写文字时一样。如何最好地摆脱这个,还没有决定。钢琴具有立体声音,具有空间中琴键位置的效果。支持多达六个同时发声的复音音符。如果同时按下多个键,控制台会报错。按下时,模仿三根弦的声音,调到同一个音符,但有一定的误差,误差的程度取决于失谐变量的值。模仿真正钢琴的右踏板,取决于 rightPedal 变量——不按下时,松开琴键后音符停止发声,如果按下,则继续发声,直到消失。缺点是如果没有足够的可用 RAM,它会冻结。 <!DOCTYPE html> <html> <head> <meta charset="windows-1251"> <title>Пианино</title> <style> .white_keys{ position: absolute; background: white; border: 2px solid; width: 25px; height: 200px; top: 0px; border-radius: 0px 0px 5px 5px; z-index: 0; text-align: center; line-height: 200px; -webkit-user-select: none; -moz-user-select: none; } .white_keys:hover{ background: #eee; } .black_keys{ position: absolute; background: black; border: 2px solid; border-color: #333; width: 15px; height: 130px; top: 0px; border-radius: 0px 0px 7px 7px; z-index: 1; color: white; text-align: center; line-height: 130px; -webkit-user-select: none; -moz-user-select: none; } .black_keys:hover{ background: #333; } </style> </head> <body bgcolor=#ccc><center><h3>Пианино</h3> <button id=start1 onclick="playDemo(demoString1)"> Старт демо-1 </button> <button id=start2 onclick="playDemo(demoString2)"> Старт демо-2 </button> <button onmousedown="clearInterval(demo);start1.disabled=start2.disabled=false;noteDuration=1500"> Стоп демо </button><br><br> <div id=piano style="position:absolute;left:50%;margin-left:-300px"></div> <script> var rightPedal = true, // Нажата ли правая педаль transpoze = 0, // Можно использовать для изменения тональности volume = 0.07, // Громкость camerton = 110, // Для точной настройки стандартных частот нот detune = 1.005, // Погрешность настройки струн fadeOut = 1.00004, // От этого зависит время затухания клавиш noteDuration = 1500, // Длительность нот stereo = 50, // Стереоэффект pan = 1.5, // Стереопанорама в пределах 0 - 2 с дробью lastPressed = lastReleased = 0, // ID последних нажатой и отжатой клавиш whiteIndex = 0; myDown = false; var frameCount = noteDuration * 44.1; var akkord = [], str = [], fm = [], samples = []; var symbols = "zsxdcvgbhnjm,l.;/q2w3e4rt6y7ui9o0p-[]", demoString1 = "VVgcbWFwXG1YE29XWl9tWmtXDm1SVVrDv1XDv1JOUlVew79aw79V&1500&300", demoString2 = "cnFyCXAOcg12DnACcg52DXAOcgIOdg5wAw0Pcg52BFAOdAYNEhgacg5wB24Obw10Dm4Cbw50DW4ObwcTdA5uCBQNGm8OdAlVDm4LDRcabw50CTB2w78SGBowdTB2QjB1EhgaMHbDvwkwecO/EhgaMHgweUIweBIYGjB5w78HEy8yd8O/BlLDvwRQw78CTgdTw78HUwZSw78EUHICDnFyCXAOcg12DnACcg52DXAOcgIOdg5wAw0Pcg52BFAOdAYNEhgacg5wB24Obw10Dm4Cbw50DW4ObwcTdA5uCBQNGm8OdAlVDm4LDRcabw50CHRsFBcab3REchQXGnBvCW1sFRgcbXREbRUYHHB0B2NmFBcaa29Cam3DvxMjJmvDv8O/w78HLzJ3&400&130", keyAsociateEncode = "WlNYRENWR0JITkpNwrxMwr7CusK/UTJXM0U0UlQ2WTdVSTlPMFDCvcObw50="; var keyAsociate = decodeURIComponent(escape(window.atob(keyAsociateEncode))); for (var i = 0; i < 37; i++){ var key = document.createElement("div"); key.id = i + 12; var n = i - 12 * Math.floor(i / 12); var keyColor = (n == 1 || n == 3 || n == 6 || n == 8 || n == 10 ? 1 : 0); if(keyColor == 1){ key.className = "black_keys"; }else{ key.className = "white_keys"; whiteIndex++; } key.setAttribute("data-color", keyColor); key.setAttribute("data-left", (19 * keyColor + 28 * whiteIndex) - 36); key.style.left = key.dataset.left + "px"; key.innerHTML = symbols[i]; key.onmousedown = function(){ akkord[0] = this.id; downKey(akkord); } key.onmouseup = function(){ akkord[0] = this.id; upKey(akkord); } key.onmouseout = function(){if(myDown == true)changeStateKey(this, 0)}; document.getElementById("piano").appendChild(key); } for (var i = 0; i < 60; i++){ var amplitude = 1; var resonance = 1; var polarity = 1; var f = Math.pow(1.06, i); // Стандартная частота ноты с номером в i samples.push([]); for (var h = 0; h < 3; h++)str[h] = Math.pow(detune, Math.random() * 2 - 1); for (var j = 0; j < frameCount; j++) { if(Math.sin(j / camerton * f) * polarity < 0){ polarity = -polarity; resonance = 1; } amplitude /= fadeOut; resonance /= 1.01; for (var h = 0; h < 3; h++)fm[h] = 50 * Math.sin( j / camerton * f * Math.floor(12 / f) * str[h]) * resonance; samples[i][j] = 0; for (var h = 0; h < 3; h++) { var garmony = (j + fm[h]) / camerton * f * str[h]; samples[i][j] += Math.sin(garmony) + Math.sin(garmony * 2); } samples[i][j] *= volume * amplitude; } } document.onmousedown = function(){myDown = true}; document.onmouseup = function(){myDown = false}; document.onkeydown = function(e){ akkord[0] = keyAsociate.indexOf(String.fromCharCode(e.which)) + 12; if(akkord[0] > 11)downKey(akkord); } document.onkeyup=function(e){ akkord[0] = keyAsociate.indexOf(String.fromCharCode(e.which)) + 12; if(akkord[0] > 11)upKey(akkord); } function downKey(e){ // Нажатие клавиши пианино lastPressed = e[0].id; var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); audioCtx.sampleRate = 44100; var frameCount = audioCtx.sampleRate * noteDuration / 1000; var myArrayBuffer = audioCtx.createBuffer(2, frameCount, audioCtx.sampleRate); for (var c = 0; c < e.length; c++){ changeStateKey(document.getElementById(e[c]), 1); var stereoSeek = Math.floor((e[c] - 30) * stereo); for(lr = 0; lr < 2; lr++){ var nowBuffering = myArrayBuffer.getChannelData(lr); for (var s = 0; s < frameCount; s++){ var evolute = Math.min((lr * 2 - 1) * ((e[c] / 30) - 1) * pan + 1, 1); var sample = samples[parseInt(e[c]) + transpoze][s + stereoSeek * ( lr * 2 - 1)]; if(sample)nowBuffering[s] += sample * evolute; } } } var source = audioCtx.createBufferSource(); source.buffer = myArrayBuffer; source.connect(audioCtx.destination); source.start(); if(rightPedal == false){ var vPeriod = setInterval(function(){ if(lastReleased == lastPressed){ source.stop(); clearInterval(vPeriod); lastPressed = lastReleased = 0; } }, 200); } setTimeout(function(){audioCtx.close()}, noteDuration); } function upKey(e){ // Отжатие клавиши пианино lastReleased = e[0].id; for (var c = 0; c < e.length; c++)changeStateKey(document.getElementById(e[c]), 0); } function changeStateKey(id, act){ // Установка состояния клавиш if(id){ var colorBar = ["white", "#ffb", "black", "#009"]; // Цвета для разных состояний клавиш id.style.background = colorBar[parseInt(id.dataset.color) * 2 + act]; id.style.top = (act * 2) + "px"; id.style.left = (parseInt(id.dataset.left) + act) + "px"; } } function playDemo(demoString){ // Воспроизведение демок start1.disabled = start2.disabled = true; var demoArray = demoString.split("&"); var dbs = decodeURIComponent(escape(window.atob(demoArray[0]))); noteDuration = demoArray[1]; var period = demoArray[2]; var tc = 0; // time counter demo = setInterval(function(){ if(dbs.charCodeAt(tc) != 255){ var akkord = []; while(dbs.charCodeAt(tc) < 64){ akkord.push(dbs.charCodeAt(tc)); tc++; } akkord.push(dbs.charCodeAt(tc) - 64); tc++; downKey(akkord); setTimeout(function(){upKey(akkord)}, period * 0.75); }else{ tc++; } if(tc == dbs.length){ clearInterval(demo); start1.disabled = start2.disabled = false; noteDuration = 1500; } }, period); } </script> </body> </html>
能。我想用 JavaScript 和 CSS 提供一架钢琴。您可以使用鼠标或计算机键盘进行游戏,也可以自动进行。钢琴上的琴键与电脑上的琴键的对应关系以符号的形式显示在钢琴的虚拟琴键上。不要长时间按住电脑键盘上的按键,因为会出现重复按下的情况,就像在写文字时一样。如何最好地摆脱这个,还没有决定。钢琴具有立体声音,具有空间中琴键位置的效果。支持多达六个同时发声的复音音符。如果同时按下多个键,控制台会报错。按下时,模仿三根弦的声音,调到同一个音符,但有一定的误差,误差的程度取决于失谐变量的值。模仿真正钢琴的右踏板,取决于 rightPedal 变量——不按下时,松开琴键后音符停止发声,如果按下,则继续发声,直到消失。缺点是如果没有足够的可用 RAM,它会冻结。