SnIPPETsX › WIDTH = 800
WIDTH = 800
Python · updated Oct 14, 2026 · 353 lines
main.js
import tkinter as tk
import random
import math
WIDTH = 800
HEIGHT = 500
root = tk.Tk()
root.title("✨")
root.geometry(f"{WIDTH}x{HEIGHT}")
root.resizable(False, False)
root.configure(bg="black")
canvas = tk.Canvas(
root,
width=WIDTH,
height=HEIGHT,
bg="black",
highlightthickness=0
)
canvas.pack()
WHITE = "#ffffff"
RED = "#d71920"
BLACK = "#050505"
GRAY = "#777777"
particles = []
for _ in range(70):
x = random.randint(0, WIDTH)
y = random.randint(0, HEIGHT)
size = random.choice([1, 1, 2])
particle = canvas.create_rectangle(
x, y,
x + size,
y + size,
fill=random.choice([WHITE, GRAY, "#777777"]),
outline=""
)
particles.append({
"id": particle,
"x": x,
"y": y,
"speed": random.uniform(0.2, 0.7)
})
mask = canvas.create_oval(
0, 0, 0, 0,
fill=RED,
outline=BLACK,
width=4
)
web_lines = []
web_lines.append(
canvas.create_line(
0, 0, 0, 0,
fill=BLACK,
width=1
)
)
for _ in range(6):
web_lines.append(
canvas.create_line(
0, 0, 0, 0,
fill=BLACK,
width=1
)
)
horizontal_webs = []
for _ in range(4):
horizontal_webs.append(
canvas.create_line(
0, 0, 0, 0,
fill=BLACK,
width=1
)
)
left_eye = canvas.create_polygon(
0, 0, 0, 0,
fill=WHITE,
outline=BLACK,
width=3
)
right_eye = canvas.create_polygon(
0, 0, 0, 0,
fill=WHITE,
outline=BLACK,
width=3
)
thread = canvas.create_line(
400,
0,
400,
100,
fill=WHITE,
width=1
)
def rotate_point(x, y, angle):
cos_a = math.cos(angle)
sin_a = math.sin(angle)
return (
x * cos_a - y * sin_a,
x * sin_a + y * cos_a
)
angle = 0
direction = 1
def animate_mask():
global angle, direction
angle += 0.018 * direction
if angle > 0.30:
direction = -1
if angle < -0.30:
direction = 1
pivot_x = 400
pivot_y = 30
rope_length = 125
mask_x = pivot_x + math.sin(angle) * rope_length
mask_y = pivot_y + math.cos(angle) * rope_length
canvas.coords(
thread,
pivot_x,
pivot_y,
mask_x,
mask_y - 58
)
canvas.coords(
mask,
mask_x - 45,
mask_y - 60,
mask_x + 45,
mask_y + 60
)
p1 = rotate_point(0, -58, angle)
p2 = rotate_point(0, 58, angle)
canvas.coords(
web_lines[0],
mask_x + p1[0],
mask_y + p1[1],
mask_x + p2[0],
mask_y + p2[1]
)
radial_angles = [
-65,
-40,
-20,
20,
40,
65
]
for i, degrees in enumerate(radial_angles):
rad = math.radians(degrees)
x1 = math.sin(rad) * 5
y1 = -math.cos(rad) * 5
x2 = math.sin(rad) * 43
y2 = -math.cos(rad) * 62
p1 = rotate_point(x1, y1, angle)
p2 = rotate_point(x2, y2, angle)
canvas.coords(
web_lines[i + 1],
mask_x + p1[0],
mask_y + p1[1],
mask_x + p2[0],
mask_y + p2[1]
)
web_y_positions = [
-38,
-15,
12,
38
]
for i, y in enumerate(web_y_positions):
width = 30 + (abs(y) * 0.20)
p1 = rotate_point(-width, y, angle)
p2 = rotate_point(width, y, angle)
canvas.coords(
horizontal_webs[i],
mask_x + p1[0],
mask_y + p1[1],
mask_x + p2[0],
mask_y + p2[1]
)
left_eye_points = [
(-37, -20),
(-12, -39),
(-17, -4),
(-35, 12)
]
right_eye_points = [
(37, -20),
(12, -39),
(17, -4),
(35, 12)
]
def transform_polygon(points):
result = []
for x, y in points:
rx, ry = rotate_point(x, y, angle)
result.extend([
mask_x + rx,
mask_y + ry
])
return result
canvas.coords(
left_eye,
*transform_polygon(left_eye_points)
)
canvas.coords(
right_eye,
*transform_polygon(right_eye_points)
)
root.after(30, animate_mask)
title = canvas.create_text(
400,
285,
text="",
fill=WHITE,
font=("Courier New", 34, "bold")
)
NAME = "! PRERNA !"
name_text = canvas.create_text(
400,
335,
text="",
fill="#00ff66",
font=("Courier New", 18, "bold")
)
message = "HAPPY BIRTHDAY!"
index = 0
def type_message():
global index
if index <= len(message):
canvas.itemconfig(
title,
text=message[:index]
)
index += 1
root.after(130, type_message)
else:
# Wait a tiny bit before showing the name
root.after(500, show_name)
def show_name():
canvas.itemconfig(
name_text,
text=NAME
)
pulse()
pulse_direction = 1
pulse_size = 34
def pulse():
global pulse_direction, pulse_size
pulse_size += pulse_direction * 0.4
if pulse_size >= 38:
pulse_direction = -1
if pulse_size <= 34:
pulse_direction = 1
canvas.itemconfig(
title,
font=("Courier New", int(pulse_size), "bold")
)
root.after(40, pulse)
def animate_particles():
for p in particles:
p["y"] -= p["speed"]
if p["y"] < 0:
p["y"] = HEIGHT
p["x"] = random.randint(0, WIDTH)
size = random.choice([1, 1, 2])
canvas.coords(
p["id"],
p["x"],
p["y"],
p["x"] + size,
p["y"] + size
)
root.after(30, animate_particles)
animate_particles()
animate_mask()
root.after(1200, type_message)
root.mainloop()
Run this Python snippet
Open this snippet on SnIPPETsX to run the Python code in your browser, edit it together with others in real time, or fork it into your own copy. No install or account is needed.