用 Python 制作一份会"动"的录取通知书
◆ ◆ ◆
一、为什么想做这个?
又到一年高考录取季,无数学子翘首以盼那张承载十二年寒窗的录取通知书。今年的新规要求纸质通知书更加简洁环保,许多高校纷纷"瘦身"——少了烫金浮雕,少了立体折页,仪式感似乎也跟着打折。但仪式感这件事,从来不该被纸张的厚薄定义。
于是萌生了一个想法:既然纸质要简洁,那不如用代码给这份仪式感"加戏"。用 Python 做一份会动的电子录取通知书——学生自己输入姓名、专业、学校,点击确认后,一封从星空深处飞来的信封缓缓落下,封蜡金光爆裂,通知书逐行展开,最后金色印章落下、彩带烟花齐鸣。这,才是属于数字时代的仪式感。
这篇文章会完整分享这个项目的实现思路:从输入界面设计、动画时间轴编排,到粒子系统、缓动函数、信封绘制等核心技术点。文末附完整源码,复制即可运行。无论你是想给身边的高考生一份惊喜,还是想学习python中的 pygame 动画,都能从中有所收获。
二、效果先睹为快
程序运行后,首先弹出一个深色风格的输入窗口,三个输入框分别填写姓名、专业、学校,配色采用深蓝底 + 金色描边 + 红色确认按钮,呼应录取通知书的红金主色调。

图 1输入界面:深蓝底色 + 金色描边 + 红色确认按钮
点击"确认"后,进入 pygame 动画展示页面。整个动画被精心编排为10多个连续阶段,从星空背景浮现到烟花持续绽放,总时长约 18 秒,每一帧都经过缓动函数处理,确保过渡丝滑自然。

