In my previous post I explain how to create a smooth translation using the Kivy Clock and Properties. There is actually an easier way for doing this.

We can use Kivy animations. It is the simplest way. Below is the code. The interesting thing about the Animation class is that we can send any widget property as the animation parameter. For example, we can send the Label‘s font_size as the Animation‘s parameter. Moreover we can send two or more parameters.

label = Label(text = "increase and move", pos=(0,0))
animation = Animation(x=500, y=500, font_size=72px, d=2, t='in_out_quad');
animation.start(label) 

As you can see, I am sending three properties (x, y, and font_size). I added the t='in_out_quad' as a small surprise to add a transition. Just ask me if you have any question.

Here is the full example of my previous post but using animations:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.animation import Animation

Builder.load_string("""
<PongBall@Widget>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size

<PongGame>:
    ball: pong_ball

    PongBall:
        id: pong_ball
        pos: 0,0
""")


class PongGame(Widget):
    def animate(self):
        animation = Animation(pos=(Window.size), d=3)
        animation.start(self.ball)

class PongApp(App):
    def build(self):
        game = PongGame()
        game.animate()
        return game

if __name__ == '__main__':
    PongApp().run()

6 thoughts on “Smooth translation of widgets in Kivy (using animations)

  1. Hi robert
    I have an Animation in a for loop.I want to bind a function to Animation.on_complete.but when on_complete will fire ?.when For loop is completely finished or in every loop iteration?
    my Animation.start() is at the end of the loop.
    main subject::dose animation sequence in for loop starts all animations in same time or one after another?
    what about on_complte it fire for every iteration or no

    Reply
  2. Hi Milad,

    Assuming you just have an instance of an Animation (i.e. you are not creating a new animation object/instance in each iteration of the loop)

    You can bind only one function to the on_complete, so each time you bind something inside the loop (or anywhere else) you basically replace that function. on_complete, therefore, won’t fire in every iteration.

    That function, however, could start several other animations but this you would have to program depending on what you have.

    —-

    So far, I have assumed that you just have one instance of the Animation. That would be the only way the question make sense. However, it is possible that you are creating a new Animation object each iteration (depending on the place you are creating the animation, inside or outside the loop?).

    So, if you are creating the animation inside the loop, then you are actually creating as many animations as iterations. Therefore, you could bind one function to the on_complete of each animation.

    —-

    You also said that you have the animation.start() at the end of the loop. Is this inside the loop?

    If yes, I must say that is awkward. You would be starting the animation as many times as iterations. It only might make sense if you are creating multiple animations.

    If no, that is still awkward. I just have troubles imagining why would you need to create an Animation inside a loop and call it afterwards.

    It would be great if you could provide me an example. You can post the question in stackoverflow.com and send me the link here?

    Reply
  3. Hi Robert
    You replide on Stackoverflow that animations execution is parallel (as the book confirms) .but why they are in parallel? there is an animation in every iteration and a start() then in every iteration an animation will fire and at the end of every animation, on_compelet methode will fire. if animations are in parallel then there will be only one on_compelet method when all animations execution finished.
    Thanks a lot

    Reply
  4. There are as many on_complete’s as animations. Each animation trigger the function on_complete. If you have something like this:

    anim1 = Anim(…
    anim1.on_complete = func1
    anim1.start(…

    anim2 = Anim(…
    anim2.on_complete = func1
    anim2.start(…

    … then, the function func1 is going to be called twice: (1) once anim1 ends and (2) once anim2 ends

    Are you familiar with object oriented programming? https://en.wikipedia.org/wiki/Object-oriented_programming

    anim1 and anim2 are different objects of the same class, therefore the on_complete method exist two times in memory. Check my first answer again…

    I might be wrong, but I am almost sure that if you spend some time understanding the difference between class and object (and instance) you will get what I am saying.
    https://en.wikipedia.org/wiki/Object-oriented_programming#Objects_and_classes

    Reply

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required