Search code examples
pythonuser-interfacekivybezier

animate Kivy Bezier curve with custom width ? (a bit silly question)


update: After discussing with others, I decided that it is a bit silly question. I wanted to animate Bezier curve with changed width, but it has no width property. with Line Bezier, I can change width, but then can't animate.


I can't change witdh of Bezier curve like Line.
here is the code:

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()

and outupt: MyApp

the problem is,

the upper curve isn't width=12.

I think that's because Kivy's Bezier Class has no attribute width cuz when I do it on kv lang, it gives me AttributeError: 'kivy.graphics.vertex_instructions.Bezier' object has no attribute 'width'. Well, why not using Line with bezier ? I want to use Animation on it and when I try to on Line with bezier, I get AttributeError: attribute 'bezier' of 'kivy.graphics.vertex_instructions.Line' objects is not readable.

so the question,

how can I change width of Bezier. if it is not possible, is there any way like finding the y of cruve (or ys) for given x so I can put Ellipse on these points and resize them to simulate width ?

thanks and pardon my english


Solution

  • The line can use bezier:, example:

    Line:
        bezier:[n1,n2,n3,n4]
        width:3
    

    This is a Line, not a Bezier, but you get the same result...

    One example:

    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()
    

    Or:

    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()