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.
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
andheight
: Define the width and height of the canvas.heartx
andhearty
: 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 randomt
values to calculate the heart shape points using theheart_function
.Diffusion Effects: Adds more points to
self._edge_diffusion_points
andself._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.