Skip to content

Commit

Permalink
Style improvements, to do: cross-browser compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Selim Sheta committed Apr 16, 2024
1 parent a12b024 commit 77df62a
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 54 deletions.
65 changes: 42 additions & 23 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,41 @@
</head>
<body>
<div class="mainContainer">
<h1>Polyrhythm Maker</h1>

<form id="polyrhythmForm">
<h1>Polyrhythm Maker</h1>
<h3>Selim Sheta 2024</h3>
<div class="globalParameters">
<label for="tempo">Tempo (BPM):</label>
<input type="number" onchange="generateMidi()" id="tempo" name="tempo" value="120" min="1" max="300" required>
<label for="duration">Duration (seconds):</label>
<input type="number" onchange="generateMidi()" id="duration" name="duration" value="30" min="1" max="600" required>

</div>
<div class="globalParameters">
<button type="button" onclick="addNote()">Add Note</button>
<button type="button" onclick="downloadMidi()">Download</button>
</div>
<div id="noteInputs"></div> <!-- Container for dynamic note inputs -->
<div id="noteInputs">
<i id ="defaultMessage">Notes will appear here as you add them.</i>
</div> <!-- Container for dynamic note inputs -->
</form>

<i id="info">P = pitch, O = octave, D = duration, V = velocity</i>
<midi-player id="player" src="" sound-font></midi-player>

<midi-visualizer type="piano-roll" id="v_roll" src=""></midi-visualizer>

</div>
<script>

let globalDataUri = "";

