[Python] How to keep a circle centered during animation

Discussão em 'Python' iniciado por Stack, Fevereiro 27, 2025.

  1. Stack

    Stack Membro Participativo

    I'm developing a Chwazi clown using a Python Kivy application.

    Quick background: in this app, there is a circle when you press (and hold and it beats (gets bigger and smaller)). I came across a problem with animation of the beating, because when I use this function:

    def beat_animation(self, circle):
    anim = Animation(size=(circle.size[0]*1.2, circle.size[1]*1.2), duration=0.5)
    anim += Animation(size=(circle.size[0], circle.size[1]), duration=0.5)
    anim.repeat = True
    anim.start(circle)


    My circle is getting bigger and smaller as I want it to be, but the problem is that it does not stay centered around the cursor. (This is meant to be an app and it supports multitouch, so it should be doing it to all the circles.)

    Here is the full code:

    import random

    import kivy
    from kivy.app import App
    from kivy.uix.widget import Widget
    from kivy.graphics import Ellipse, Color
    from kivy.uix.label import Label
    from kivy.animation import Animation


    class Touch(Widget):
    def __init__(self, **kwargs):
    super(Touch, self).__init__(**kwargs)
    self.circles = {} # Dictionary to store circles for each finger

    def on_touch_down(self, touch):
    if touch.id not in self.circles:
    with self.canvas:
    width, height = self.size # Get the screen size
    circle_size = min(width, height) * 0.3 # Calculate the circle size as 10% of the smaller dimension of the screen
    color = Color(random.random(), random.random(), random.random(), 1.0) # Random color for the circle
    circle = Ellipse(pos=(touch.x - circle_size/2, touch.y - circle_size/2), size=(circle_size, circle_size))
    self.circles[touch.id] = (color, circle)
    self.beat_animation(circle)

    def beat_animation(self, circle):
    anim = Animation(size=(circle.size[0]*1.2, circle.size[1]*1.2), duration=0.5)
    anim += Animation(size=(circle.size[0], circle.size[1]), duration=0.5)
    anim.repeat = True
    anim.start(circle)

    def on_touch_move(self, touch):
    width, height = self.size # Get the screen size
    circle_size = min(width, height) * 0.3 # Calculate the circle size as 10% of the smaller dimension of the screen
    if touch.id in self.circles:
    color, circle = self.circles[touch.id]
    circle.pos = (touch.x - circle_size/2, touch.y - circle_size/2)

    def on_touch_up(self, touch):
    if touch.id in self.circles:
    color, circle = self.circles.pop(touch.id)
    self.canvas.remove(color)
    self.canvas.remove(circle)

    class MultiTouchApp(App):
    def build(self):
    return Touch()

    if __name__ == "__main__":
    MultiTouchApp().run()


    I tried to add change it like so:

    def beat_animation(self, circle, touch):
    anim = Animation(pos=(touch.x - circle.size[0] / 2, touch.y - circle.size[1] / 2), size=(circle.size[0] * 1.2, circle.size[1] * 1.2), duration=0.5)
    anim += Animation(pos=(touch.x - circle.size[0] / 2, touch.y - circle.size[1] / 2), size=(circle.size[0] / 1.2, circle.size[1] / 1.2), duration=0.5)
    anim.repeat = True
    anim.start(circle)


    But then when I stop moving my finger, the circle just jumps back to the location it was first created (I think it is because the touch parameter that is passed to beat_animation is not changing dynamically). How can I fix it?

    Continue reading...

Compartilhe esta Página