import tkinter as tk
import random
import math
import sys

# ============ 默认名字(可自行修改或命令行传参)============
NAME = "宝贝"
# =========================================================

WIN_WIDTH = 80
WIN_HEIGHT = 60
NUM_WINDOWS = 50          # 小窗口数量
MOVE_STEPS = 30           # 动画帧数
MOVE_DELAY = 20           # 每帧间隔(ms)

# ============ 情话库(可以随意增删)============
LOVE_WORDS = [
    "你是我的光",
    "余生请多指教",
    "遇见你真好",
    "眼里只有你",
    "想和你虚度时光",
    "今晚月色真美",
    "你是我最温柔的梦",
    "三餐四季有你",
    "星河滚烫,你是人间理想",
    "爱你三千遍",
    "人间值得,未来可期",
    "你是我的半截的诗",
    "山水一程,三生有幸",
    "愿得一心人",
    "白首不相离",
    "初见乍欢,久处仍怦然",
    "此生固短,无你何欢",
    "你笑起来真像好天气",
    "承蒙你出现,够我喜欢好多年",
    "见山是山,见你是全世界",
    "你是我的文艺复兴",
    "为你,千千万万遍",
    "入目无别人,四下皆是你",
    "山野万里,你是我藏在微风里的欢喜",
    "晓看天色暮看云,行也思君,坐也思君",
    "我的世界很小,装你一个刚好",
    "既见君子,云胡不喜",
    "不思进取,思你",
    "我见众生皆草木,唯你是青山",
    "世界很暗,然后你来了"
]
# ==============================================

def heart_curve(t):
    """心形曲线参数方程,t∈[0, 2π]"""
    x = 16 * math.sin(t) ** 3
    y = 13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t)
    return x, -y                 # 屏幕坐标系y轴向下,取反

def generate_heart_points(n, scale, center_x, center_y):
    """生成n个均匀分布在心形曲线上的坐标点"""
    points = []
    for i in range(n):
        t = 2 * math.pi * i / n
        x, y = heart_curve(t)
        px = center_x + x * scale
        py = center_y + y * scale
        points.append((px, py))
    return points

def random_color():
    """随机生成鲜艳颜色"""
    return "#{:02x}{:02x}{:02x}".format(
        random.randint(100, 255),
        random.randint(50, 200),
        random.randint(100, 200)
    )

def main():
    # 读取命令行名字(如果有的话)
    global NAME
    if len(sys.argv) > 1:
        NAME = sys.argv[1]

    # 主窗口
    root = tk.Tk()
    root.title("520 ❤")
    root.geometry("300x100+100+100")
    label = tk.Label(root, text=f"送给 {NAME} ❤", font=("微软雅黑", 16))
    label.pack(expand=True)

    # 屏幕尺寸,爱心居中
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    center_x = screen_width // 2
    center_y = screen_height // 2
    scale = 15                     # 爱心大小

    # 1. 生成爱心位置(终点)
    heart_points = generate_heart_points(NUM_WINDOWS, scale, center_x, center_y)

    # 2. 生成随机起始位置(屏幕内不越界)
    start_positions = []
    for _ in range(NUM_WINDOWS):
        sx = random.randint(0, screen_width - WIN_WIDTH)
        sy = random.randint(0, screen_height - WIN_HEIGHT)
        start_positions.append((sx, sy))

    # 3. 创建所有无边框彩色小窗口(初始位置随机)
    windows = []
    for i, (sx, sy) in enumerate(start_positions):
        color = random_color()
        win = tk.Toplevel(root)
        win.overrideredirect(True)              # 无边框
        win.configure(bg=color)
        win.geometry(f"{WIN_WIDTH}x{WIN_HEIGHT}+{int(sx)}+{int(sy)}")

        # 随机选一句情话
        love_word = random.choice(LOVE_WORDS)
        lbl = tk.Label(win, text=love_word,
                       bg=color, fg="white",
                       font=("微软雅黑", 8, "bold"),
                       wraplength=WIN_WIDTH-4)   # 自动换行
        lbl.pack(expand=True)

        win.lift()
        windows.append({
            'win': win,
            'current_x': sx, 'current_y': sy,
            'target_x': heart_points[i][0],
            'target_y': heart_points[i][1],
            'step': 0
        })

    # 4. 动画:从随机位置向爱心位置移动
    def animate():
        all_done = True
        for w in windows:
            if w['step'] < MOVE_STEPS:
                all_done = False
                progress = (w['step'] + 1) / MOVE_STEPS
                # smoothstep 缓动
                eased = progress * progress * (3 - 2 * progress)
                new_x = w['current_x'] + (w['target_x'] - w['current_x']) * eased
                new_y = w['current_y'] + (w['target_y'] - w['current_y']) * eased
                w['win'].geometry(
                    f"{WIN_WIDTH}x{WIN_HEIGHT}+{int(new_x)}+{int(new_y)}")
                w['step'] += 1

        if not all_done:
            root.after(MOVE_DELAY, animate)

    # 立刻启动动画,无需延迟
    root.after(500, animate)

    # 5. 关闭主窗口时销毁所有小窗口
    def on_closing():
        for w in windows:
            w['win'].destroy()
        root.destroy()
    root.protocol("WM_DELETE_WINDOW", on_closing)

    root.mainloop()

if __name__ == "__main__":
    main()

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