how to display the musical notes one by one with vexflow ?

485 views
Skip to first unread message

guy mescam

unread,
Feb 24, 2021, 10:57:19 AM2/24/21
to vexflow
Hello, 
I just discovered vexflow. I looked at all the tutorials but I couldn't find how to add the notes one by one to the staff. I have a virtual accordion keyboard and I want each key pressed to display the corresponding solfeggio note on the staff. I used the function 
--------------------------------------------------------------------------------------------
"function writeNote (pitch, rhythm) { 
 document.getElementById ('score'); // add additional if statements to include more rhythmic options if (rhythm === '/ 8') { score.set ({time: "1/8"}) } else if (rhythm === '/ q') { score.set ({time: "1/4"}); } else if (rhythm === '/ h') { score.set ({time: "1/2"}); } system.addStave ({ voices: [score.voice (score.notes (pitch + rhythm))] }). addClef ('treble'); vf.draw (); } " 
----------------------------------------------------------------------------------------------
 I get the 1st note, but I cannot display other notes. It seems that each time vexflow expects the number of notes for a measure (4 in my case). If so, is there a solution and if so thanks for your help. 
Cordially 
Guy
PS: I am an amateur programmer, French and I use google translate. Hope this is clear to you

Isaac Hartung

unread,
Jul 20, 2021, 1:10:58 PM7/20/21
to vexflow
The code below redraws the melody variable--an array of midi numbers--as it changes (I am using react-piano to feed notes into vexflow).  This approach simply deletes the previous drawing and draws a new one.
----------------------------------------------------------------------
import Vex from 'vexflow';
import {useEffect} from 'react';
import {midiVex, staveNotes} from './helper.js';

export default function Sheet (props) {

    const clear = () => {
        var myDiv = document.getElementById("boo")
        while(myDiv.lastElementChild){
            myDiv.removeChild(myDiv.lastElementChild);
        }
    }

    const createContext = (divID) => {
        const VF = Vex.Flow;

        // Create an SVG renderer and attach it to the DIV element named "boo".
        var div = document.getElementById(divID)
        var renderer = new VF.Renderer(div, VF.Renderer.Backends.SVG);

        // Size our SVG:
        renderer.resize(500, 500);

        // And get a drawing context:
        return renderer.getContext();
    }

    const drawStave = (context) => {
        const VF = Vex.Flow;
        var stave = new VF.Stave(10, 40, 400);
        // Add a clef and time signature.
        stave.addClef("treble").addTimeSignature("4/4");
        // Connect it to the rendering context and draw!
        stave.setContext(context).draw();
        return stave;

    }

    useEffect(() => {
        drawStave(createContext('boo'));
    }, []);

    useEffect(() => {
        const VF = Vex.Flow;
        if(props.melody.length){
           
            clear();   
            var context = createContext('boo');

            var stave = drawStave(context);

            var rawNotes = staveNotes(midiVex(props.melody));
            var notes = [];
            for(let i = 0; i < rawNotes.length; i++){
                notes.push(new VF.StaveNote(rawNotes[i]));
            }

            var voice = new VF.Voice({num_beats:notes.length, beat_value:4});
            voice.addTickables(notes);

            var formatter = new VF.Formatter().joinVoices([voice]).format([voice], 400);

            voice.draw(context,stave);
        }

    }, [props.melody]);

    return (
        <div id='boo'></div>
    );
Reply all
Reply to author
Forward
0 new messages