使用自定义宽度为 Kivy Bezier 曲线制作动画? (有点傻的问题)
animate Kivy Bezier curve with custom width ? (a bit silly question)
更新:在与其他人讨论后,我认为这是一个有点愚蠢的问题。我想为改变宽度的贝塞尔曲线制作动画,但它没有宽度 属性。使用 Line Bezier,我可以更改宽度,但无法设置动画。
我无法像 Line
那样改变 Bezier
曲线的 witdh
。
这是代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *
class MyLayout(Widget):
def __init__(self):
super(MyLayout, self).__init__()
with self.canvas:
self.L=Bezier(points=[200,450,500,300,600,150],width=12)
self.k=Line (bezier=[100,350,400,200,500,50 ],width=12)
class MyApp(App):
def __init__(self):
super(MyApp, self).__init__()
def build(self):
return MyLayout()
if __name__=="__main__":
MyApp().run()
并输出:
问题是,
上面的曲线不是 width=12
。
我认为那是因为 Kivy 的贝塞尔 Class 没有属性 width
因为当我在 kv
lang 上这样做时,它给了我 AttributeError: 'kivy.graphics.vertex_instructions.Bezier' object has no attribute 'width'
。那么,为什么不使用 Line
和 bezier
呢?我想在其上使用 Animation
,当我尝试在 Line
上使用 bezier
时,我得到 AttributeError: attribute 'bezier' of 'kivy.graphics.vertex_instructions.Line' objects is not readable
.
所以这个问题,
如何更改 Bezier
的 width
。如果不可能,是否有任何方法可以找到给定 x 的 cruve(或 ys)的 y 以便我可以将 Ellipse
放在这些点上并调整它们的大小以模拟宽度?
谢谢并原谅我的英语♥
Bezier
没有width
属性,但是Line
有。所以你可以为 width
设置动画。一个简单的方法是通过动画 NumericProperty
来保持宽度。这是您的代码的修改版本:
from kivy.animation import Animation
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
from kivy.graphics import *
class MyLayout(Widget):
line_width = NumericProperty(12)
def __init__(self):
super(MyLayout, self).__init__()
with self.canvas:
self.L=Bezier(points=[200,450,500,300,600,150],width=self.line_width)
self.k=Line (bezier=[100,350,400,200,500,50 ],width=self.line_width)
def on_line_width(self, instance, new_width):
self.k.width = new_width
class MyApp(App):
def build(self):
Clock.schedule_once(self.anim)
return MyLayout()
def anim(self, dt):
a = Animation(line_width=3)
a.start(self.root)
if __name__=="__main__":
MyApp().run()
如果您在 kv
中构建 Line
,那么您甚至不需要 on_line_width()
方法,因为 kivy 会为您进行绑定。
线路可以使用bezier:
,例如:
Line:
bezier:[n1,n2,n3,n4]
width:3
这是 Line
,而不是 Bezier
,但您得到的结果相同...
一个例子:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
posicao=[]
class Draw(BoxLayout):
def __init__(self, **kwargs):
super(Draw, self).__init__(**kwargs)
def on_touch_down(self,touch):
posicao.append(touch.pos)
def on_touch_up(self,touch):
posicao.clear()
def on_touch_move(self,touch):
Line = Builder.load_string(
"""
FloatLayout:
canvas:
Color:
rgba:11,.1,1,1
Line:
points: {pos}
width:14
""".format(pos=(touch.pos, posicao[0])))
self.add_widget(Line)
posicao.clear()
posicao.append(touch.pos)
class Code(App):
def build(self):
return Draw()
if __name__ == '__main__':
Code().run()
我
或者:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *
posi = []
Builder.load_string(
"""
<Draw>:
""")
class Draw(BoxLayout):
def __init__(self, **kwargs):
super(Draw, self).__init__(**kwargs)
def on_touch_down(self,touch):
posi.clear()
posi.append(touch.pos)
def on_touch_up(self,touch):
posi.clear()
def on_touch_move(self,touch):
with self.canvas:
Line(points=[posi[0], touch.pos],width=14)
posi.clear()
posi.append(touch.pos)
class Code(App):
def build(self):
return Draw()
if __name__ == '__main__':
Code().run()
更新:在与其他人讨论后,我认为这是一个有点愚蠢的问题。我想为改变宽度的贝塞尔曲线制作动画,但它没有宽度 属性。使用 Line Bezier,我可以更改宽度,但无法设置动画。
我无法像 Line
那样改变 Bezier
曲线的 witdh
。
这是代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import *
class MyLayout(Widget):
def __init__(self):
super(MyLayout, self).__init__()
with self.canvas:
self.L=Bezier(points=[200,450,500,300,600,150],width=12)
self.k=Line (bezier=[100,350,400,200,500,50 ],width=12)
class MyApp(App):
def __init__(self):
super(MyApp, self).__init__()
def build(self):
return MyLayout()
if __name__=="__main__":
MyApp().run()
并输出:
问题是,
上面的曲线不是 width=12
。
我认为那是因为 Kivy 的贝塞尔 Class 没有属性 width
因为当我在 kv
lang 上这样做时,它给了我 AttributeError: 'kivy.graphics.vertex_instructions.Bezier' object has no attribute 'width'
。那么,为什么不使用 Line
和 bezier
呢?我想在其上使用 Animation
,当我尝试在 Line
上使用 bezier
时,我得到 AttributeError: attribute 'bezier' of 'kivy.graphics.vertex_instructions.Line' objects is not readable
.
所以这个问题,
如何更改 Bezier
的 width
。如果不可能,是否有任何方法可以找到给定 x 的 cruve(或 ys)的 y 以便我可以将 Ellipse
放在这些点上并调整它们的大小以模拟宽度?
谢谢并原谅我的英语♥
Bezier
没有width
属性,但是Line
有。所以你可以为 width
设置动画。一个简单的方法是通过动画 NumericProperty
来保持宽度。这是您的代码的修改版本:
from kivy.animation import Animation
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
from kivy.graphics import *
class MyLayout(Widget):
line_width = NumericProperty(12)
def __init__(self):
super(MyLayout, self).__init__()
with self.canvas:
self.L=Bezier(points=[200,450,500,300,600,150],width=self.line_width)
self.k=Line (bezier=[100,350,400,200,500,50 ],width=self.line_width)
def on_line_width(self, instance, new_width):
self.k.width = new_width
class MyApp(App):
def build(self):
Clock.schedule_once(self.anim)
return MyLayout()
def anim(self, dt):
a = Animation(line_width=3)
a.start(self.root)
if __name__=="__main__":
MyApp().run()
如果您在 kv
中构建 Line
,那么您甚至不需要 on_line_width()
方法,因为 kivy 会为您进行绑定。
线路可以使用bezier:
,例如:
Line:
bezier:[n1,n2,n3,n4]
width:3
这是 Line
,而不是 Bezier
,但您得到的结果相同...
一个例子:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
posicao=[]
class Draw(BoxLayout):
def __init__(self, **kwargs):
super(Draw, self).__init__(**kwargs)
def on_touch_down(self,touch):
posicao.append(touch.pos)
def on_touch_up(self,touch):
posicao.clear()
def on_touch_move(self,touch):
Line = Builder.load_string(
"""
FloatLayout:
canvas:
Color:
rgba:11,.1,1,1
Line:
points: {pos}
width:14
""".format(pos=(touch.pos, posicao[0])))
self.add_widget(Line)
posicao.clear()
posicao.append(touch.pos)
class Code(App):
def build(self):
return Draw()
if __name__ == '__main__':
Code().run()
我 或者:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *
posi = []
Builder.load_string(
"""
<Draw>:
""")
class Draw(BoxLayout):
def __init__(self, **kwargs):
super(Draw, self).__init__(**kwargs)
def on_touch_down(self,touch):
posi.clear()
posi.append(touch.pos)
def on_touch_up(self,touch):
posi.clear()
def on_touch_move(self,touch):
with self.canvas:
Line(points=[posi[0], touch.pos],width=14)
posi.clear()
posi.append(touch.pos)
class Code(App):
def build(self):
return Draw()
if __name__ == '__main__':
Code().run()