Embed note on beat

by Nate

HTML

<svg class="symbol" viewBox="0 0 24 48">
  <g class="symbol-root">
    <line class="note-stem" x1=17.75 y1=2 x2=17.75 y2=37.5 />
    <ellipse class="note-head symbol-anchor" cx="10" cy="42.5" rx="8" ry="5" />
  </g>
</svg>

<svg class="line" viewBox="0 0 50 100">
  <g class="measures">
    <svg class="measure">
      <g class="beat">
        <line onpointerup="place_note_on_f_line(event)" id="f" class="staff-line" x1="0" y1="75" x2="50" y2="75" />
        <line onpointerup="place_note_on_e_line(event)" id="e" class="staff-line" x1="0" y1="30" x2="50" y2="30" />
      </g>
      <g class="notes">
      </g>
    </svg>
  </g>
</svg>

CSS

* {
  padding: 0;
  margin: 0;
}

body {
  background-color: #111;
  color: white;
}

.note-stem {
  stroke-width: 1.5px;
  stroke-linecap: round;
  stroke: white;
}

.note-head {
  transform: skewy(-15deg);
  fill: white;
}

.symbol {
  margin: 0 8px;
  border: solid 1px green;
  height: 50px;
}

.line {
  border: solid 1px red;
  height: 200px;
  width: 50%;
}

.measure {
  border: solid 1px blue;
}

.staff-line {
  stroke: white;
  stroke-width: 2px;
}
.staff-line:hover {
  stroke-width: 4px;
}

svg {
  height: 100%;
  stroke: black;
}

JavaScript

// Will need a context-menu option for changing a subdivided note's
// # of subdivisions and subdivision index
// This will allow changing between syncopation and chord-ed notes

// FIXME Selecting different staff lines causes all notes to be moved
// to that line

const symbol = document.getElementsByClassName("symbol")[0]
const symbol_anchor = symbol.querySelector(".symbol-anchor")
const f_staff_line = document.getElementById("f")
const e_staff_line = document.getElementById("e")

const f_coords = [
  f_staff_line.x1.baseVal.value,
  f_staff_line.y1.baseVal.value,
  f_staff_line.x2.baseVal.value,
  f_staff_line.y2.baseVal.value,
]

const e_coords = [
  e_staff_line.x1.baseVal.value,
  e_staff_line.y1.baseVal.value,
  e_staff_line.x2.baseVal.value,
  e_staff_line.y2.baseVal.value,
]

const f_midpoint_coords = [
  Math.abs(f_coords[2] - f_coords[0]) / 2,
  f_coords[1],
]

const e_midpoint_coords = [
  Math.abs(e_coords[2] - e_coords[0]) / 2,
  e_coords[1],
]

const symbol_anchor_coords = [
  symbol_anchor.cx.baseVal.value,
  symbol_anchor.cy.baseVal.value,
]

const staff_line_stroke_width = parseInt(window.getComputedStyle(e_staff_line).getPropertyValue("stroke-width"))

const staff_line_stroke_width_midpoint = staff_line_stroke_width / 2

console.log(`Symbol Anchor Coordinates: ${symbol_anchor_coords}`)

console.log(`F Coordinates: ${f_coords}`)
console.log(`E Coordinates: ${e_coords}`)

console.log(`F Midpoint: ${f_midpoint_coords}`)
console.log(`E Midpoint: ${e_midpoint_coords}`)

console.log(`Staff line stroke width: ${staff_line_stroke_width}`)

function space_symbols_along_beat(current_symbols, placement_coords) {

  console.log(`Number of current symbols in beat: ${current_symbols.length}`)

  for (const each_symbol of current_symbols) {
    // FIXME Will probably need to scale the new_symbol so it fits into 
    // the perspective of the staff_line
    
    // FIXME scale the view of visible measure/line so that the full note
    // can be seen

    const...