How to Create Canvas Animation Using Tkinter

Tkinter is one of the most popular GUI toolkits available for python. It is available as part of the standard python installation. Hence you can use this package without installing any additional modules. Tkinter is a powerful GUI library and you can use it to build full fledged user interfaces or build simple desktop games.

This article contains a step by step guide on building an animation using the python tkinter package. We will be using canvas object of the tkinter package to draw our animation. Note that the following program requires python 3.6 or above.

The following python program creates a simple animation showing the movement of a ball across the screen. Following are the steps in the program,

  • Create and display main window of the application
  • Create and attach the canvas to the main window. We will be drawing to this canvas
  • Draw and animate a circle (our ball) inside the canvas

Let us start by importing tkinter and time modules. We will use time module to introduce a delay for drawing successive screens of the animation,

import tkinter
import time

Let us now create a set of variables for our animation demo. This defines the size of our gaming canvas, speed of the ball, size of the ball and where we want our ball to start moving from.

# width of the animation window
animation_window_width=800
# height of the animation window
animation_window_height=600
# initial x position of the ball
animation_ball_start_xpos = 50
# initial y position of the ball
animation_ball_start_ypos = 50
# radius of the ball
animation_ball_radius = 30
# the pixel movement of ball for each iteration
animation_ball_min_movement = 5
# delay between successive frames in seconds
animation_refresh_seconds = 0.01

The following function creates the application window with the specified title and dimensions,

# The main window of the animation
def create_animation_window():
  window = tkinter.Tk()
  window.title("Tkinter Animation Demo")
  # Uses python 3.6+ string interpolation
  window.geometry(f'{animation_window_width}x{animation_window_height}')
  return window

We then create a function to create the animation canvas and attach it to the main window,

# Create a canvas for animation and add it to main window
def create_animation_canvas(window):
  canvas = tkinter.Canvas(window)
  canvas.configure(bg="black")
  canvas.pack(fill="both", expand=True)
  return canvas

Let us now create a function to create and animate a circle in an infinite loop. We use the create_oval method to create a circle(ball) with specified radius and draw it on canvas. We move the ball until it reaches a boundary and then we reverse the direction of the ball. Note the use of move method of canvas which lets us move a drawing in the canvas to another location. Also note the use of python array unpacking to get the location of the ball.

# Create and animate ball in an infinite loop
def animate_ball(window, canvas,xinc,yinc):
  ball = canvas.create_oval(animation_ball_start_xpos-animation_ball_radius,
            animation_ball_start_ypos-animation_ball_radius,
            animation_ball_start_xpos+animation_ball_radius,
            animation_ball_start_ypos+animation_ball_radius,
            fill="blue", outline="white", width=4)
  while True:
    canvas.move(ball,xinc,yinc)
    window.update()
    time.sleep(animation_refresh_seconds)
    ball_pos = canvas.coords(ball)
    # unpack array to variables
    xl,yl,xr,yr = ball_pos
    if xl < abs(xinc) or xr > animation_window_width-abs(xinc):
      xinc = -xinc
    if yl < abs(yinc) or yr > animation_window_height-abs(yinc):
      yinc = -yinc

Finally let us call all the functions in order to run our animation,

# The actual execution starts here
animation_window = create_animation_window()
animation_canvas = create_animation_canvas(animation_window)
animate_ball(animation_window,animation_canvas, animation_ball_min_movement, animation_ball_min_movement)

Full code of the python animation demo using tkinter is given below. This can be easily extended to a bat and ball game if you know event handling in tkinter. Save the following code in "tkinter-draw-demo.py" file and then run the command "python3 tkinter-draw-demo.py" to see the animation.

import tkinter
import time

# width of the animation window
animation_window_width=800
# height of the animation window
animation_window_height=600
# initial x position of the ball
animation_ball_start_xpos = 50
# initial y position of the ball
animation_ball_start_ypos = 50
# radius of the ball
animation_ball_radius = 30
# the pixel movement of ball for each iteration
animation_ball_min_movement = 5
# delay between successive frames in seconds
animation_refresh_seconds = 0.01

# The main window of the animation
def create_animation_window():
  window = tkinter.Tk()
  window.title("Tkinter Animation Demo")
  # Uses python 3.6+ string interpolation
  window.geometry(f'{animation_window_width}x{animation_window_height}')
  return window

# Create a canvas for animation and add it to main window
def create_animation_canvas(window):
  canvas = tkinter.Canvas(window)
  canvas.configure(bg="black")
  canvas.pack(fill="both", expand=True)
  return canvas

# Create and animate ball in an infinite loop
def animate_ball(window, canvas,xinc,yinc):
  ball = canvas.create_oval(animation_ball_start_xpos-animation_ball_radius,
            animation_ball_start_ypos-animation_ball_radius,
            animation_ball_start_xpos+animation_ball_radius,
            animation_ball_start_ypos+animation_ball_radius,
            fill="blue", outline="white", width=4)
  while True:
    canvas.move(ball,xinc,yinc)
    window.update()
    time.sleep(animation_refresh_seconds)
    ball_pos = canvas.coords(ball)
    # unpack array to variables
    xl,yl,xr,yr = ball_pos
    if xl < abs(xinc) or xr > animation_window_width-abs(xinc):
      xinc = -xinc
    if yl < abs(yinc) or yr > animation_window_height-abs(yinc):
      yinc = -yinc

# The actual execution starts here
animation_window = create_animation_window()
animation_canvas = create_animation_canvas(animation_window)
animate_ball(animation_window,animation_canvas, animation_ball_min_movement, animation_ball_min_movement)