Animation is about making graphic objects move smoothly around a screen. The method to create the sensation of smooth dynamic action is simple:
Besides the obvious applications of making animated figures move around on a screen for entertainment, animating the results of computer code gives you powerful insights into how code works at a detailed level. Animation offers an extra dimension to the programmers’ debugging arsenal. It provides you with an all encompassing, holistic view of software execution in progress that nothing else can.
We make an image of a small colored disk and draw it in a sequence of different positions.
Execute the program shown and you will see a neat row of colored disks laid on top of each other going from top left to bottom right. The idea is to demonstrate the method of systematic position shifting.
# moveball_1.py #>>>>>>>>>>>>> from Tkinter import * root = Tk() root.title("shifted sequence") cw = 250 # canvas width ch = 130 # canvas height
chart_1 = Canvas(root, width=cw, height=ch, background=”white”)
chart_1.grid(row=0, column=0)
# The parameters determining the dimensions of the ball and its
# position.
# =====================================
posn_x = 1 # x position of box containing the ball (bottom)
posn_y = 1 # y position of box containing the ball (left edge)
shift_x = 3 # amount of x-movement each cycle of the ‘for’ loop
shift_y = 2 # amount of y-movement each cycle of the ‘for’ loop
ball_width = 12 # size of ball – width (x-dimension)
ball_height = 12 # size of ball – height (y-dimension)
color = “violet” # color of the ball
for i in range(1,50): # end the program after 50 position shifts
posn_x += shift_x
posn_y += shift_y
chart_1.create_oval(posn_x, posn_y, posn_x + ball_width,
posn_y + ball_height,
fill=color)
root.mainloop()
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
A simple ball is drawn on a canvas in a sequence of steps, one on top of the other. For each step, the position of the ball is shifted by three pixels as specified by the size of shift_x. Similarly, a downward shift of two pixels is applied by an amount to the value of shift_y. shift_x and shift_y only specify the amount of shift, but they do not make it happen. What makes it happen are the two commands posn_x += shift_x and posn_y += shift_y. posn is the abbreviation for position.
posn_x += shift_x means “take the variable posn_x and add to it an amount shift_x.” It is the same as posn_x = posn_x + shift_x.
Another minor point to note is the use of the line continuation character, the backslash “”. We use this when we want to continue the same Python command onto a following line to make reading easier. Strictly speaking for text inside brackets “(…)” this is not needed. In this particular case you can just insert a carriage return character. However, the backslash makes it clear to anyone reading your code what your intention is.
The series of ball images in this recipe were drawn in a few microseconds. To create decent looking animation, we need to be able to slow the code execution down by just the right amount. We need to draw the equivalent of a movie frame onto the screen and keep it there for a measured time and then move on to the next, slightly shifted, image. This is done in the next recipe.
Here we introduce the time control function canvas.after(milliseconds) and the canvas.update() function that refreshes the image on the canvas. These are the cornerstones of animation in Python.
Control of when code gets executed is made possible by the time module that comes with the standard Python library.
Execute the program as previously. What you will see is a diagonal row of disks being laid in a line with a short delay of one fifth of a second (200 milliseconds) between updates. The result is shown in the following screenshot showing the ball shifting in regular intervals.
# timed_moveball_1.py #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from Tkinter import * root = Tk() root.title("Time delayed ball drawing")
cw = 300 # canvas width
ch = 130 # canvas height
chart_1 = Canvas(root, width=cw, height=ch, background=”white”)
chart_1.grid(row=0, column=0)
cycle_period = 200 # time between fresh positions of the ball
# (milliseconds).
# The parameters determining the dimensions of the ball and it’s
# position.
posn_x = 1 # x position of box containing the ball (bottom).
posn_y = 1 # y position of box containing the ball (left edge).
shift_x = 3 # amount of x-movement each cycle of the ‘for’ loop.
shift_y = 3 # amount of y-movement each cycle of the ‘for’ loop.
ball_width = 12 # size of ball – width (x-dimension).
ball_height = 12 # size of ball – height (y-dimension).
color = “purple” # color of the ball
for i in range(1,50): # end the program after 50 position shifts.
posn_x += shift_x
posn_y += shift_y
chart_1.create_oval(posn_x, posn_y, posn_x + ball_width,
posn_y + ball_height, fill=color)
chart_1.update() # This refreshes the drawing on the canvas.
chart_1.after(cycle_period) # This makes execution pause for 200
# milliseconds.
root.mainloop()
This recipe is the same as the previous one except for the canvas.after(…) and the canvas.update() methods. These are two functions that come from the Python library. The first gives you some control over code execution time by allowing you to specify delays in execution. The second forces the canvas to be completely redrawn with all the objects that should be there. There are more complicated ways of refreshing only portions of the screen, but they create difficulties so they will not be dealt with here.
The canvas.after(your-chosen-milliseconds) method simply causes a timed-pause to the execution of the code. In all the preceding code, the pause is executed as fast as the computer can do it, then when the pause, invoked by the canvas.after() method is encountered, execution simply gets suspended for the specified number of milliseconds. At the end of the pause, execution continues as if nothing ever happened.
The canvas.update() method forces everything on the canvas to be redrawn immediately rather than wait for some unspecified event to cause the canvas to be refreshed.
The next step in effective animation is to erase the previous image of the object being animated shortly before a fresh, shifted clone is drawn on the canvas. This happens in the next example.
It is also worth noting that Tkinter is robust. When you give position coordinates that are off the canvas, Python does not crash or freeze. It simply carries on drawing the object ‘off-the-page’. The Tkinter canvas can be seen as just a tiny window into an almost unlimited universe of visual space. We only see objects when they move into the view of the camera which is the Tkinter canvas.
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…