Tuesday, July 8, 2014

47. Animated Splash Screen


Letters are animated, between initial and final positions, with bounce.




This is the letter images used. The zip file contains many images.




You should extract it to the folder where the kv and python files are.




These are the imports. The Widget is for the root. The Image is for the individual letters. Any application needs the App. The Animation is imported so we can use the in-built animation. We use 3 Properties, to hold the different variables. We also import the Window class since we want to know the window size in the globals, that is, outside the classes. The Clock is needed to set the animations at certain times.




Here, the strings corresponds to the name of image file, for 6 of the letters. We use a template string, so we don't have to write the entire string many times.




The word written in the application is 'THE GAME'. We have 7 letters, only 6 are unique. This is the reason only 6 images are needed. These are the initial positions of the 7 letters.




These correspond to the final positions of the 7 letters.




The Letter class is based on Image class. There are three Properties, a String to hold filename, a counter to hold a number between 0 and 6. The pos Boolean indicates if the letters are at initial position or at final position. The initialization code just starts a function start_anim.




The function start_anim first reads the counter. Thus it can set the final position after the animation. There is a bounce at the end. Once it is at final position, the variable pos becomes True.




If a touch or click is detected, depending on where the letters are, a forward animation is started or a reverse animation.




This shows what we mean by reverse animation. We go from final positions to initial positions, with a bounce at start. Now the pos becomes False to indicate a complete cycle. Now if touch is detected, it can start the forward animation.




The root Widget creates the 7 letters. The function initial_positions was scheduled in the app. The string 'TheGame' is converted to a list, meaning each character will be iterated over. enumerate() is used to get index as well as a character. Then a Letter() is created pointing to appropriate filename, the counter position, and the initial position.




In the app, we schedule the function initial_positions, where the letters will be created.


# ex47.py

from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.app import App
from kivy.animation import Animation
from kivy.properties import (StringProperty, NumericProperty,
                             BooleanProperty)
from kivy.core.window import Window
from kivy.clock import Clock

LETTERS={}
LETT_TEMPLATE = ('Letter_Blocks_01/'
                 'Letter_Blocks_01_Set_4_{}_64x64.png')
LETTERS['T'] = LETT_TEMPLATE.format('T')
LETTERS['H'] = LETT_TEMPLATE.format('H')
LETTERS['E'] = LETT_TEMPLATE.format('E')
LETTERS['G'] = LETT_TEMPLATE.format('G')
LETTERS['A'] = LETT_TEMPLATE.format('A')
LETTERS['M'] = LETT_TEMPLATE.format('M')

POSITIONS={}
POSITIONS[0]=100,Window.height-100
POSITIONS[1]=Window.width/2,Window.height-50
POSITIONS[2]=Window.width-100,Window.height-100
POSITIONS[3]=100,100
POSITIONS[4]=Window.width/3,50
POSITIONS[5]=2*Window.width/3,50
POSITIONS[6]=Window.width-100,100

FPOSITIONS={}
_X,_Y = Window.width/2,Window.height/2
FPOSITIONS[0]=_X-64,_Y+32
FPOSITIONS[1]=_X,_Y+32
FPOSITIONS[2]=_X+64,_Y+32
FPOSITIONS[3]=_X-96,_Y-32
FPOSITIONS[4]=_X-32,_Y-32
FPOSITIONS[5]=_X+32,_Y-32
FPOSITIONS[6]=_X+96,_Y-32

class Letter(Image):
    fname = StringProperty()
    counter = NumericProperty()
    pos = BooleanProperty(False)

    def __init__(self, **kwargs):
        super(Letter, self).__init__(**kwargs)
        Clock.schedule_once(self.start_anim,.1)

    def start_anim(self,dt):
        i=self.counter
        Animation.cancel_all(self)
        anim = Animation(center_x = FPOSITIONS[i][0],
                         center_y = FPOSITIONS[i][1],
                         t='out_bounce',
                         d = 5)
        anim.start(self)
        self.pos = True
        
    def on_touch_down(self,touch):
        if self.pos == True:
            Clock.schedule_once(self.rev_anim,.1)
        else:
            Clock.schedule_once(self.start_anim,.1)

    def rev_anim(self,dt):
        i=self.counter
        Animation.cancel_all(self)
        anim = Animation(center_x = POSITIONS[i][0],
                         center_y = POSITIONS[i][1],
                         t='in_bounce',
                         d = 5)
        anim.start(self)
        self.pos = False

class Ex47(Widget):
    def initial_positions(self,dt):
        for i,lett in enumerate(list('TheGame')):
            letter = Letter()
            letter.fname = LETTERS[lett.upper()]
            letter.center = POSITIONS[i]
            letter.counter = i
            self.add_widget(letter)

       
class Ex47App(App):
    def build(self):
        ex47=Ex47()
        Clock.schedule_once(ex47.initial_positions,.5)
        return ex47

if __name__=='__main__':
    Ex47App().run()



In the kv file, we only need to connect the source to the correct filename.




Then we create a gray background color.


# ex47.kv

<Letter>:
    source: root.fname
        
<Ex47>:
    canvas:
        Color:
            rgb: .75,.75,.75
        Rectangle:
            size: self.size
            pos: self.pos   
        


Demo of App on Youtube

3 comments:

  1. Python:

    Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    https://www.emexotechnologies.com/online-courses/python-training-in-electronic-city/

    ReplyDelete
  2. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    Python Training in electronic city

    ReplyDelete
  3. Good post.thank you.
    visit
    web programming tutorial
    welookups

    ReplyDelete