Desenvolvimento de aplicações mobile em Python. Criação de animações em Kivy. Parte 2



Saudações a todos os fãs e especialistas da linguagem de programação Python!



Hoje, continuaremos a lidar com o tópico de animações em uma estrutura de plataforma cruzada para suporte multi-touch - Kivy em conjunto com a biblioteca de componentes do Google Material Design - KivyMD . No último artigo, já analisamos um exemplo de aplicação de teste em Python / Kivy / KivyMD, neste iremos abordar o tema animações com mais detalhes. No final do artigo, irei fornecer um link para o repositório do projeto, onde você pode baixar e sentir por si mesmo, um aplicativo de demonstração Kivy / KivyMD. Como o anterior, este artigo conterá não um pequeno número de animações e vídeos GIF, então sirva um pouco de café e vamos lá!



Kivy é executado em Linux, Windows, OS X, Android, iOS e Raspberry Pi. Você pode executar o mesmo código em todas as plataformas suportadas sem fazer quaisquer alterações adicionais na base de código. Kivy suporta uma ampla variedade de dispositivos de entrada, incluindo WM_Touch, WM_Pen, Mac OS X Trackpad e Magic Mouse, Mtdev, Linux Kernel HID, TUIO e, como Flutter, não usa controles nativos. Todos os seus widgets são personalizáveis. Isso significa que os aplicativos Kivy terão a mesma aparência em todas as plataformas. Mas devido ao fato de que os widgets Kivy podem ser personalizados como você quiser, você pode criar seus próprios widgets. Por exemplo, é assim que a biblioteca KivyMD apareceu . Antes de continuar, vamos dar uma olhada em uma pequena visão geral dos recursos do Kivy:



Demonstrações do aplicativo Kivy












Esses vídeos demonstram claramente a interação do aplicativo Kivy com o usuário por meio de gestos e animações. Vamos criar um aplicativo simples com animação de dois rótulos:



from kivy.animation import Animation
from kivy.lang import Builder

from kivymd.app import MDApp


KV = """
<CommonLabel@MDLabel>
    opacity: 0
    adaptive_height: True
    halign: "center"
    y: -self.height


MDScreen:
    on_touch_down: app.start_animation()

    CommonLabel:
        id: lbl_1
        font_size: "32sp"
        text: "M A R S"

    CommonLabel:
        id: lbl_2
        font_size: "12sp"
        text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
"""


class TestAnimation(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def start_animation(self):
        lbl_1 = self.root.ids.lbl_1
        lbl_2 = self.root.ids.lbl_2

        Animation(
            opacity=1, y=lbl_1.height * 2, d=0.9, t="in_out_back"
        ).start(lbl_1)
        Animation(
            opacity=1, y=lbl_2.height + ids.lbl_1.height, d=1, t="in_out_back"
        ).start(lbl_2)


TestAnimation().run()


Este é um aplicativo pronto para uso. Vamos apenas editá-lo ligeiramente. A regra CommonLabel na linha KV é semelhante à criação de uma classe no código Python. Comparar:





O código em Kivy Language é sempre mais curto e mais legível. Portanto, no código Python, teremos apenas lógica. Criamos dois rótulos com propriedades comuns descritas na regra CommonLabel : opacidade , tamanho da textura do rótulo ( adaptive_height ), alinhamento horizontal ( halign ), posição do eixo Y ( y ) e atribuímos a esses rótulos id-shniki ( lbl_1 , lbl_2 ) para ser capaz de acessar e manipular as propriedades de objetos de rótulo do código Python. Em seguida, nós anexado a start_animation chamada de método para a on_touch_down evento (acionado quando tocar a qualquer lugar da tela)no qual vamos animar nossos dois rótulos.



Animação



Kivy usa a classe Animation para animar objetos . O uso é muito simples: ao inicializar a classe Animation, você deve passar nomes de propriedades com valores de destino que serão alcançados no final da animação como argumentos. Por exemplo:



    def start_animation(self):
        #     KV 
        lbl_1 = self.root.ids.lbl_1
        lbl_2 = self.root.ids.lbl_2
        #   
        Animation(
            opacity=1,  #     1
            y=lbl_1.height * 2,  #      Y
            d=0.9,  #   
            t="in_out_back"  #  
        ).start(lbl_1)  #   start  ,   
        #   
        Animation(
            opacity=1, y=lbl_2.height + lbl_1.height, d=1, t="in_out_back"
        ).start(lbl_2)


Na animação abaixo, demonstrei o resultado da animação mais simples que criamos, com diferentes tipos de animação:



  1. in_out_back
  2. out_elastic
  3. linear




Vamos complicar um pouco a tarefa e tentar animar a rotação dos rótulos no plano. Para isso, usaremos manipulações de matriz ( PushMatrix, PopMatrix, Rotate, Translate, Scale ). Adicione uma instrução de tela ao rótulo compartilhado :



<CommonLabel@MDLabel>
    angle: 180  #  
    [...]

    canvas.before:
        PushMatrix
        Rotate:
            angle: self.angle
            origin: self.center
    canvas.after:
        PopMatrix


E no código Python, passaremos uma nova propriedade de ângulo para animação para a classe Animation:



    def start_animation(self):
        lbl_1 = self.root.ids.lbl_1
        lbl_2 = self.root.ids.lbl_2

        Animation(angle=0, [...]).start(lbl_1)
        Animation(angle=0, [...]).start(lbl_2)


Resultado:



Vamos adicionar uma animação da escala dos rótulos:



<CommonLabel@MDLabel>
    scale: 5  #  
    [...]

    canvas.before:
        PushMatrix
        [...]
        Scale:
            #    
            x: self.scale
            y: self.scale
            z: self.scale
            origin: self.center
    canvas.after:
        PopMatrix


No código Python, passaremos uma nova propriedade de escala para animação para a classe Animation:



    def start_animation(self):
        lbl_1 = self.root.ids.lbl_1
        lbl_2 = self.root.ids.lbl_2

        Animation(scale=1, [...]).start(lbl_1)
        Animation(scale=1, [...]).start(lbl_2)


Resultado:



A classe Animation possui vários eventos para rastrear o processo de animação: on_start, on_progress, on_complete . Considere o último. on_complete é chamado quando o processo de animação termina. Vamos vincular este evento ao método complete_animation que criaremos agora:



[...]


class TestAnimation(MDApp):
    [...]

    def complete_animation(self, animation, animated_instance):
        """
        :type animation: <kivy.animation.Animation object>
        :type animated_instance: <WeakProxy to <kivy.factory.CommonLabel object>>
        """

        #      .
        Animation(scale=1.4, d=1, t="in_out_back").start(animated_instance)
        Animation(color=(1, 0, 1, 1), d=1).start(animated_instance)


Nós vinculamos o evento:



    def start_animation(self):
        [...]

        animation = Animation(
            angle=0, scale=1, opacity=1, y=lbl_1.height * 2, d=0.9, t="in_out_back"
        )
        animation.bind(on_complete=self.complete_animation)
        animation.start(lbl_1)

        [....]


Resultado:



É tudo por agora. Perguntou:



Abaixo, anexo uma prévia do projeto Kivy / KivyMD e um link para o repositório onde você pode baixar o APK e tocar em:



O repositório



APK pode ser encontrado no diretório do repositório - StarTest / bin



All Articles