Heart Animation Program with Python and Tkinter

Time: Column:Python views:190

Learn how to create a dynamic heart animation using Python's Tkinter library. This tutorial explains the complete code structure, mathematical functions, and GUI implementation to render a romantic heart with "I Love You!" text in the center.

Heart Animation Program with Python and Tkinter

Complete Code

import tkinter as tk
import tkinter.messagebox
import random
from math import sin, cos, pi, log
from tkinter.constants import *

width = 888
height = 500
heartx = width / 2
hearty = height / 2
side = 11
heartcolor = "skyblue"  # Heart color, can be customized
word = "I Love You!"  # Text to display, can be customized

# Heart class
class Heart:
    def __init__(self, generate_frame=20):
        self._points = set()  # Set of original heart coordinates
        self._edge_diffusion_points = set()  # Edge diffusion effect points
        self._center_diffusion_points = set()  # Center diffusion effect points
        self.all_points = {}  # Dynamic coordinates for each frame
        self.build(2000)
        self.random_halo = 1000
        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):
        for _ in range(number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t)
            self._points.add((x, y))
        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.05)
                self._edge_diffusion_points.add((x, y))
        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.17)
            self._center_diffusion_points.add((x, y))

Code Analysis
This code is a heart animation program written with the tkinter library. It displays a dynamic heart animation and shows the text "I Love You!" in the center of the screen. The code consists of multiple functional modules, which will be analyzed below:

1. Importing Libraries

import tkinter as tk
import tkinter.messagebox
import random
from math import sin, cos, pi, log
from tkinter.constants import *
  • tkinter: Used to create Graphical User Interfaces (GUI).

  • random: Generates random numbers, used to add random effects in the animation.

  • math: Provides mathematical calculations, such as trigonometric and logarithmic functions, used to generate the heart shape.

  • tkinter.constants: Includes constants for alignment and positioning, e.g., CENTER.


2. Global Variable Definitions

width = 888
height = 500
heartx = width / 2
hearty = height / 2
side = 11
heartcolor = "skyblue"  # Heart color, can be customized
word = "I Love You!"  # Text to display, can be customized
  • width and height: Define the width and height of the canvas.

  • heartx and hearty: Center coordinates of the heart.

  • side: Sets the initial size of the heart.

  • heartcolor: Determines the heart's color.

  • word: Text displayed on the screen.


3. Heart Class

The Heart class generates and renders the dynamic heart effect.

3.1 __init__ Method

def __init__(self, generate_frame=20):
    self._points = set()  # Set of original heart coordinates
    self._edge_diffusion_points = set()  # Edge diffusion effect points
    self._center_diffusion_points = set()  # Center diffusion effect points
    self.all_points = {}  # Dynamic coordinates for each frame
    self.build(2000)
    self.random_halo = 1000
    self.generate_frame = generate_frame
    for frame in range(generate_frame):
        self.calc(frame)
  • self._points, self._edge_diffusion_points, self._center_diffusion_points: Store the heart's original points, edge diffusion effect points, and center diffusion effect points, respectively.

  • self.all_points: Saves all point data for each frame.

  • self.build(2000): Constructs the heart shape and diffusion effects.

  • self.random_halo: Controls the intensity of the halo effect.

  • self.generate_frame: Determines the number of frames, affecting animation smoothness.


3.2 build Method

def build(self, number):
    for _ in range(number):
        t = random.uniform(0, 2 * pi)
        x, y = heart_function(t)
        self._points.add((x, y))
  • self._points: Generates random t values to calculate the heart shape points using the heart_function.

  • Diffusion Effects: Adds more points to self._edge_diffusion_points and self._center_diffusion_points for edge and center diffusion effects.


3.3 calc_position Method

def calc_position(x, y, ratio):
    force = 1 / (((x - heartx) ** 2 + (y - hearty) ** 2) ** 0.520)  # Magical parameter
    dx = ratio * force * (x - heartx) + random.randint(-1, 1)
    dy = ratio * force * (y - hearty) + random.randint(-1, 1)
    return x - dx, y - dy

This method calculates the offset for each point during animation. The offset considers distance, ratio, and randomness, making the effect more natural.


3.4 calc Method

def calc(self, generate_frame):
    ratio = 10 * curve(generate_frame / 10 * pi)
    halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
    halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))
    all_points = []
    heart_halo_point = set()
    for _ in range(halo_number):
        t = random.uniform(0, 2 * pi)
        x, y = heart_function(t, shrink_ratio=11.6)
        x, y = shrink(x, y, halo_radius)
        if (x, y) not in heart_halo_point:
            heart_halo_point.add((x, y))
            x += random.randint(-14, 14)
            y += random.randint(-14, 14)
            size = random.choice((1, 2, 2))
            all_points.append((x, y, size))

This method calculates changes for each frame and updates the heart points and halo effects.


3.5 render Method

def render(self, render_canvas, render_frame):
    for x, y, size in self.all_points[render_frame % self.generate_frame]:
        render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=heartcolor)

Renders all points of the current frame on the canvas using rectangles.


4. Helper Functions

4.1 heart_function

def heart_function(t, shrink_ratio: float = side):
    x = 16 * (sin(t) ** 3)
    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
    x *= shrink_ratio
    y *= shrink_ratio
    x += heartx
    y += hearty
    return int(x), int(y)

This function calculates the coordinates of the heart shape based on the parameter t. It uses a mathematical formula to generate the heart shape points.
shrink_ratio controls the size of the heart.

4.2 scatter_inside

def scatter_inside(x, y, beta=0.15):
    ratio_x = - beta * log(random.random())
    ratio_y = - beta * log(random.random())
    dx = ratio_x * (x - heartx)
    dy = ratio_y * (y - hearty)
    return x - dx, y - dy

This function simulates the scattering effect of points, controlling the distribution of points inside the heart.

4.3 shrink

def shrink(x, y, ratio):
    force = -1 / (((x - heartx) ** 2 + (y - hearty) ** 2) ** 0.6)
    dx = ratio * force * (x - heartx)
    dy = ratio * force * (y - hearty)
    return x - dx, y - dy

This function adjusts the position of the points by calculating a scaling factor, making them expand or contract relative to the center of the heart.

4.4 curve

def curve(p):
    return 2 * (2 * sin(4 * p)) / (2 * pi)

This function generates a smooth periodic change to control the movement of points in the animation.


5. Main Program and Display

def love():
    root = tk.Tk()
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    x = (screenwidth - width) // 2
    y = (screenheight - height) // 2 - 66
    root.geometry("%dx%d+%d+%d" % (width, height, x, y))
    root.title("❤")
    canvas = tk.Canvas(root, bg='black', height=height, width=width)
    canvas.pack()
    heart = Heart()
    draw(root, canvas, heart)
    tk.Label(root, text=word, bg="black", fg="skyblue", font="Helvetic 25 bold").place(relx=.5, rely=.5, anchor=CENTER)
    root.mainloop()
  • Creates the main window and sets its size and title.

  • Initializes a canvas and uses the Heart class to generate the heart effect.

  • Uses the draw function to refresh the canvas at intervals and render new frames.

  • Displays the text "I Love You!" at the center of the window.


6. Summary
This code creates a dynamic heart animation using tkinter and mathematical functions, showcasing glowing and scattering effects. The heart looks vivid and romantic thanks to these visual effects. By controlling animation frames, the shape and trajectory of the heart keep changing, producing a smooth and continuous dynamic effect. This is not just a simple GUI program but also integrates concepts from mathematics and physical simulation.