Sairam Mangeshkar
Sairam Mangeshkar

Reputation: 371

How to start multiple animations at once in Kivy?

Goal:


Expected Result:


Actual Result:


The Code for Reference:

class KivySplash(Screen):
    def __init__(self, **kwargs):
        super(KivySplash, self).__init__(**kwargs)
        anim1 = MyAnimation(duration=4, opacity=0)
        anim1.bind(on_complete=self.on_anim1_complete)
        self.animation = MyAnimation(duration=3) + MyAnimation(duration=4, opacity=1) + MyAnimation(duration=5) + anim1
        self.img1 = Image(source=os.path.join(original_dir, "Kivy-logo-black-512.png"), opacity=0)
        self.img2 = Image(source=os.path.join(original_dir, "python-powered-w-200x80.png"))
        self.label1 = Label(text="Powered by:", font_size=48)
        box_layout = BoxLayout(orientation="vertical")
        box_layout1 = BoxLayout()
        box_layout.add_widget(self.label1)
        box_layout1.add_widget(self.img1)
        box_layout1.add_widget(self.img2)
        box_layout.add_widget(box_layout1)
        self.add_widget(box_layout)

    def on_anim1_complete(self, *args):
        do_nothing(self, *args)
        if self.img1 in self.animation.animated_widgets:
            pass

    def on_enter(self, *args):
        self.animation.start(self.img1)
        self.animation.start(self.img2)


Thanking You.

Upvotes: 0

Views: 530

Answers (1)

John Anderson
John Anderson

Reputation: 38857

I believe you have encountered a bug in the kivy Animation. If you are just using a simple Animation, then starting that Animation on multiple Widgets should work fine. The bug happens when you are using a Sequence (Animations connected with '+'). Sequences work by running the first Animation and binding an internal on_complete method that starts the next Animation in the Sequence. When you call start, that on_complete method is bound. But as soon as the first Animation on the first Widget in the Sequence completes, the second Animation is started and the on_complete method is unbound. Now, when the first Animation on the second Widget completes, the on_complete is not called (is was unbound after the first Widget completed), and the second Animation is not started.

Here is the code from Sequence:

def on_anim1_complete(self, instance, widget):
    self.anim1.unbind(on_complete=self.on_anim1_complete)
    self.anim2.start(widget)

In your case, it looks like the Animation is not starting on the second Widget, but because your first Animation doesn't actually animate anything, you don't see it.

Unfortunately, there are not many alternatives to avoid this problem.

  • You can build a copy of the entire Animation a second time (copy() or deepcopy() will not work), and just use two different animations (one for each Widget).
  • You can do your own sequencing by just using simple Animations and use your own on_complete to start the next Animation. Conveniently, the on_complete arguments includes the animated widget that you need for the next start() call.
  • In some situations, you may be able to animate a single container (like a Layout). Since that is only animating a single Widget, the sequencing should work correctly.

Upvotes: 1

Related Questions