Python带娃编程系列实践-第1期:明星呼吸灯墙——让女儿和她的偶像“同框”
专栏名称:Python带娃编程系列实践
专栏作者:制造数据与AI践行者老蒋(javy21)
作者CSDN:制造数据与AI践行者老蒋-CSDN博客
📌 写在前面
我家女儿今年初三,粉上了白鹿、范丞丞这些明星,房间里一面墙壁改造后,贴满了他们的海报。有一天她盯着墙上的海报问我:“爸,能让这些照片动起来吗?就像活过来一样。”
我想了想说:能。而且用Python,不超过100行代码就能做到。想学吗?
于是就有了这篇教程。明星呼吸灯墙,让静态的明星照片像呼吸一样有节奏地放大缩小,配上柔和的光晕,摆在电脑屏幕上特别酷。
效果图如下:

全程不到50行核心代码,女儿从零开始跟着做,半小时就跑通了。关键是——她全程没觉得是在“上课”,而是在“做自己的作品” 。
如果你家里也有一个追星的孩子,或者你想让孩子觉得“编程挺好玩的”,这篇就是为你准备的。
🎯 本文适合:零基础Python新手(尤其初中或者高中生),以及想带娃入门的家长。
⏱️ 预计耗时:环境搭建10分钟 + 写代码20分钟 = 半小时跑通。
💻 技术栈:Python + Flask(一个极简的Web框架)+ HTML + CSS。
🤔 为什么要做这个?
很多家长问:孩子学编程,从哪开始?
我的答案是——从“能看到效果”的东西开始。
学编程最大的误区,就是让孩子对着黑乎乎的控制台敲print("Hello World")。孩子看不到图形、看不到动画、看不到任何“像软件”的东西,很快就觉得无聊了。
但如果你让她在浏览器里打开一个页面,上面是她喜欢的明星照片,每张照片都在像呼吸一样律动——她会觉得“这是我做出来的?”然后追着你问“下一个做什么”。
这就是兴趣的起点。
而且这个案例里藏着几个编程的核心概念:
-
列表(List) —— 管理一堆明星照片
-
循环(for循环) —— 批量处理每一张照片
-
函数(Function) —— 把重复的逻辑打包起来
-
前后端交互 —— Python在后端处理数据,网页在前端展示效果
孩子不需要理解这些术语,她只需要知道“我改了这段代码,页面就变了”——这种“因果感” 才是编程思维的核心。
🛠️ 需要准备什么?
硬件方面:一台能联网的电脑(Windows/Mac都可以)。
软件方面(跟着做,10分钟搞定):
| 工具 | 作用 | 怎么装 |
|---|---|---|
| Python 3.8+ | 运行代码 | 官网 python.org 下载安装 |
| PyCharm(或VSCode) | 写代码的编辑器 | 社区版免费,官网下载 |
| Flask | Python的Web框架 | 终端执行 pip install flask |
💡 给家长的建议:如果孩子第一次接触编程,建议你帮她把环境装好,让她专注于“写代码”和“看效果”这两个最有成就感的环节。
📁 项目结构(先看一眼,心里有数)
javy21_DadKidsCoding/
├── app.py # 主程序(核心代码就这一个文件)
├── requirements.txt # 依赖清单(就一行:flask)
├── templates/
│ └── week01_breath.html # 页面模板
└── static/
├── css/
│ └── style.css # 样式(呼吸动画的核心在这里)
└── images/
└── stars/ # ⭐ 放明星照片的文件夹(孩子自己动手放)
整个项目就4个核心文件,加起来不到200行代码。其中真正需要孩子动手写的——几乎只有最后一步:把照片放进文件夹。
💻 动手做:一步一步来
第1步:创建项目文件夹
在电脑的 D:/SRC/wee_projects/ 下新建一个文件夹,叫 javy21_DadKidsCoding(名字可以自己改,但建议用英文)。
第2步:安装Flask
打开终端(Windows是CMD或PowerShell,Mac是终端),输入:
pip install flask
看到“Successfully installed flask”就成功了。
第3步:创建 requirements.txt
在项目文件夹里新建一个文本文件,命名为 requirements.txt,写入:
# ============================================================
# 作者 : 制造数据与AI践行者老蒋(javy21)
# CSDN博客 : https://blog.csdn.net/javy21
# 核心内容 : 项目Python依赖包清单
# 安装命令 : pip install -r requirements.txt
# ============================================================
Flask==3.0.0
requests==2.31.0
这个文件的作用是——以后换电脑时,执行 pip install -r requirements.txt 就能一键安装所有依赖。
第4步:创建 app.py(核心程序)
在项目文件夹里新建 app.py,复制下面的代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
=============================================================
# 作者 (Author) : 制造数据与AI践行者老蒋(javy21)
# CSDN博客地址 : https://blog.csdn.net/javy21
# 文件名称 (Filename): app.py
# 核心内容 (Core) : Flask 主入口,负责路由分发与数据渲染
# 设计思路 (Logic) :
# 1. 初始化 Flask 应用
# 2. 扫描 static/images/stars/ 目录获取所有明星图片
# 3. 为每张图片生成随机旋转角度和错峰延迟时间
# 4. 渲染 HTML 模板,传递明星数据
# 适用周次 (Week) : W01
=============================================================
"""
from flask import Flask, render_template
import os
import random
app = Flask(__name__)
# 明星照片存放目录
STAR_FOLDER = os.path.join(app.static_folder, 'images', 'stars')
@app.route('/')
def index():
"""
功能描述:首页 - 展示明星呼吸灯墙。
设计思路:
1. 扫描 stars 文件夹获取所有图片
2. 为每张图片生成随机倾斜角度和错峰延迟
3. 渲染页面
"""
# 扫描图片文件夹
star_images = []
if os.path.exists(STAR_FOLDER):
for f in os.listdir(STAR_FOLDER):
if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.webp')):
star_images.append(f)
star_images.sort()
# 构建每张卡片的数据
star_data = []
for idx, filename in enumerate(star_images):
display_name = os.path.splitext(filename)[0]
star_data.append({
'name': filename,
'display_name': display_name,
'rotation': random.randint(-4, 5), # 随机倾斜
'delay': round(idx * 0.25, 2) # 错峰延迟,形成波浪
})
return render_template('week01_breath.html', stars=star_data, week_num=1)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
这段代码在做什么? 简单说——它启动了一个小网站,扫描你放照片的文件夹,把每张照片的信息(文件名、旋转角度、呼吸节奏)发给网页模板去展示。
第5步:创建页面模板
在项目文件夹里新建一个 templates 文件夹,在里面新建 week01_breath.html,复制下面的代码:
{#
=============================================================
# 作者 (Author) : 制造数据与AI践行者老蒋(javy21)
# CSDN博客地址 : https://blog.csdn.net/javy21
# 文件名称 (Filename): week01_breath.html
# 核心内容 (Core) : 明星呼吸灯墙页面
# 设计思路 (Logic) :
# 1. 接收后端传来的明星数据列表
# 2. 循环生成每张明星卡片(拍立得风格)
# 3. 每张卡片独立设置旋转角度和动画延迟
# 适用周次 (Week) : W01
=============================================================
#}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>第1周 · 明星呼吸灯墙</title>
<style>
/* ===== 软木板背景 ===== */
body {
margin: 0;
min-height: 100vh;
background: #d9b382;
background-image:
radial-gradient(circle at 20% 30%, rgba(255,215,175,0.4) 0%, transparent 30%),
radial-gradient(circle at 80% 70%, rgba(160,120,80,0.2) 0%, transparent 40%),
repeating-linear-gradient(45deg, rgba(0,0,0,0.03) 0px, rgba(0,0,0,0.03) 2px, transparent 2px, transparent 8px);
padding: 30px 20px;
font-family: "Comic Sans MS", "PingFang SC", cursive;
}
/* ===== 标题 ===== */
.header {
text-align: center;
padding: 15px 0 30px 0;
}
.header h1 {
background: #fefefe;
padding: 10px 35px;
border-radius: 50px;
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
font-size: 24px;
color: #5d4037;
display: inline-block;
border: 2px dashed #c29a6b;
}
.header .badge {
background: #ff6b6b;
color: white;
padding: 6px 18px;
border-radius: 30px;
font-size: 16px;
margin-left: 15px;
}
/* ===== 拍立得卡片容器 ===== */
.polaroid {
max-width: 1200px;
margin: 0 auto;
background: #fefefe;
padding: 35px 30px 25px 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.25);
transform: rotate(0.8deg);
border-radius: 4px 4px 20px 20px;
text-align: center;
}
/* ===== 明星网格 ===== */
.star-grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 30px 40px;
padding: 20px 0;
}
/* ===== 每张明星卡片(迷你拍立得) ===== */
.star-card {
background: white;
padding: 12px 12px 8px 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
border-radius: 2px 2px 8px 8px;
transition: transform 0.3s ease;
position: relative;
width: 160px;
}
.star-card:hover {
transform: scale(1.05) !important;
z-index: 999;
}
/* ===== 图钉 ===== */
.star-card::before {
content: "📌";
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%) rotate(-30deg);
font-size: 28px;
filter: drop-shadow(0 4px 4px rgba(0,0,0,0.3));
z-index: 10;
}
/* ===== 明星图片 + 呼吸动画 ===== */
.star-img {
width: 100%;
height: 160px;
object-fit: cover;
border-radius: 6px;
display: block;
background: #eee;
animation: breathe 2.5s ease-in-out infinite;
}
/* ===== 名字 ===== */
.star-name {
margin: 8px 0 2px 0;
font-size: 16px;
font-weight: 600;
color: #4a3728;
border-top: 1px solid #f0e0d0;
padding-top: 6px;
}
/* ===== ⭐ 呼吸动画关键帧 ===== */
@keyframes breathe {
0% {
transform: scale(1);
box-shadow: 0 0 8px rgba(255, 107, 107, 0.2);
}
50% {
transform: scale(1.04);
box-shadow: 0 0 30px rgba(255, 107, 107, 0.7), 0 0 60px rgba(255, 200, 100, 0.3);
}
100% {
transform: scale(1);
box-shadow: 0 0 8px rgba(255, 107, 107, 0.2);
}
}
</style>
</head>
<body>
<div class="header">
<h1>📌 老爸带娃 · 编程奇遇记 <span class="badge">第1周</span></h1>
</div>
<div class="polaroid">
<h2 style="color:#5d4037;">✨ 明星们的呼吸灯墙 ✨</h2>
<p style="color:#8d6e63; font-size:14px;">🖱️ 鼠标放上去会放大哦 ~ 每张照片都在“呼吸”</p>
<div class="star-grid">
{% for star in stars %}
<div class="star-card" style="transform: rotate({{ star.rotation }}deg);">
<img src="{{ url_for('static', filename='images/stars/' + star.name) }}"
alt="{{ star.display_name }}"
class="star-img"
style="animation-delay: {{ star.delay }}s;">
<div class="star-name">{{ star.display_name }}</div>
</div>
{% endfor %}
</div>
<div style="margin-top: 30px; font-size: 13px; color: #a1887f; border-top: 1px dashed #d7ccc8; padding-top: 15px;">
💡 老爸提示:每张照片呼吸的节奏不一样,像波浪一样扫过~
</div>
</div>
</body>
</html>
第6步:创建样式文件(可选,但推荐)
在项目文件夹里新建 static/css/style.css,把上面HTML里 <style> 标签中的内容剪切进去,然后在HTML头部改成引用外部样式。这样代码会更整洁。
不过对于初学者来说,直接把样式写在HTML里更直观——所有东西都在一个文件里,改起来方便。
第7步:⭐ 放照片(孩子最喜欢的环节)
在项目文件夹里新建 static/images/stars/ 文件夹。
让女儿自己去百度搜索她喜欢的明星照片(白鹿、范丞丞、赵露思……),下载后放进这个文件夹。
📌 小技巧:照片文件名最好用拼音或英文(如
bailu.jpg、fanchengcheng.jpg),避免中文文件名在有些浏览器里显示乱码。照片尺寸建议接近正方形(比如300x300),显示效果最好。
第8步:运行!
在终端里进入项目文件夹,执行:
python app.py
然后打开浏览器,访问 http://127.0.0.1:5000
你会看到:软木板的背景上,一张张“拍立得”照片整齐排列,每张照片都在有节奏地“呼吸”——放大、发光、缩小,循环往复。而且每张照片的呼吸节奏不一样,像波浪一样从左到右扫过去。
鼠标放上去:照片会放大并暂停呼吸,方便仔细看。
🧠 核心原理:用大白话讲给孩子听
这部分是给孩子看的,家长可以念给娃听。
问:照片为什么会“呼吸”?
答:我们给每张照片加了一个“闹钟”(CSS动画),每隔2.5秒响一次。每次闹钟响的时候,照片就做三件事:
-
放大一点点(从1倍变成1.04倍)
-
亮起来(加一圈粉色的光晕)
-
再缩回去
一放大一缩小,看起来就像人在呼吸。
问:为什么每张照片呼吸的节奏不一样?
答:因为每张照片的“闹钟”启动时间不一样。第一张0秒启动,第二张0.25秒后启动,第三张0.5秒后启动……这样就形成了波浪效果。
问:代码里哪句是控制这个的?
答:style="animation-delay: {{ star.delay }}s;" —— 这句就是给每张照片设置不同的启动延迟。
📝 让孩子动手改一改(锻炼编程思维)
运行成功后,让孩子试试改这几个地方,看看会发生什么:
| 改什么 | 在哪改 | 改成什么 | 效果会怎样 |
|---|---|---|---|
| 呼吸速度 | @keyframes breathe 中的 2.5s |
改成 1s |
呼吸变快,像急促喘气 |
| 呼吸幅度 | 50% 中的 scale(1.04) |
改成 scale(1.2) |
照片放大更多,像要跳出来 |
| 光晕颜色 | box-shadow 中的 rgba(255,107,107,...) |
改成 rgba(100,200,255,...) |
粉色光晕变成蓝色 |
这就是编程思维——不是背代码,而是改了某个参数,观察发生了什么变化,然后理解“为什么”。
🎯 本篇学到了什么?
| 知识点 | 通俗解释 |
|---|---|
| 列表(List) | 把一堆明星照片放在一起管理 |
| for循环 | 对每张照片做同样的事情(加图钉、加动画) |
| CSS动画(@keyframes) | 告诉浏览器“每隔几秒做一次放大缩小” |
| 前后端配合 | Python负责“找照片”,HTML负责“显示照片” |
| 参数化思维 | 改一个数字就能改变整个效果 |
📢 下期预告
第2周我们要做的是——《王者荣耀经济曲线》。
女儿打游戏的时候,我们让她记录一局游戏里不同时间点的金币数量,然后用Python画出一条“经济走势图”。
为什么做这个? 因为孩子对游戏感兴趣,而“数据可视化”是编程里非常实用的一项技能。把游戏数据变成图表,她会觉得“编程还能干这个?”
敬请期待!
💬 想听听你的反馈
这篇教程是【Python带娃编程系列实践】的第1期。我计划每周更新一篇,持续一年,带着女儿从零开始一步步走进编程的世界。
如果你带着孩子跟着做了,欢迎在评论区告诉我:
-
孩子看到呼吸灯墙时的反应是什么?
-
她最喜欢哪个明星的照片?
-
有没有遇到什么问题?
你的反馈会帮助我把后面的教程写得更好。如果有特别想做的主题(小游戏、小工具、数据图表……),也可以在评论区告诉我,我会考虑加到后面的计划里。
📌 源码地址:还在整理中,会在评论区留言说明的。
📌 专栏目录:【Python带娃编程系列实践】——每周一篇,从零到一。
📌 关于作者:制造数据与AI践行者老蒋(javy21),20多年软件行业老兵,CSDN博客专家。用代码陪伴女儿成长。
下一篇见!🚀
更多推荐



所有评论(0)