I'm making a piano simulator and want to have buttons on each key that play the note when clicked. I used the button html element to make the sound play, as I've heard this is the best way to do it and it wouldn't work if I used the JavaScript button object.
this is the JS code and it works just fine to play the sound when clicked.
let cButton = document.getElementById("cButton");
cButton.addEventListener('click', function(){
C.play();
})
However the buttons are all up at the top of the page because they are html elements and I'm not sure how to add them into the JS code so they can be moved to the keys.
This is the output of my code. 1
EDIT: This is my HTML and CSS code as well, as some have been asking for it.
<button id="cButton">C</button>
<button id="dButton">D</button>
<button id="eButton">E</button>
<button id="fButton">F</button>
<button id="gButton">G</button>
<button id="aButton">A</button>
<button id="bButton">B</button>
This is just creating all the buttons.
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
Note, the CSS code isn't my own, it was there when I opened the file. I've tried messing around with it a bit, but all it does is change things inside the white bar at the top where the buttons are.
CodePudding user response:
You want to use JSX, it's pretty much a framework that allows you to write HTML elements and combine it with JS. You can create a variable that represents a key of the piano and then use JS to assign each sound value to each different key.
CodePudding user response:
Let's say we have the following html snippet inside our page:
<div id="key1">
</div>
<div id="key2">
</div>
..etc for each key
If I wanted to add a button element on the div key1 element I could use the innerHtml property.
document.getElementById("key1").innerHtml = `<button key="mybutton" onclick="dostuff()"> MyButton </button`
You can investigate more into how you can do this on Mozilla https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
You can probably do this with other DOM properties.
It has been awhile since I have done vanilla JS, I usually do React so hopefully this is not rusty code :). It would also help if you could post some HTML so we can see how your entire project looks.
CodePudding user response:
Follow these codes:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>------------ CodeSpeedy ----------</h1>
<div >
<!-- white and black keys -->
<div data-note="C" ><h3>C</h3></div>
<div data-note="O" ><h3>O</h3></div>
<!-- white keys -->
<div data-note="D" ><h3>D</h3></div>
<!-- white and black keys -->
<div data-note="E" ><h3>E</h3></div>
<div data-note="S" ><h3>S</h3></div>
<div data-note="P" ><h3>P</h3></div>
<!-- white keys -->
<div data-note="E1" ><h3>E</h3></div>
<!-- white and black keys -->
<div data-note="E" ><h3>E</h3></div>
<div data-note="D" ><h3>D</h3></div>
<!-- white keys -->
<div data-note="Y" ><h3>Y</h3></div>
</div>
<!-- Audio files -->
<audio id="C" src="music/tune0.mp3"></audio>
<audio id="O" src="music/tune (1).mp3"></audio>
<audio id="D" src="music/tune (2).mp3"></audio>
<audio id="E" src="music/tune (3).mp3"></audio>
<audio id="S" src="music/tune (4).mp3"></audio>
<audio id="P" src="music/tune (5).mp3"></audio>
<audio id="E1" src="music/tune (4).mp3"></audio>
<audio id="E" src="music/tune (3).mp3"></audio>
<audio id="D" src="music/tune (2).mp3"></audio>
<audio id="Y" src="music/tune (1).mp3"></audio>
<script src="script.js"></script>
</body>
</html>
Style.css
body {
background: rgba(39, 34, 34, 0.986);
}
h1{
color: cyan;
text-align: center;
}
h3{
margin-top: 350px;
text-align: center;
font-size: large;
}
.container {
width: 100%;
display: flex;
flex-flow: row nowrap;
}
.white {
position: relative;
background: rgb(241, 240, 240);
width: 10%;
height: 400px;
margin: 0 2px;
}
.white.black:after {
content: "";
position: absolute;
top: 0;
background: rgb(17, 11, 11);
right: -25%;
width: 50%;
height: 50%;
z-index: 1;
}
script.js
const WHITE=['a','s','d','f','j','k','k'];
const BLACK=['r','t','y','u','i'];
let keys=document.querySelectorAll('.key');
let blackKeys=document.querySelectorAll('.key.black');
let whiteKeys=document.querySelectorAll('.key.white');
// eventlistener for mouse click
keys.forEach(key =>{
key.addEventListener('click',()=>playMusic(key));
});
//eventlistener for key press using keydown
document.addEventListener('keydown',e=>{
let key=e.key;
let whiteKeyIndex=WHITE.indexOf(key);
let blackKeyIndex=BLACK.indexOf(key);
if(whiteKeyIndex>-1) playMusic(whiteKeys[whiteKeyIndex]);
if(blackKeyIndex>-1) playMusic(blackKeys[blackKeyIndex])
});
// this function will play audio
function playMusic(key){
const audio=document.getElementById(key.dataset.note);
audio.currentTime=0;
audio.play();
}
It will provide you with an HTML page that contains a piano keyboard simulator with sound.
CodePudding user response:
If you simply want to place the keys over the top of the image, you can use position absolute with top and left properties as well as psuedo elements to style the keys to overlay over the image.
In my example I only code the C and D keys, if you expand the snippit to full page and press anywhere on the C or D you will get the event to trigger a console log of the dataset-id value.
const keys = document.querySelectorAll('.keys')
function showNote(e){
console.log(e.target.dataset.id)
// your play code can go here, use the dataset.id of the event.target to get the note
}
keys.forEach(note => note.addEventListener('click', showNote))
#main {
background: url(https://i.stack.imgur.com/jHa3G.png) no-repeat;
width: 100vw;
height: 100vh;
}
#cButton {
position: absolute;
top: 105px;
left: 37px;
height: 340px;
width: 45px;
/* border: 1px solid black; uncomment to see the key outline and comment out opacity */
opacity: 0;
}
#cButton:after {
content: '';
position: absolute;
top: 210px;
left: 42px;
height: 127px;
width: 30px;
/* border: 1px solid black; uncomment to see the key outline and comment out opacity */
opacity: 0;
}
#dButton {
position: absolute;
top: 105px;
left: 130px;
height: 340px;
width: 45px;
/* border: 1px solid black; uncomment to see the key outline and comment out opacity */
opacity: 0;
}
#dButton:before {
content: '';
position: absolute;
top: 210px;
left: -18px;
height: 127px;
width: 15px;
/* border: 1px solid black; uncomment to see the key outline and comment out opacity */
opacity: 0;
}
#dButton:after {
content: '';
position: absolute;
top: 210px;
left: 42px;
height: 127px;
width: 15px;
/* border: 1px solid black; uncomment to see the key outline and comment out opacity */
opacity: 0;
}
/* keep styling your keys to fill them in by targeting their unique ids and using before and after psuedo elements to style the ends of the whole keys (white keys)
<div id="main">
<button data-id="c" id="cButton" title="right click me and click 'inspect' to see the element in your console inspector, then open the button parent element and hover over the element and its psuedo elements in your inspector to see the highlighted elements/psuedo elements in your browser window =)">C</button>
<button data-id="d" id="dButton">D</button>
<button data-id="e" id="eButton">E</button>
<button data-id="f" id="fButton">F</button>
<button data-id="g" id="gButton">G</button>
<button data-id="a" id="aButton">A</button>
<button data-id="b" id="bButton">B</button>
</div>