Staffs#

Single staff#

[1]:
from manimusic import *

config.media_embed = True; config.media_width = "100%"
_RV = "-v WARNING -qm --progress_bar None --disable_caching Example"
_RI = "-v WARNING -s --progress_bar None --disable_caching Example"
_RV_mid = "-v WARNING -qm -r 1200,300 --progress_bar None --disable_caching Example"
_RI_mid = "-v WARNING -s -r 1200,300 --progress_bar None --disable_caching Example"
Manim Community v0.17.3

[2]:
class Example(Scene):
  def construct(self):
    staff = Staff()
    self.play(ShowStaff(staff))
    self.wait()

%manim $_RV_mid
[3]:
class Example(Scene):
  def construct(self):
    self.add(
      Staff(width=12, height=1),
      Rectangle(width=12, height=1, color=TEAL, stroke_width=10, stroke_opacity=0.6)
    )

%manim $_RI_mid
_images/CHP_1_3_0.png
[4]:
class Example(Scene):
  def construct(self):
    self.add(
      Staff(clefs="f",width=12, height=1),
    )

%manim $_RI_mid
_images/CHP_1_4_0.png
[5]:
class Example(Scene):
  def construct(self):
    self.add(
      Staff(clefs="c",width=12, height=1),
    )

%manim $_RI_mid
_images/CHP_1_5_0.png

Multiple staffs#

Note

The width applies to all staves and the height refers to that of each staff.

Warning

Don’t use the Staff.set(width=...) or Staff.set(height=...) setters because that would mess up the structure sizes, to change the size after the staff definition use Staff.scale(...).

[6]:
class Example(Scene):
  def construct(self):
    self.add(
      Staff(clefs="gf",width=12, height=0.8),
    )

%manim $_RI_mid

_images/CHP_1_8_0.png

Select each staff#

[7]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="gfcf", width=12)
    staff.staffs[0].set_color(RED)
    staff.staffs[1].set_color(TEAL)
    staff.staffs[2].set_color(PURPLE)
    staff.staffs[3].set_color(ORANGE)

    staff.staffs[2][0].set_color(YELLOW)
    staff.staffs[2][-1].set_style(stroke_width=10, stroke_color=PINK)

    self.add(staff)

%manim $_RI
_images/CHP_1_10_0.png

Gap between staffs#

[8]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="gf", width=12, arrange_config={"buff": 3})
    self.add(staff)

%manim $_RI
_images/CHP_1_12_0.png

Select each clef#

[9]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="gfcf", width=12)
    staff.clefs_group[0].set_color(RED)
    staff.clefs_group[1].set_color(TEAL)
    staff.clefs_group[2].set_color(PURPLE)
    staff.clefs_group[3].set_color(ORANGE)
    self.add(staff)

%manim $_RI
_images/CHP_1_14_0.png

Partitions#

Note

The partitions will help us to position all the objects within the staff, notes, tempo, key signatures, etc.

[10]:
class Example(Scene):
  def construct(self):
    staff      = Staff(width=13,partition=40)
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    self.add(staff, partitions)

%manim $_RI_mid
_images/CHP_1_16_0.png

Bars#

[11]:
class Example(Scene):
  def construct(self):
    staff      = Staff(width=13,partition=40,bars=[7,25,31])
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    self.add(staff, partitions)

%manim $_RI_mid
_images/CHP_1_18_0.png
[12]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="gfc", width=13,partition=40,bars=[7,25,31])
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    staff.bars_group[0].set_color(RED)
    staff.bars_group[1].set_color(TEAL)
    staff.bars_group[2].set_color(PURPLE)
    self.add(staff, partitions)

%manim $_RI
_images/CHP_1_19_0.png

Tempo#

[13]:
class Example(Scene):
  def construct(self):
    staff      = Staff(width=13,partition=40,bars=[7,25,31])
    pt         = staff.partition
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    staff.add_tempo(4, 4, 4/pt)  # 4/4 at proportion 4/40
    staff.add_tempo(2, 3, 20/pt) # 2/3 at proportion 4/40
    staff.tempo[0].set_color(RED)
    staff.tempo[1].set_color(TEAL)
    self.add(staff, partitions)

%manim $_RI_mid
_images/CHP_1_21_0.png
[14]:
class Example(Scene):
  def construct(self):
    staff      = Staff(clefs="cfg", width=13,partition=40,bars=[7,25,31])
    pt         = staff.partition
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    staff.add_tempo(4, 4, 4/pt)  # 4/4 at proportion 4/40
    staff.add_tempo(2, 3, 20/pt) # 2/3 at proportion 4/40
    staff.tempo[0].set_color(RED)
    staff.tempo[1].set_color(TEAL)
    staff.tempo[2].set_color(PURPLE)
    staff.tempo[3].set_color(ORANGE)
    staff.tempo[4].set_color(GREEN)
    self.add(staff, partitions)

