Creating Perfectly Looping Animations With Python

by i95sarmiento in Teachers > University+

7234 Views, 105 Favorites, 0 Comments

Creating Perfectly Looping Animations With Python

cover-ezgif.com-video-to-gif-converter.gif

In this project, we’ll explore a creative technique to make animations that loop perfectly, using periodic functions and offsets in Python. Looping animations are incredibly popular in everything from graphic design to social media posts, video games, and even data visualizations. By creating these smoothly repeating effects, we can craft visually captivating and hypnotic animations that appear to "breathe" with natural rhythm.

This technique relies on three main components:

  1. Periodic Functions: These are functions that repeat at regular intervals, like sine or cosine waves.
  2. Transformation: Applying a visual change to our objects based on the periodic function.
  3. Offset: Adding variation by applying a delay to each object’s transformation, creating patterns that seem to ripple or radiate outward.

Imagine using this to create designs like a grid of dots that pulse from large to small in a perfect wave, or lines that rotate in unison with slight timing differences. This technique is versatile and can be expanded to generate everything from organic textures to kaleidoscopic patterns.

By the end of this project, you’ll have a deeper understanding of how to create looping animations in Python, and you’ll be equipped to experiment with your own unique designs.

Supplies

Materials Needed

  1. A computer
  2. Python installed (along with the matplotlib and numpy libraries)

Setting Up Your Project

Captura de pantalla 2024-11-11 192824.png
Captura de pantalla 2024-11-11 192905.png
Captura de pantalla 2024-11-11 192932.png

Before we dive into coding, let’s set up the file where we’ll write our Python code.

  1. Create the File: Open the folder where you'd like to save your project, and create a new text file. Rename this file to loop.py (make sure it has the .py extension, which tells your computer it’s a Python file).
  2. Open Command Prompt: In the same folder, click on the address bar at the top of the window, type cmd, and press Enter. This will open the Command Prompt directly in the folder where your file is located, making it easy to run your Python code.
  3. Run Your Code: To test or execute your code, simply type loop.py in the Command Prompt and press Enter.

With your project set up, you’re ready to start coding! Let's move on to creating the animation functions that will bring your design to life.

Setting Up the Environment

Captura de pantalla 2024-11-11 193245.png

Before we begin coding, make sure you have matplotlib installed. You can install it via pip:

pip install matplotlib


Defining the Periodic Function

A periodic function will control the movement of objects. Here, we’ll use a sine wave, which loops naturally over time, making it perfect for animations.

import numpy as np

def periodic_function(p):
"""Maps sine function to a usable range for object size."""
return np.interp(np.sin(2 * np.pi * p), [-1, 1], [2, 8])


Creating the Offset Function

The offset creates a delay that gives the illusion of motion propagating through space. In this example, the offset will be based on each object's distance from the center.

def offset(x, y, width, height):
"""Calculate offset based on distance from the center."""
center_x, center_y = width / 2, height / 2
return 0.01 * np.sqrt((x - center_x) ** 2 + (y - center_y) ** 2)


Setting Up the Animation Loop

Captura de pantalla 2024-11-11 193651.png

We’ll use a grid of points and control their size based on the periodic function and offset. This setup allows us to render each frame with dynamic points that grow and shrink in sync, creating a mesmerizing effect.

import matplotlib.pyplot as plt

# Parameters
num_frames = 60
grid_size = 40
width, height = 500, 500

# Create figure
fig, ax = plt.subplots()
plt.axis("equal")
plt.axis("off")

# Generate frames
for frame in range(num_frames):
plt.cla()
t = frame / num_frames
for i in range(grid_size):
for j in range(grid_size):
x = np.interp(i, [0, grid_size - 1], [0, width])
y = np.interp(j, [0, grid_size - 1], [0, height])
size = periodic_function(t - offset(x, y, width, height))
ax.plot(x, y, 'o', markersize=size, color="black")

plt.pause(0.1)

plt.show()


Downloads

Exporting As a GIF

animation.gif
animation1.gif
animation2.gif
animation3.gif
animation4.gif
animation5.gif

To create a GIF, we can save each frame and use imageio to compile them.

import imageio

frames = []
for frame in range(num_frames):
t = frame / num_frames
ax.clear() # Clear the graph on each frame to avoid overlaps

# Draw the dot grid
for i in range(grid_size):
for j in range(grid_size):
x = np.interp(i, [0, grid_size - 1], [0, width])
y = np.interp(j, [0, grid_size - 1], [0, height])
size = periodic_function(t - offset(x, y, width, height))
ax.plot(x, y, 'o', markersize=size, color="black")

# Render the canvas image
fig.canvas.draw()
image = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))

frames.append(image) # Add the rendered image to frames

# Save GIF
imageio.mimsave('animation.gif', frames, duration=0.1)


You can vary the parameters num_frames, grid_size and width, height to get different results.

Downloads

Experimenting With Different Offsets

animation6.gif
animation7.gif
animation8.gif

Try changing the offset function to experiment with other patterns, like rotating lines or creating spiral effects. Here's an example for rotation:

def linear_offset(x, y, width, height):
"""Offset based on rotation across x and y."""
return 0.005 * (x + 2 * y)

Final Thoughts

With these periodic and offset functions, the possibilities are endless. By adjusting parameters, you can create unique animations and patterns with a distinct visual rhythm.