lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: test spanner with controlled gradient / dynamic volume curve indicat


From: Thomas Morley
Subject: Re: test spanner with controlled gradient / dynamic volume curve indicated by grey level
Date: Tue, 30 Jan 2018 22:32:54 +0100

2018-01-30 6:19 GMT+01:00 Michael Winter <address@hidden>:
> A bit more here. I think I can fake this in a markup... See example pasted
> below. My scheme skilz are minimal. I would like yo do this interpolating
> between the x position of adjacent notes. So maybe I can do this as a custom
> beam stencil. or some kind of spanner. Basically I want a scheme function
> that will give me the position of a given note and the next note... Thanks!
>
> \relative c'' {
>   s64
>   -\markup {
>     \combine
>     \override #'(line-join-style . miter)
>     \with-color #(x11-color 'grey60)
>     \path #2
>     #'((moveto 0 0)
>      (lineto 0.3 0)
>      (closepath)
>      )
>
>    \combine
>     \override #'(line-join-style . miter)
>     \with-color #(x11-color 'grey40)
>     \path #2
>     #'((moveto 0.3 0)
>      (lineto 0.6 0)
>      (closepath))
>
>     \override #'(line-join-style . miter)
>     \with-color #(x11-color 'grey20)
>     \path #2
>     #'((moveto 0.6 0)
>      (lineto 0.9 0)
>      (closepath))
>
>   }
>
>
> }
>
>
> On 01/29/2018 06:27 PM, Michael Winter wrote:
>>
>> Hello...
>>
>> I have tried quite a few hacks, but nothing really suitable.
>>
>> What I really want is to simple draw a line beneath the staff that has a
>> grey scale gradient such that for each note, I give a target value.
>>
>> Most of what I have tried involves doing this in increments with
>> overlapping spanners, I also tried the code in this thread:
>> https://lists.nongnu.org/archive/html/lilypond-user/2016-10/msg00097.html
>>
>> I think the answer is doing this with svg directives since in the svg
>> documentation there are directives for linear gradients, but I do not know
>> how to build the function to use svg directives and such that the target
>> greyscale value is reached at the x-position of a given notehead.
>>
>> Also, ideally I would be able to use spacer rests to give intermediary
>> values along the way, since the curve is actually not linear.
>>
>> Thanks in advance and my apologies if I have been unclear.
>>
>> Best,
>> Michael



Hi Michael,

not sure I've got you right.

Probably the quick hack below may give you a starting point.
It will not work with spacers though, because they don't cause a NoteColumn.

Cheers,
  Harm

#(define (make-filled-box-stencil-list x-coords half-thick colors rl)
  (if (null? (cdr x-coords))
      rl
      (make-filled-box-stencil-list
        (cdr x-coords)
        half-thick
        (cdr colors)
        (cons
          (stencil-with-color
            (make-filled-box-stencil
              (cons (car x-coords) (cadr x-coords))
              (cons (- half-thick) half-thick))
            (car colors))
          rl))))

\version "2.19.65"

foo =
\override TextSpanner.stencil =
  #(lambda (grob)
    (let* ((ncs (ly:grob-object grob 'note-columns))
           (nc-ls
             (if (ly:grob-array? ncs)
                 (ly:grob-array->list ncs)
                 '()))
           (sys (ly:grob-system grob))
           (nc-exts
             (map
               (lambda (nc)
                 (ly:grob-extent nc sys X))
               nc-ls))
           (left-info
             (ly:grob-property grob 'left-bound-info))
           (right-info
             (ly:grob-property grob 'right-bound-info))
           (thick (ly:grob-property grob 'thickness 1))
           (x-coords
             (map
               (lambda (e)
                 (- e (assoc-get 'X left-info)))
               `(
                 ,(assoc-get 'X left-info)
                 ,@(map
                   interval-center
                   (drop-right (drop nc-exts 1) 1))
                 ,(assoc-get 'X right-info))))
          (ls (iota (1- (length x-coords)) 20 20))
          (color-gradient
            (assoc-get 'color-gradient (ly:grob-property grob 'details) '(1)))
          ;; overkill below ...
          (safe-color-gradient-ls
            (append
              color-gradient
              (make-list (length x-coords) (last color-gradient))))
          (color
            (assoc-get 'color (ly:grob-property grob 'details)))
          (colors
            (map
              (lambda (n)
                (x11-color (string->symbol (format #f "~a~a" (or color
'grey) n))))
              safe-color-gradient-ls)))
    (apply
      ly:stencil-add
      (make-filled-box-stencil-list x-coords thick colors '()))))

{
    \override TextSpanner.thickness = 0.5
    %% make sure color and it's gradient exists, otherwise all's black
    \override TextSpanner.details.color = #'grey
    \override TextSpanner.details.color-gradient = #'(60 40 20)
    \foo
    c''2\startTextSpan
    d''
    e''
    f''\stopTextSpan
}

{
    \override TextSpanner.thickness = 0.5
    \override TextSpanner.details.color = #'LightCyan
    \override TextSpanner.details.color-gradient = #'(2 3 4)
    \foo
    c''2\startTextSpan
    d''
    e''
    f''\stopTextSpan
}

Attachment: atest-70.png
Description: PNG image


reply via email to

[Prev in Thread] Current Thread [Next in Thread]