let player = document.getElementById("player")
let v_staff = document.getElementById("v_staff")
let v_roll = document.getElementById("v_roll")
let container = document.getElementById('noteInputs');
let defaultMessage = document.getElementById('defaultMessage');
let numNotes = 0;
// Add a new note and its options to the container
function addNote() {
const container = document.getElementById('noteInputs');
if (defaultMessage) defaultMessage.remove();
const tempo = document.getElementById('tempo').value;
const duration = document.getElementById('duration').value;

Expand All @@ -43,7 +53,7 @@ <h1>Polyrhythm Maker</h1>
let defaultVelocity = 70;
let defaultBeats = Math.floor(tempo*duration/60/2);
let defaultTimes = defaultBeats/2; // Initial default "times" value for the first note

// Fetch the last note container added
const lastNoteContainer = container.querySelector('div[id^="noteContainer"]:last-child');
if (lastNoteContainer) {
Expand Down Expand Up @@ -72,7 +82,9 @@ <h1>Polyrhythm Maker</h1>
noteDiv.id = 'noteContainer' + noteIndex;
noteDiv.className = 'noteContainer'
noteDiv.innerHTML = `
<label for="note${noteIndex}">Pitch</label>
<button type="button" onchange="generateMidi()" id="xbut${noteIndex}" onclick="removeNote(${noteIndex})">X</button>
<label for="note${noteIndex}">P</label>
<select id="note${noteIndex}" onchange="generateMidi()" name="note${noteIndex}">
<option value="C">C</option>
<option value="C#">C#/Db</option>
Expand All @@ -88,10 +100,10 @@ <h1>Polyrhythm Maker</h1>
<option value="B">B</option>
</select>
<label for="octave${noteIndex}">Octave</label>
<label for="octave${noteIndex}">O</label>
<input type="number" onchange="generateMidi()" id="octave${noteIndex}" name="octave${noteIndex}" min="-2" max="8" value="${defaultOctave}" required>
<label for="duration${noteIndex}">Duration</label>
<label for="duration${noteIndex}">D</label>
<select id="duration${noteIndex}" onchange="generateMidi()" name="duration${noteIndex}" required>
<option value="1">whole</option>
<option value="2">half</option>
Expand All @@ -102,36 +114,48 @@ <h1>Polyrhythm Maker</h1>
<option value="64">sixty-fourth</option>
</select>
<label for="velocity${noteIndex}">Velocity</label>
<label for="velocity${noteIndex}">V</label>
<input type="number" onchange="generateMidi()" id="velocity${noteIndex}" name="velocity${noteIndex}" min="1" max="100" value="${defaultVelocity}" required>
<label for="times${noteIndex}">| Must play</label>
<input type="number" onchange="generateMidi()" id="times${noteIndex}" name="times${noteIndex}" min="1" max="100" value="${defaultTimes}" required>
<label for="beats${noteIndex}">times every</label>
<input type="number" onchange="generateMidi()" id="beats${noteIndex}" name="beats${noteIndex}" min="1" max="100" value="${defaultBeats}" required>
<label for="xbut${noteIndex}">beats.</label>
<button type="button" onchange="generateMidi()" id="xbut${noteIndex}" onclick="removeNote(${noteIndex})">X</button>
<label for="end${noteIndex}">beats.</label>
<div><id ="${noteIndex}"></div>
`;
container.appendChild(noteDiv);
// Set the default pitch selection
container.querySelector('div[id^="noteContainer"]:last-child').querySelector('select[id^="note"]').selectedIndex = defaultPitch;
noteDiv.querySelector('select[id^="note"]').selectedIndex = defaultPitch;
// Set the default duration selection
container.querySelector('div[id^="noteContainer"]:last-child').querySelector('select[id^="duration"]').selectedIndex = defaultDuration;
noteDiv.querySelector('select[id^="duration"]').selectedIndex = defaultDuration;
// remove border from top note container
container.querySelector('div[id^="noteContainer"]:first-child').style.borderTop = "none";
numNotes += 1;
generateMidi();
}

// Remove a note
function removeNote(index) {
const noteToRemove = document.getElementById('noteContainer' + index);
noteToRemove.remove();
numNotes -= 1;
// remove border from top note container
if (numNotes > 0) container.querySelector('div[id^="noteContainer"]:first-child').style.borderTop = "none";

if (numNotes == 0){
defaultMessage = document.createElement('div');
defaultMessage.innerHTML = `<i id ="defaultMessage">Notes will appear here as you add them.</i>`;
container.appendChild(defaultMessage);
}
generateMidi();
}

// Generate the polyrhythm
function generateMidi() {
event.preventDefault();
if(event) event.preventDefault();
var track = new MidiWriter.Track();
const tempo = document.getElementById('tempo').value;
const duration = document.getElementById('duration').value;
Expand Down Expand Up @@ -168,11 +192,6 @@ <h1>Polyrhythm Maker</h1>
track.addEvent(noteEvents);
var write = new MidiWriter.Writer([track]);
globalDataUri = write.dataUri();

let player = document.getElementById("player")
let v_staff = document.getElementById("v_staff")
let v_roll = document.getElementById("v_roll")

player.src = write.dataUri()
v_roll.src = write.dataUri()
player.addVisualizer(v_roll);
Expand Down
81 changes: 50 additions & 31 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
--text: #032319;
--background: #fafffd;
--primary: #2d5c4e;
--secondary: #af9ad6;
--accent: #f2b44e;
--secondary: #626262;
--accent: #f05477;
}

body {
font-family: 'Arial', sans-serif;
background-color: var(--background);
color: var(--text);
padding: 20px;
margin: 0;

}

.mainContainer {
Expand All @@ -23,28 +21,24 @@ body {
}

h1, h3 {
margin: 0;
color: var(--primary);
}

form {
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
margin-top: 20px;
overflow-x: hidden;
max-height: 600px;
display: flex;
flex-direction: column;
justify-content: center; /* Centers content horizontally */
align-items: center; /* Optional: if you also want vertical centering */
width: 100%;
margin-bottom: 5px;
}

label {
margin: 5px 0 5px;
}

input[type="number"],
input,
select {
padding: 8px;
margin: 5px 0 5px;
Expand All @@ -69,49 +63,74 @@ button:hover {
background-color: var(--accent);
}

#noteInputs {
width: 100%; /* Ensures the container spans the full width of its parent */
overflow-x: auto; /* Enables horizontal scrolling when content overflows */
margin-top: 10px;
padding-bottom: 10px;
.globalParameters {
margin-top: 5px;
display: inline-block;
white-space: nowrap; /* Prevents items from wrapping to the next line */
}

#noteInputs{
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
margin-top: 20px;
overflow: auto;
display: flex;
flex-direction: column;
justify-content: center; /* Centers content horizontally */
align-items: center; /* Optional: if you also want vertical centering */
justify-content: flex-start; /* Centers content horizontally */
align-items: flex-start; /* Optional: if you also want vertical centering */
max-height: 550px;
max-width: 100%;
}

.noteContainer {
display: inline-block;
font-size: 14px;
border-top: 1px solid var(--secondary);
white-space: nowrap; /* Prevents items from wrapping to the next line */
}

#noteInputs label,
#noteInputs input,
#noteInputs select {
.noteContainer label,
.noteContainer input,
.noteContainer select {
display: inline-block;
width: auto;
max-width: 85px;
margin-right: 10px;
}

#noteInputs button {
.noteContainer button {
background-color: var(--secondary);
width: 30px;
height: 30px;
font-weight: bold;
text-align: center;
padding: 0;
margin: 0 10px 0 0;
}

#noteInputs button:hover {
.noteContainer button:hover {
background-color: var(--accent);
}

.noteContainer {
display: inline-block;
font-size: 14px;
border-top: 1px solid var(--secondary);
white-space: nowrap; /* Prevents items from wrapping to the next line */
}

midi-player {
display: block;
margin-top: 20px;
width: 100%;
max-width: 600px;
background-color: transparent;
backdrop-filter: drop-shadow(0 0 2px rgba(0,0,0,0.1))
}

midi-visualizer {
display: block;
margin-top: 20px;
max-width: 100%;
}

#info {
margin: 0px 0px 10px;
padding: 0;
text-align: center;
}

0 comments on commit 77df62a

Please sign in to comment.