%manim $_RI
_images/CHP_1_22_0.png
[15]:
class Example(Scene):
  def construct(self):
    staff      = Staff(clefs="cfg", width=13,partition=40,bars=[7,25,31])
    pt         = staff.partition
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    staff.add_tempo(4, 4, 4/pt)  # 4/4 at proportion 4/40
    staff.add_tempo(2, 3, 20/pt) # 2/3 at proportion 4/40
    staff.add_tempo(6, 8, 33/pt) # 6/8 at proportion 33/40
    staff.tempo_group[0].set_color(RED)
    staff.tempo_group[1].set_color(TEAL)
    staff.tempo_group[2].set_color(PURPLE)
    self.add(staff, partitions)

%manim $_RI
_images/CHP_1_23_0.png

Key signatures#

[16]:
class Example(Scene):
  def construct(self):
    pt    = 20
    staff = Staff(clefs="fcg", width=13,partition=pt)
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    ks_sharp         = staff.get_sharp_signature(7, start_at=3/pt)
    ks_natural_sharp = staff.get_natural_sharp_signature(7, 6/pt)
    ks_flat          = staff.get_flat_signature(7, 11/pt)
    ks_natural_flat  = staff.get_natural_flat_signature(7, 15/pt)
    self.add(
      staff,
      partitions,
      ks_sharp.set_color(RED),
      ks_natural_sharp.set_color(RED),
      ks_flat.set_color(TEAL),
      ks_natural_flat.set_color(TEAL)
    )
%manim $_RI
_images/CHP_1_25_0.png

Move objects over the staffs#

[17]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="cfg", width=13,partition=40,bars=[5, 12, 30])
    pt    = staff.partition
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    triangle   = Triangle(fill_opacity=1, color=RED).set(height=0.4)
    self.add(staff, partitions, triangle)
    self.play(
      triangle.animate
        .move_to(staff.get_proportion_line(5/pt, 0)) # 0: first line
        .set_color(TEAL)
    )
    self.wait()
    self.play(
      triangle.animate
        .move_to(staff.get_proportion_line(12/pt, 2)) # 2: third line
        .set_color(TEAL)
    )
    self.wait()
    self.play(
      triangle.animate
        .move_to(staff.get_proportion_line(30/pt, 1)) # 1: second line
        .set_color(PURPLE)
    )
    self.wait()
    self.play(
      staff.bars_group[1].animate
        .set_x(staff.get_proportion_line(30/pt, 1)[0])
        .set_style(stroke_width=10, stroke_color=YELLOW)
    )
    self.wait()


%manim $_RV

Note

Staff.staffs[0][0] is the line 0 of the first staff, Staff.staffs[1][0] is the line 0 of the second staff.

[18]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="gf", width=13,partition=10)
    pt    = staff.partition
    partitions = staff.get_ticks(number_height=0.16).set_color(YELLOW)
    staff_gap  = staff.get_space_between_lines()
    dot = Dot().set(height=staff_gap)

    dot.move_to(
      staff.staffs[0][0].point_from_proportion(3/pt)
    )
    self.add(staff, partitions, dot)
    self.play(
      dot.animate.move_to(
        staff.staffs[0][1].point_from_proportion(4/pt)
      ).set_color(RED)
    )
    self.play(
      dot.animate.move_to(
        staff.staffs[0][2].point_from_proportion(5/pt)
      ).set_color(TEAL)
    )
    self.play(
      dot.animate.move_to(
        staff.staffs[1][3].point_from_proportion(6/pt)
      ).set_color(YELLOW)
    )
    self.play(
      dot.animate.shift(DOWN * staff_gap / 2).set_color(PURPLE)
    )
    self.wait()

%manim $_RV

ShowStaff#

Note

This animation shows only the lines and clefs, the rest have to be added separately, or use other animation like Write.

[19]:
class Example(Scene):
  def construct(self):
    staff = Staff(clefs="cfg", width=13,partition=40,bars=[7,25,31])
    pt    = staff.partition
    staff.add_tempo(4, 4, 4/pt)
    staff.add_tempo(2, 3, 20/pt)
    staff.add_tempo(6, 8, 33/pt)
    self.play(ShowStaff(staff))
    self.play(
      Write(staff.tempo_group),
      LaggedStartMap(GrowFromCenter, staff.bars_group)
    )
    self.wait()
    self.play(Write(staff)) # <- To show all
    self.wait()

%manim $_RV

All staff config#

class Staff(VGroup):
    DEFAULT_ARRANGE_CONFIG = {
      "direction": DOWN, "buff": 1
    }
    DEFAULT_STAFF_CONFIG = {
      "stroke_width": 3,
      "stroke_opacity": 1,
      "fill_opacity": 1,
      "stroke_color": WHITE,
    }
    DEFAULT_CLEFF_CONFIG = {
      "fill_opacity": 1,
      "stroke_opacity": 1,
      "fill_color": WHITE,
      "stroke_color": WHITE
    }
    def __init__(self,
                 num_staffs=0,
                 clefs=None,
                 arrange_config={},
                 staff_config={},
                 clef_config={},
                 left_buff=0.08, # with the clef and the staff left side
                 show_reference=False,
                 bars=[],
                 partition=30,
                 width=8,
                 height=1,
                **kwargs):

The arrange_config, staff_config and cleff_config dicts will be merged with the class variables so they can be overridden.