Jump to content

Colored arrows (alternative method)

From LilyPond wiki

This snippet demonstrates drawing colored arrows in a score, e.g. for analysis purposes. These arrows will adapt to layout changes, because they are made of spanners between (invisible) note heads. If you need arrows with a fixed length and angle, you might prefer Snippet 961.

\version "2.24.0"

forwardArrow = #(define-music-function (color)
                  (color?)
                  #{ % Cross-staff arrows are made using the VoiceFollower:
                    \once \override VoiceFollower.layer = #-5
                    % To have the arrow behind the staff, choose a value below 0 for the layer.
                    % If you want the arrows to cover the notes, choose a value of 2 or more.
                    \once \override VoiceFollower.thickness = #'5    % line thickness
                    \once \override VoiceFollower.color = #color
                    \once \override VoiceFollower.bound-details.left.padding = #4
                    \once \override VoiceFollower.bound-details.right.padding = #5
                    % Padding can be adjusted to move arrow ends closer to the notes
                    \once \override VoiceFollower.bound-details.right.arrow = ##t
                    \once \override VoiceFollower.breakable = ##t  % ##f prevents line breaks within an arrow
                    % Arrows within the same staff use the Glissando spanner:
                    \once \override Glissando.layer = #-5
                    \once \override Glissando.thickness = #'5
                    \once \override Glissando.color = #color
                    \once \override Glissando.bound-details.left.padding = #4
                    \once \override Glissando.bound-details.right.padding = #5
                    \once \override Glissando.bound-details.right.arrow = ##t
                    \once \override Glissando.breakable = ##t
                  #})

backwardArrow = #(define-music-function (color)
                  (color?)
                  #{
                    \once \override VoiceFollower.layer = #-5
                    \once \override VoiceFollower.thickness = #'5    % line thickness
                    \once \override VoiceFollower.color = #color
                    \once \override VoiceFollower.bound-details.left.padding = #4
                    \once \override VoiceFollower.bound-details.right.padding = #5
                    % pretty much the same stuff, but arrow head at the left side:
                    \once \override VoiceFollower.bound-details.left.arrow = ##t
                    \once \override VoiceFollower.breakable = ##t
                    \once \override Glissando.layer = #-5
                    \once \override Glissando.thickness = #'5
                    \once \override Glissando.color = #color
                    \once \override Glissando.bound-details.left.padding = #4
                    \once \override Glissando.bound-details.right.padding = #5
                    \once \override Glissando.bound-details.left.arrow = ##t % same here...
                    \once \override Glissando.breakable = ##t
                  #})


\relative c' {
  <<
    % Usage: place the arrow function call before the note, the glissando statement after the note
    \new Staff = upper {c4 d e \backwardArrow #blue c \glissando    R1   R1   R1   R1   R1   c4 d e c   e1 d c}
    \new Staff = middle {R1    c4 d e c   e8 d e f g f e c    d c d e f e f d    c1    R1    R1*4}
    \new Staff = lower
    {<<
      {R1   R1    c4 d e \forwardArrow #blue c\glissando    R1   c4 d e c    d c b2    R1*4}
      { \override NoteColumn.ignore-collision = ##t 
        % Cross-staff arrows use an additional voice with hidden notes between them.
        % To make these notes visible, uncomment the following line:
        %      \override NoteHead.color = #cyan \override NoteHead.layer = #2
        % and remove the following "\hideNotes" line:
        \hideNotes
        \set Voice.followVoice = ##t
        \change Staff = "upper"  c4 s2.
        % place the arrow function call immediately before the staff change:
        \backwardArrow #green
        \change Staff = "middle"  g4 s2.
        \forwardArrow #red
        \change Staff = "lower"  c4  s2.    s1    c4 s2.
        \break
        \forwardArrow #red
        \change Staff = "middle"  c4 s2.
        \forwardArrow #red
        \change Staff = "upper"  c4 s2.
      }
    >>}
  >>
}