如何实现Kivy中Line组件circle参数的半径平滑动画效果?
问题描述
我的预期效果:
将半径为100px的圆形通过动画过渡到半径150px的状态,我认为解决方案应该比较简单,但目前我没有找到可行的实现方法。
最小可复现代码
from kivy.app import App from kivy.uix.button import Button from kivy.uix.boxlayout import BoxLayout from kivy.graphics import Line, Ellipse from kivy.clock import Clock from kivy.animation import Animation class AnimationExample(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_interval(self.animate, 2) with self.canvas: self.pulsating_line = Line( circle=(self.center_x, self.center_y, 100), width=2) self.bind(size = self.update, pos = self.update ) def update(self, *args): self.pulsating_line.circle = (self.center_x, self.center_y, 100, ) def animate(self, *args): print('Animate') circ = self.pulsating_line circ.circle = (self.center_x, self.center_y, 100, ) circ.width = 2 # This works for animated "width" Animation(width=8, t='out_bounce', d=1.1).start(circ) # In my opinion is this analogical approach, but of course, it not works :/ # Animation(circle=(self.center_x, # self.center_y, # 150, # ), # t='out_bounce', # d=0.8).start(circ) class TutorialApp(App): def build(self): return AnimationExample() TutorialApp().run()
解决方法
你不能直接对Line.circle元组属性做过渡动画,Kivy的Animation默认不支持元组类型的属性差值计算。可以通过自定义可动画的数值属性实现需求,修改后的代码如下:
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.graphics import Line from kivy.clock import Clock from kivy.animation import Animation from kivy.properties import NumericProperty class AnimationExample(BoxLayout): # 自定义圆形半径属性,支持动画过渡 circle_r = NumericProperty(100) def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_interval(self.animate, 2) with self.canvas: self.pulsating_line = Line( circle=(self.center_x, self.center_y, self.circle_r), width=2) # 绑定属性变化事件:位置/尺寸改变、半径改变时都更新圆形 self.bind(size = self.update_circle, pos = self.update_circle, circle_r = self.update_circle ) def update_circle(self, *args): self.pulsating_line.circle = (self.center_x, self.center_y, self.circle_r, ) def animate(self, *args): print('Animate') circ = self.pulsating_line # 重置初始状态 self.circle_r = 100 circ.width = 2 # 原有描边宽度动画保留 Animation(width=8, t='out_bounce', d=1.1).start(circ) # 直接动画自定义的半径属性即可 Animation(circle_r=150, t='out_bounce', d=0.8).start(self) class TutorialApp(App): def build(self): return AnimationExample() TutorialApp().run()
修改逻辑说明:
- 新增
NumericProperty类型的circle_r属性存储圆形半径,Kivy的Animation原生支持数值类型属性的过渡计算 - 绑定
circle_r属性的变化事件,属性更新时自动刷新圆形的半径参数 - 动画逻辑改为直接对
circle_r属性做过渡,即可实现圆形半径从100px到150px的平滑动画效果
内容的提问来源于stack exchange,提问作者lukassliacky
相关产品推荐
相关产品推荐

