You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy开发Chwazi克隆应用:动画时如何保持圆形居中?

解决Kivy中Chwazi克隆圆形跟随光标跳动并居中的问题

问题核心

你的问题出在用动画绑定了固定的初始touch位置,而没有实时更新圆形坐标。手指移动时,动画里的位置参数还是创建时的坐标,松开后自然会跳回原点。正确做法是把「位置跟随」和「缩放动画」拆分开:位置靠on_touch_move实时更新,缩放动画单独处理大小。

具体修改方案

  1. 关联Touch与对应圆形
    创建圆形时,用字典把当前touch和圆形对象绑定,方便后续移动时快速找到对应圆形:

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.circles = {}  # 存储touch到圆形的映射
    
    def on_touch_down(self, touch):
        if touch.is_touch and not touch.is_mouse_scrolling:
            # 创建圆形组件
            circle = Label(
                size_hint=(None, None),
                size=(50, 50),
                pos=(touch.x - 25, touch.y - 25),  # 初始居中
                canvas=Canvas()
            )
            # 绘制圆形(保留你原有的canvas绘制逻辑)
            with circle.canvas:
                Color(1, 0, 0, 0.5)
                Ellipse(pos=circle.pos, size=circle.size)
            self.add_widget(circle)
            # 绑定touch和圆形
            self.circles[touch] = circle
            # 启动跳动动画
            self.beat_animation(circle)
        return super().on_touch_down(touch)
    
  2. 实时更新圆形位置
    在on_touch_move里实时调整圆形坐标,确保始终围绕光标居中:

    def on_touch_move(self, touch):
        if touch in self.circles:
            circle = self.circles[touch]
            # 计算居中位置:光标坐标减去圆形半宽/半高
            circle.pos = (touch.x - circle.size[0]/2, touch.y - circle.size[1]/2)
            # 同步更新canvas绘制的椭圆位置(如果用canvas画圆形)
            for instruction in circle.canvas.children:
                if isinstance(instruction, Ellipse):
                    instruction.pos = circle.pos
        return super().on_touch_move(touch)
    
  3. 修改跳动动画,只处理缩放
    动画仅负责大小变化,不再绑定固定位置,避免冲突:

    def beat_animation(self, circle):
        # 定义缩放循环动画:从原大小放大到1.5倍,再缩小回原大小
        anim = Animation(size=(75, 75), duration=0.3) + Animation(size=(50, 50), duration=0.3)
        anim.repeat = True
        anim.start(circle)
        # 同步更新canvas椭圆的大小(如果用canvas绘制)
        def update_ellipse_size(instance, value):
            for instruction in instance.canvas.children:
                if isinstance(instruction, Ellipse):
                    instruction.size = instance.size
        circle.bind(size=update_ellipse_size)
    
  4. 松开手指时清理资源
    在on_touch_up中停止动画并移除对应圆形:

    def on_touch_up(self, touch):
        if touch in self.circles:
            circle = self.circles.pop(touch)
            Animation.cancel_all(circle)
            self.remove_widget(circle)
        return super().on_touch_up(touch)
    

关键说明

  • 拆分逻辑:位置由触摸事件实时驱动,动画只负责视觉缩放,避免两者互相干扰。
  • 多点触控适配:用字典绑定每个touch和对应圆形,确保多手指操作时不会混淆。
  • Canvas同步:如果圆形是用Kivy Canvas绘制的(比如Ellipse),必须在pos/size变化时同步更新Canvas指令的属性,否则绘制的图形不会跟随组件移动。

内容的提问来源于stack exchange,提问作者Lior Malka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:37:08