Playable Piano Keyboard with Demos

Developer
Size
10,019 Kb
Views
8,096

How do I make an playable piano keyboard with demos?

Playable piano/keyboard using HTML audio API. Includes demos of No Suprises, Life on Mars, Für Elise and The Entertainer.. What is a playable piano keyboard with demos? How do you make a playable piano keyboard with demos? This script and codes were developed by Adam on 28 November 2022, Monday.

Playable Piano Keyboard with Demos Previews

Playable Piano Keyboard with Demos - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Playable Piano Keyboard with Demos</title> <link href="https://fonts.googleapis.com/css?family=Condiment" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="wrap"> <!--Controls--> <div class="controls-container"> <div class="speakers"></div> <div class="controls"> <div class="input-container"> <h2>Keyboard 5000</h2> <div class="input-buttons"> <div class="demo-buttons"> <div> <button class="demo-button demo1"></button> <div>1</div> </div> <div> <button class="demo-button demo2"></button> <div>2</div> </div> <div> <button class="demo-button demo3"></button> <div>3</div> </div> <div> <button class="demo-button demo4"></button> <div>4</div> </div> <div> <button class="help"></button> <div>Help</div> </div> </div> <div class="demo-label">Demos</div> </div> </div> <div class="inputs"> <input type="range" class="volume" step="0.1" min="0" max="1"></input> <input type="range" class="tempo" min="2" max="8"></input> </div> <div class="input-labels"> <div>Volume</div> <div>Tempo</div> </div> </div> <div class="speakers"></div> </div> <!--Keyboard--> <div class="keyboard"> <div data-note="c4" data-key="81" class="key white oct">q</div> <div data-note="db4" data-key="50" class="key black black1 oct">2</div> <div data-note="d4" data-key="87" class="key white oct">w</div> <div data-note="eb4" data-key="51" class="key black black2 oct">3</div> <div data-note="e4" data-key="69" class="key white oct">e</div> <div data-note="f4" data-key="82" class="key white oct">r</div> <div data-note="gb4" data-key="53" class="key black black3 oct">5</div> <div data-note="g4" data-key="84" class="key white oct">t</div> <div data-note="ab4" data-key="54" class="key black black4 oct">6</div> <div data-note="a4" data-key="89" class="key white oct">y</div> <div data-note="bb4" data-key="55" class="key black black5 oct">7</div> <div data-note="b4" data-key="85" class="key white oct">u</div> <div data-note="c5" data-key="88" class="key white">x</div> <div data-note="db5" data-key="68" class="key black black6">d</div> <div data-note="d5" data-key="67" class="key white">c</div> <div data-note="eb5" data-key="70" class="key black black7">f</div> <div data-note="e5" data-key="86" class="key white">v</div> <div data-note="f5" data-key="66" class="key white">b</div> <div data-note="gb5" data-key="72" class="key black black8">h</div> <div data-note="g5" data-key="78" class="key white">n</div> <div data-note="ab5" data-key="74" class="key black black9">j</div> <div data-note="a5" data-key="77" class="key white">m</div> <div data-note="bb5" data-key="75" class="key black black10">k</div> <div data-note="b5" data-key="188" class="key white">,</div> <div data-note="c6" data-key="190" class="key white">.</div> </div>
</div> <script src="js/index.js"></script>
</body>
</html>

Playable Piano Keyboard with Demos - Script Codes CSS Codes

