vexflow icon indicating copy to clipboard operation
vexflow copied to clipboard

Curves and StaveTies are lining up with annotations in stead of noteheads

Open stefanvonk opened this issue 3 years ago • 6 comments
trafficstars

It seems that my Curves and StaveTies are lining up with the annotations and not with the noteheads: image

Does anyone know why they aren't lining up with the noteheads instead of the annotations? How can I solve this?

Very appreciated if someone could help me out!

stefanvonk avatar Jul 07 '22 18:07 stefanvonk

I won't be able to help much, but from experience, if you can share some code (e.g. how you set the curves) or better even a jsfiddle (interactive demo), that will probably help the team help you. Also, which vexflow version are you using?

sschmidTU avatar Jul 07 '22 19:07 sschmidTU

This is because annotations, like all modifiers, affect the left/right extent of the tick context. The curve code gets it's x position from note start x + width/2. 2 problems with that: not all modifiers are symmetric around the note head, and the tie should go to the note head in this case, not to the outside of the bounding box.

There are cases where you want this behavior, depending on the modifier. For accidentals and dots, you want this behavior, but not for most other modifiers, especially ones that go above/below the note.

I don't know if there's an easy solution to this. I feel like slurs in particular might be best left to the application. For Ties the interface is a bit more flexible, and ties are simpler anyway since the endpoints are close. For a tie you can control the x offset in each direction for instance, but for a curve there is only the single x shift parameter.

AaronDavidNewman avatar Jul 07 '22 19:07 AaronDavidNewman

I'm using the latest version of vexflow, 4.0.3.

I'm adding the ties and curves as follow: ties.push(new VF.Curve(notes[1], notes[2])) curves.push(new VF.StaveTie({first_note: notes[1], last_note: notes[2]}))

In between I format and draw my notes (VF.Formatter.FormatAndDraw)

And later on add them to the context and draw: for(i=0; i < ties.length; i++) {ties[i].setContext(context).draw()} for(i=0; i < curves.length; i++) {curves[i].setContext(context).draw()}

An interactive demo (jsfiddle) is too complex for my code.

stefanvonk avatar Jul 07 '22 19:07 stefanvonk

OK, thanks for this info @AaronDavidNewman! But you say that I can set the x offset of a StaveTie? I don't see that option in the documentation on https://0xfe.github.io/vexflow/api/classes/StaveTie.html. How can I do that? Also for Curve I don't see the option to shift x, https://0xfe.github.io/vexflow/api/classes/Curve.html.

If I can shift the x position of the left side of Curves and Ties I think I can probably calculate the offset and apply it to the Curves and Ties.

stefanvonk avatar Jul 08 '22 18:07 stefanvonk

Look at the render_options parameters.

For curve, x_shift is what I meant. Looking at VF code, it is applied to both the beginning and the end X, which is a limitation. It would be better if there were a separate start and end offset.

StaveTie lets you specify left/right shifts, but only supports one set of control points so it doesn't really work as a phrasing mark.

This is the code from Smoosic.

const curve = new VF.Curve(vxStart, vxEnd,
        {
          thickness: slur.thickness,
          x_shift: slurX,
          y_shift: slur.yOffset,
          spacing: slur.spacing,
          cps: svgPoint,
          invert: slur.invert,
          position: slur.position,
          position_end: slur.position_end
        });

AaronDavidNewman avatar Jul 08 '22 21:07 AaronDavidNewman

Thanks. I solved it with your suggestions. The only problem left now is that my curves are looking a litle bit odd and my ties are a bit too thick: image

But I'll look at that later, maybe I can fix it.

stefanvonk avatar Jul 09 '22 14:07 stefanvonk