图 2动画 多个个关键阶段预览(4×3 网格)
可以看到,动画的视觉层次非常丰富:前期以深紫蓝星空为底,信封红色醒目;中期通知书米白信纸展开,金色标题与深棕正文形成对比;后期金色印章与多彩烟花/彩带将气氛推向高潮。下面我们逐一拆解技术实现。
三、技术方案选型
这个项目只需要两个 Python 库,都是零门槛的"老朋友":
**tkinter** —— Python 标准库自带,无需额外安装。用于制作输入界面,跨平台兼容性极好,Windows / macOS / Linux 开箱即用。虽然界面朴素,但通过配色和字体调整,依然能做出不错的效果。
**pygame** —— Python 经典的 2D 游戏开发库,`pip install pygame` 即可。它擅长处理实时渲染、粒子系统、动画帧率控制,是实现复杂动画效果的最佳选择。相比 matplotlib 的动画,pygame 性能更好、自由度更高。
🚀 快速开始安装命令只需一行:pip install pygame。tkinter 是 Python 自带的,无需安装。建议使用 Python 3.8 以上版本。 |
四、核心实现解析
4.1动画时间轴:10余段精心编排
整个动画采用"时间轴驱动"的设计思路。记录每个阶段的起始时间和持续时长,主循环中根据当前时间 t 计算各阶段的进度,再驱动对应的绘制函数。这种设计的好处是:**动画节奏可调、阶段可增减、逻辑清晰不混乱**。
# 时间轴:每个阶段 (起始时间, 持续时长) timeline = { "bg_fade":(0.0,1.5),#背景渐显 "envelope":(1.5,2.0),#信封飞入 "hover":(3.5,0.8),#悬停定影 "seal_glow":(4.3,0.7),#封蜡发光 "seal_burst":(5.0,0.5),#封蜡爆裂 "flap_open":(5.5,0.8),#翻盖开启 "letter_out":(6.3,1.2),#通知书滑出 "letter_unfold":(7.5,1.0),#通知书展开 "title_show":(8.5,1.5),#标题浮现 "body_show":(10.0,2.0),#正文逐行 "seal_drop":(12.0,0.8),#印章落下 "celebrate":(12.8,999),#庆祝(持续) } |
每个阶段的进度通过一个 pts(name) 方法计算,返回 0~1 的归一化值,再喂给缓动函数实现自然过渡。例如信封飞入阶段,进度从 0 到 1,配合 ease_out_cubic 缓动,信封会"先快后慢"地落到位,比匀速运动自然得多。
4.2缓动函数:让动画"活"起来
匀速动画看起来像机器人,而真实世界的运动都有"惯性"——起步慢、加速、减速、停止。缓动函数就是模拟这种物理特性的数学工具。程序内置了 5 种常用缓动函数,分别适用于不同场景:
def ease_out_cubic(t):# 先快后慢,适合"落下"动作 return1 - (1 - t) ** 3 def ease_in_out_cubic(t):# 两端慢中间快,适合"展开" return4*t**3 if t < 0.5 else 1 - (-2*t+2)**3/2 def ease_out_back(t, s=1.7): # 带回弹,适合"印章落下" return1 + (s+1)*(t-1)**3 + s*(t-1)**2 def ease_out_bounce(t):# 弹跳,适合"落地"效果 ift < 1/2.75:return 7.5625*t*t elift < 2/2.75: t -= 1.5/2.75; return 7.5625*t*t + 0.75 elift < 2.5/2.75: t -= 2.25/2.75; return 7.5625*t*t + 0.9375 else:t -= 2.625/2.75; return 7.5625*t*t + 0.984375 def ease_out_elastic(t):# 弹性,适合"印章定影" ift == 0 or t == 1: return t return 2**(-10*t) * math.sin((t-0.075)*(2*math.pi/0.3)) + 1 …… |
其中 ease_out_back 带有轻微"过冲"效果,让印章落下时有一个小小的回弹,模拟真实印章"啪"地盖下去的质感;ease_out_bounce 则模拟球体落地的多次弹跳,用在封蜡爆裂的碎片上非常生动。这些函数虽然数学公式看着复杂,但都是业界验证过的经典曲线,直接套用即可。
4.3粒子系统:烟花、彩带、金光
粒子系统是整个动画"高级感"的核心。程序实现了一个统一的 ParticleSystem 类,支持三种发射模式:burst(径向爆裂,用于封蜡炸开)、confetti(彩带,用于庆祝)、sparkle(闪烁星点,用于装饰光效)。每个粒子有位置、速度、加速度、颜色、大小、生命值等属性,每帧更新物理状态并绘制。
class Particle: def__init__(self, x, y, vx, vy, color, size, life, gravity=200, shape='circle',spin=0): self.x,self.y = x, y self.vx,self.vy = vx, vy self.color= color self.size= size self.life= life self.max_life= life self.gravity= gravity self.shape= shape# circle / rect / star self.spin= spin self.angle= 0 defupdate(self, dt): self.vy+= self.gravity * dt# 重力 self.x+= self.vx * dt self.y+= self.vy * dt self.angle+= self.spin * dt self.life-= dt @property defalive(self): returnself.life > 0 defdraw(self, surf): alpha= max(0, min(255, int(255 * self.life / self.max_life))) #... 根据 shape 绘制不同形状的粒子 |
烟花则是一个独立类,先有一个"上升"阶段(带尾迹粒子),到达目标高度后"爆炸",向四周发射 30~50 个彩色粒子。庆祝阶段会持续随机生成烟花,配合两侧不断喷出的彩带,营造出满屏欢庆的氛围。
4.4信封绘制:旋转 + 翻盖 + 封蜡
信封是动画前半段的主角。绘制时先在一个临时 Surface 上画好信封主体(红色渐变 + 金色边框 + 校徽装饰),再通过 pygame.transform.rotate 旋转到当前角度,实现"飞入时旋转"的效果。翻盖则是一个三角形,通过旋转角度从 0° 到 180° 模拟翻开动作。
def draw_envelope(surf, x, y, w, h, flap_angle=0.0, seal_glow=0.0): # 1. 信封主体:红色渐变 + 金色边框 body = pygame.Surface((w, h), pygame.SRCALPHA) # 绘制渐变背景、边框、装饰花纹... # 2. 翻盖:三角形,按 flap_angle 旋转 ifflap_angle > 0: flap= pygame.Surface((w, h//2), pygame.SRCALPHA) #绘制三角形翻盖... rotated= pygame.transform.rotate(flap, -flap_angle * 180) # blit 到信封顶部 #3. 封蜡:红色圆 + 金光晕 if seal_glow > 0: glow= make_radial_gradient(60, 60, (255,220,120,int(180*seal_glow)), (255,220,120,0)) surf.blit(glow,(cx-30, cy-30), special_flags=BLEND_ADD) #4. 整体旋转后 blit 到主屏幕 ifrotation != 0: body= pygame.transform.rotate(body, rotation) surf.blit(body, body.get_rect(center=(x, y))) …… |
4.5通知书内容:逐行浮现 + 金色印章
通知书展开后,内容按"标题 → 称呼 → 正文 → 落款 → 印章"的顺序逐行浮现。每行文字的透明度从 0 渐变到 255,配合轻微的上移位移,形成"从虚到实"的浮现效果。正文部分动态嵌入用户输入的姓名、专业、学校,让每份通知书都是独一无二的。
def draw_seal_stamp(surf, x, y, scale=1.0, alpha=255, rotation=0): size= int(90 * scale) seal= pygame.Surface((size*2, size*2), pygame.SRCALPHA) #外圈:红色圆环 pygame.draw.circle(seal,(165,30,35,alpha), (size,size), size-4, 5) #内圈:红色实心圆(半透明) pygame.draw.circle(seal,(165,30,35,alpha//2), (size,size), size-12) # 中央文字:"录取专用章" font = pygame.font.Font(FONT_SERIF_BOLD, int(20*scale)) txt= font.render("录取专用章", True, (165,30,35,alpha)) seal.blit(txt,txt.get_rect(center=(size,size))) #旋转并 blit ifrotation: seal= pygame.transform.rotate(seal, rotation) surf.blit(seal,seal.get_rect(center=(x,y))) |
五、如何运行
运行非常简单,三步即可:
# 第一步:安装 pygame(tkinter 是 Python 自带的) pip install pygame # 第二步:保存源码为 admission_notice.py # (文末附完整源码,复制粘贴即可) # 第三步:运行admission_notice.py文件 |
运行后会弹出输入窗口,填写信息点击确认即可看到动画。动画过程中可以按空格键跳过到庆祝阶段,按 ESC 键退出。
六、更多玩法与扩展
这份代码是一个良好的起点,你可以在此基础上做很多扩展:
1. 个性化定制:修改配色方案中的颜色常量,换成你心仪的学校主色调;在通知书正文中加入校训、院系寄语等个性化内容。
2. 增加音效:用 pygame.mixer 加载背景音乐和音效(封蜡爆裂声、印章盖落声、烟花绽放声),让动画"声画并茂"。
3. 导出视频:在主循环中每帧调用 pygame.image.save 保存截图,再用 ffmpeg 合成 MP4,就能导出动画视频分享到社交平台。
4. 网页版:将 pygame 逻辑移植到 HTML5 Canvas + JavaScript,或用 Pyodide 在浏览器直接运行 Python,做成一个在线生成器,让更多人能用。
5. 批量生成:读取 Excel 名单,批量生成每位学生的专属动画通知书。
七、写在最后
如果你也觉得这个项目有趣,欢迎动手试试,给身边的高考生一份特别的惊喜。也欢迎在评论区分享你的改进版本——期待看到更多创意!
祝所有考生:金榜题名,前程似锦!
◆END◆
(完整源码见通过网盘分享的文件:2026-0723-录取通知书动画
链接: https://pan.baidu.com/s/1FTThhjgyOKcAlURkT7i0XQ?pwd=x2pa 提取码: x2pa)