html { font-family: 'Condiment', cursive; text-align: center; font-size: 20px;
}
@media (max-width: 700px) { html { font-size: 14px; }
}
@media (max-width: 500px) { html { font-size: 10px; }
}
body { background-color: #666;
}
.wrap { display: flex; flex-direction: column; max-width: 1000px; margin: 50px auto; background: #111; border-radius: 10px; box-shadow: 10px 2px 10px #090909, 2px 10px 10px #090909;
}
.controls-container { display: flex; width: 100%; justify-content: space-around;
}
.speakers { width: 200px; height: 5px; background: #000; margin: 40px 0 0; box-shadow: 0 15px #000, 0 30px #000, 0 45px #000, 0 60px #000, 0 75px #000;
}
@media (max-width: 600px) { .speakers { display: none; }
}
.controls { width: 600px; color: white; display: flex; flex-direction: column; align-items: center;
}
.controls .input-container { display: flex;
}
.controls .input-container h2 { font-size: 1.48rem;
}
.controls .input-container .input-buttons { padding: 1em 0 0 2.5em;
}
.controls .input-container .input-buttons .demo-buttons { display: flex;
}
.controls .input-container .input-buttons .demo-label { padding-right: 40px;
}
.controls .input-container .input-buttons button { background: #7f0101; border-radius: 5%; border: none; padding: 10px 20px; margin: 0 2px 5px; cursor: pointer;
}
.controls .input-container .input-buttons button.on { background: #e40202; box-shadow: 0px 0px 2px 2px #b20101;
}
.controls .input-container .input-buttons button.help { background: #006b10;
}
.controls .input-container .input-buttons button.help.on { background: #00d11f; box-shadow: 0px 0px 2px 2px #00d11f;
}
.controls .inputs { display: flex;
}
.controls .inputs input { padding: 0 10px;
}
.controls .inputs input.tempo { transform: rotateY(180deg);
}
.controls .input-labels { display: flex; justify-content: space-around;
}
.controls .input-labels > div { padding: 0 4.5em;
}
.keyboard { width: 95%; height: 160px; display: flex; margin: 10px auto 10px; position: relative;
}
.white, .black { display: flex; align-items: flex-end; justify-content: center; font-size: 2rem; border-radius: 5px; border: 2px solid black; font-family: sans-serif;
}
.white { height: 100%; width: 12.5%; background-color: ivory; box-shadow: 2px 7px 2px #222222;
}
.white.played { background-color: #DDDDDD; transform: translate(0, 2px);
}
.black { height: 70%; width: 3%; position: absolute; z-index: 2; margin-left: -1.6%; background-color: black; color: white;
}
@media (max-width: 600px) { .black { width: 6%; }
}
.black.played { background-color: #333333; transform: translate(0, 2px);
}
.black.black1 { left: 6.7%;
}
.black.black2 { left: 13.3%;
}
.black.black3 { left: 26.7%;
}
.black.black4 { left: 33.4%;
}
.black.black5 { left: 40%;
}
.black.black6 { left: 53.3%;
}
@media (max-width: 600px) { .black.black6 { left: 11%; }
}
.black.black7 { left: 60%;
}
@media (max-width: 600px) { .black.black7 { left: 23%; }
}
.black.black8 { left: 73.3%;
}
@media (max-width: 600px) { .black.black8 { left: 48.5%; }
}
.black.black9 { left: 80%;
}
@media (max-width: 600px) { .black.black9 { left: 61%; }
}
.black.black10 { left: 86.7%;
}
@media (max-width: 600px) { .black.black10 { left: 73%; }
}
@media (max-width: 600px) { .oct { display: none; }
}
input[type=range] { -webkit-appearance: none; margin: 10px 0; width: 100%;
}
input[type=range]:focus { outline: none;
}
input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 2px; cursor: pointer; animate: 0.2s; box-shadow: 1px 1px 1px #000000; background: #000000; border-radius: 0px; border: 1px solid #000000;
}
input[type=range]::-webkit-slider-thumb { box-shadow: 1px 1px 1px #000000; border: 1px solid #000000; height: 20px; width: 10px; border-radius: 5px; background: #808080; cursor: pointer; -webkit-appearance: none; margin-top: -10px;
}
input[type=range]:focus::-webkit-slider-runnable-track { background: #000000;
}
input[type=range]::-moz-range-track { width: 100%; height: 2px; cursor: pointer; animate: 0.2s; box-shadow: 1px 1px 1px #000000; background: #000000; border-radius: 0px; border: 1px solid #000000;
}
input[type=range]::-moz-range-thumb { box-shadow: 1px 1px 1px #000000; border: 1px solid #000000; height: 20px; width: 10px; border-radius: 5px; background: #808080; cursor: pointer;
}
input[type=range]::-ms-track { width: 100%; height: 2px; cursor: pointer; animate: 0.2s; background: transparent; border-color: transparent; color: transparent;
}
input[type=range]::-ms-fill-lower { background: #000000; border: 1px solid #000000; border-radius: 0px; box-shadow: 1px 1px 1px #000000;
}
input[type=range]::-ms-fill-upper { background: #000000; border: 1px solid #000000; border-radius: 0px; box-shadow: 1px 1px 1px #000000;
}
input[type=range]::-ms-thumb { box-shadow: 1px 1px 1px #000000; border: 1px solid #000000; height: 20px; width: 10px; border-radius: 5px; background: #808080; cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower { background: #000000;
}
input[type=range]:focus::-ms-fill-upper { background: #000000;
}

Playable Piano Keyboard with Demos - Script Codes JS Codes

"use strict";
/* HTML Audio API responsive piano/keyboard -TO DO test on mobile Demo 1 - No Suprises - Radiohead Demo 2 - Life on Mars - David Bowie Demo 3 - Für Elise - Ludwig van Beethoven Demo 4 - The Entertainer - Scott Joplin Increase tempo before you play a demo to play the song faster
*/
document.addEventListener("DOMContentLoaded", function () { //Frequencies list from http://www.phy.mtu.edu var frequencies = [["rest", 0], ["b3", 233.08], ["c4", 261.63], ["db4", 277.18], ["d4", 293.66], ["eb4", 311.13], ["e4", 329.63], ["f4", 349.23], ["gb4", 369.99], ["g4", 392.00], ["ab4", 415.30], ["a4", 440.00], ["bb4", 466.16], ["b4", 493.88], ["c5", 523.25], ["db5", 554.37], ["d5", 587.33], ["eb5", 622.25], ["e5", 659.25], ["f5", 698.46], ["gb5", 739.99], ["g5", 783.99], ["ab5", 830.61], ["a5", 880.00], ["bb5", 932.33], ["b5", 987.77], ["c6", 1046.50], ["d6", 1174.66], ["e6", 1318.51]]; //Songs //Note followed by note length. Crotchet = 100 var noSuprises = [["rest", 0], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["bb4", 50], ["db5", 50], ["f5", 50], ["g5", 50], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["a5", 50], ["c5", 50], ["f5", 50], ["c5", 50], ["bb4", 50], ["db5", 50], ["f5", 50], ["g5", 50], ["a4", 200], ["c4", 200], ["a4", 50], ["a4", 100], ["g4", 200], ["a4", 50], ["a4", 200], ["b3", 150], ["rest", 25], ["b3", 25], ["a4", 50], ["a4", 100], ["g4", 100], ["f4", 100], ["bb4", 200], ["d4", 200], ["e4", 50], ["e4", 100], ["f4", 100], ["g4", 100], ["a4", 250]]; var lifeOnMars = [["rest", 0], ["ab4", 50], ["bb4", 50], ["c5", 50], ["db5", 50], ["c5", 50], ["bb4", 100], ["ab4", 50], ["c5", 100], ["rest", 200], ["ab4", 50], ["bb4", 50], ["c5", 50], ["db5", 50], ["c5", 50], ["bb4", 100], ["ab4", 50], ["f5", 100], ["rest", 200], ["db5", 50], ["eb5", 50], ["f5", 50], ["gb5", 50], ["f5", 50], ["eb5", 100], ["db5", 50], ["f5", 150], ["rest", 150], ["db5", 50], ["eb5", 50], ["f5", 50], ["gb5", 50], ["f5", 50], ["eb5", 100], ["db5", 50], ["db5", 100], ["bb5", 200], ["f5", 200], ["eb5", 50], ["eb5", 50], ["eb5", 50], ["d5", 50], ["bb4", 100], ["c5", 100], ["rest", 50], ["bb5", 100], ["f5", 200], ["eb5", 50], ["eb5", 50], ["d5", 100], ["c5", 100], ["d5", 100], ["c5", 200], ["rest", 150], ["c5", 50], ["c5", 50], ["c5", 50], ["d5", 50], ["c5", 50], ["f5", 100], ["eb5", 25], ["d5", 25], ["c5", 100], ["rest", 150], ["bb4", 50], ["bb4", 50], ["bb4", 50], ["c5", 50], ["bb4", 100], ["bb5", 200], ["f5", 200], ["eb5", 50], ["eb5", 50], ["eb5", 50], ["d5", 50], ["bb4", 100], ["c5", 100], ["rest", 50], ["bb5", 100], ["f5", 200], ["eb5", 50], ["eb5", 50], ["eb5", 50], ["d5", 50], ["c5", 50], ["d5", 50], ["c5", 100], ["rest", 300], ["c5", 50], ["c5", 50], ["c5", 50], ["c5", 50], ["d5", 50], ["c5", 50], ["f5", 100], ["eb5", 25], ["d5", 25], ["c5", 100], ["rest", 200], ["bb4", 50], ["bb4", 50], ["bb4", 50], ["c5", 50], ["bb4", 100], ["bb5", 600]]; var furElise = [["rest", 0], ["e5", 25], ["eb5", 25], ["e5", 25], ["eb5", 25], ["e5", 25], ["b4", 25], ["d5", 25], ["c5", 25], ["a4", 50], ["rest", 25], ["c4", 25], ["e4", 25], ["a4", 25], ["b4", 50], ["rest", 25], ["e4", 25], ["ab4", 25], ["b4", 25], ["c5", 50], ["rest", 25], ["e4", 25], ["e5", 25], ["eb5", 25], ["e5", 25], ["eb5", 25], ["e5", 25], ["b4", 25], ["d5", 25], ["c5", 25], ["a4", 50], ["rest", 25], ["c4", 25], ["e4", 25], ["a4", 25], ["b4", 50], ["rest", 25], ["e4", 25], ["c5", 25], ["b4", 25], ["a4", 50], ["rest", 25], ["b4", 25], ["c5", 25], ["d5", 25], ["e5", 75], ["g4", 25], ["f5", 25], ["e5", 25], ["d5", 75], ["f4", 25], ["e5", 25], ["d5", 25], ["c5", 75], ["e4", 25], ["d5", 25], ["c5", 25], ["b4", 50], ["rest", 25], ["e4", 25], ["e5", 25], ["rest", 25], ["e5", 25], ["e6", 25], ["rest", 25], ["eb5", 25], ["e5", 50], ["rest", 25], ["eb5", 25], ["e5", 25], ["eb5", 25], ["e5", 25], ["eb5", 25], ["e5", 25], ["b4", 25], ["d5", 25], ["c5", 25], ["a4", 100]]; var theEntertainer = [["rest", 0], ["d6", 50], ["e6", 50], ["c6", 50], ["a5", 100], ["b5", 50], ["g5", 100], ["d5", 50], ["e5", 50], ["c5", 50], ["a4", 100], ["b4", 50], ["g4", 100], ["d5", 50], ["e5", 50], ["c5", 50], ["a4", 100], ["b4", 50], ["a4", 50], ["ab4", 50], ["g4", 100], ["rest", 50], ["g5", 100], ["d4", 50], ["d4", 50], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 300], ["c5", 50], ["d5", 50], ["eb5", 50], ["e5", 50], ["c5", 50], ["d5", 50], ["e5", 100], ["b4", 50], ["d5", 100], ["c5", 300], ["d4", 50], ["d4", 50], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 300], ["a4", 50], ["g4", 50], ["gb4", 50], ["a4", 50], ["c5", 50], ["e5", 100], ["d5", 50], ["c5", 50], ["a4", 50], ["d5", 300], ["d4", 50], ["d4", 50], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 100], ["e4", 50], ["c5", 300], ["c5", 50], ["d5", 50], ["eb5", 50], ["e5", 50], ["c5", 50], ["d5", 50], ["e5", 100], ["b4", 50], ["d5", 100], ["c5", 300], ["c5", 50], ["d5", 50], ["e5", 50], ["c5", 50], ["d5", 50], ["e5", 100], ["c5", 50], ["d5", 50], ["c5", 50], ["e5", 50], ["c5", 50], ["d5", 50], ["e5", 100], ["c5", 50], ["d5", 50], ["c5", 50], ["e5", 50], ["c5", 50], ["d5", 50], ["e5", 100], ["b4", 50], ["d5", 100], ["c5", 250]]; var demoButtons = Array.from(document.querySelectorAll('.demo-button')); var tempoInput = document.querySelector('.tempo'); var volumeInput = document.querySelector('.volume'); var blackKey = Array.from(document.querySelectorAll('.black')); var whiteKey = Array.from(document.querySelectorAll('.white')); var help = document.querySelector('.help'); var key = Array.from(document.querySelectorAll('.key')); var volume = 0.5; //Lower value = faster speed var tempo = 5; //Create new audio context when note played function playNote(note, length) { var AudioContext = window.AudioContext || window.webkitAudioContext, ctx = new AudioContext(), oscillator = ctx.createOscillator(), gainNode = ctx.createGain(); oscillator.type = 'triangle'; oscillator.frequency.value = note; gainNode.gain.value = volume; oscillator.connect(gainNode); gainNode.connect(ctx.destination); oscillator.start(0); //Trying to prevent popping sound on note end. Probably can be improved gainNode.gain.setTargetAtTime(0, length / 1000 - 0.05, 0.08); oscillator.stop(ctx.currentTime + (length / 1000 + 0.2)); oscillator.onended = function () { return ctx.close(); }; } //Finds clicked element returns data-note value and runs playKey function function onClickPlay(e) { var key = 0; var length = 300; var noteClass = e.target.dataset.note; for (var i = 0; i < frequencies.length; i++) { if (frequencies[i][0] === noteClass) { key = frequencies[i][1]; } } addVisual(e.target); playNote(key, length); } //Finds pressed key and returns data-note value function keyDownSearch(event) { var key = 0; var length = 300; var keyPressed = document.querySelector("div[data-key=\"" + event.keyCode + "\"]"); if (keyPressed === null) { return; } var note = keyPressed.dataset.note; for (var i = 0; i < frequencies.length; i++) { if (frequencies[i][0] === note) { key = frequencies[i][1]; } } addVisual(keyPressed); playNote(key, length); } //add each note to setinterval and playNote function demo(arr, e) { var noteLength = 0; e.target.classList.add('on'); tempoInput.disabled = true; demoButtons.forEach(function (btn) { btn.disabled = true; }); var _loop = function _loop(i) { noteLength += arr[i - 1][2] * tempo; setTimeout(function () { playNote(arr[i][1], arr[i][2] * tempo); if (arr[i][1] !== 0) { document.querySelector("[data-note=" + arr[i][0] + "]").classList.add('played'); } setTimeout(function () { if (arr[i][1] !== 0) { document.querySelector("[data-note=" + arr[i][0] + "]").classList.remove('played'); } if (arr.length - 2 < i) { e.target.classList.remove('on'); tempoInput.disabled = false; demoButtons.forEach(function (btn) { btn.disabled = false; }); } }, arr[i][2] * tempo - 0.05); }, noteLength); }; for (var i = 1; i < arr.length; i++) { _loop(i); } } //map notes in song to frequencies function findFrequencies(song, e) { var arr = []; song.forEach(function (note) { frequencies.forEach(function (frequency) { if (note[0] === frequency[0]) { arr.push([note[0], frequency[1], note[1]]); } }); }); demo(arr, e); } //play demo according to which one selected function demoHandler(e) { if (e.target.classList.contains('demo1')) { findFrequencies(noSuprises, e); } if (e.target.classList.contains('demo2')) { findFrequencies(lifeOnMars, e); } if (e.target.classList.contains('demo3')) { findFrequencies(furElise, e); } if (e.target.classList.contains('demo4')) { findFrequencies(theEntertainer, e); } } //input handlers function updateTempo(e) { tempo = e.target.value; } function updateVolume(e) { volume = e.target.value; } //adds css class when note played function addVisual(key, length) { key.classList.add('played'); setTimeout(function () { key.classList.remove('played'); }, length || 300); } //keyboard information toggle var helpOn = true; function helpToggle() { if (helpOn) { blackKey.forEach(function (key) { key.style.color = 'rgba(0,0,0,0)'; }); whiteKey.forEach(function (key) { key.style.color = 'rgba(255,255,255,0)'; }); help.classList.remove('on'); helpOn = !helpOn; } else { blackKey.forEach(function (key) { key.style.color = 'rgba(255,255,255,1)'; }); whiteKey.forEach(function (key) { key.style.color = 'rgba(0,0,0,1)'; }); help.classList.add('on'); helpOn = !helpOn; } } //event listeners help.addEventListener('click', helpToggle); demoButtons.forEach(function (key) { key.addEventListener('click', demoHandler); }); key.forEach(function (key) { key.addEventListener('click', onClickPlay); }); window.addEventListener('keydown', keyDownSearch); tempoInput.addEventListener('change', updateTempo); volumeInput.addEventListener('change', updateVolume); //Hide keyboard help letters on load helpToggle();
});
Playable Piano Keyboard with Demos - Script Codes
Playable Piano Keyboard with Demos - Script Codes
Home Page Home
Developer Adam
Username rzencoder
Uploaded November 28, 2022
Rating 3
Size 10,019 Kb
Views 8,096
Do you need developer help for Playable Piano Keyboard with Demos?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Adam (rzencoder) Script Codes
Create amazing art & images with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!