从零开始“渐进式开发”构建Flask小工具——我的平面地图编辑器开发记录
渐进式开发流程:从零开始逐步构建平面地图编辑器。采用 模块化开发思路,每一步只添加一个小功能。以下是详细步骤:
第一步:初始化项目结构
1. 创建基础目录
F:\deepseek\xiaoshuo\
├── app.py # 主程序入口
└── static/ # 静态资源
└── css/
└── style.css
└── templates/ # HTML模板
└── index.html
2. 编写最简 Flask 应用
文件: app.py
from flask import Flask, render_template
# 导入Flask模块:用于创建Web应用框架。
# 导入render_template函数:用于渲染HTML模板,将动态数据传递给静态文件。
app = Flask(__name__)
#创建Flask应用实例:__name__表示当前模块的名称,用于Flask调试模式标识。
#作用:作为整个Web应用的核心对象,管理路由、请求等。
@app.route('/')
def home():
return render_template('index.html')
# 定义根路径路由:当用户访问网站主页时,触发此函数。
# 返回渲染后的模板:render_template加载指定的HTML文件,并将其返回给浏览器。
# 作用:为用户提供一个访问入口,展示绘制界面。
if __name__ == '__main__':
app.run(debug=True)
文件: templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>简单地图编辑器</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>欢迎使用地图编辑器</h1>
</body>
</html>
运行测试:
python app.py
访问 http://127.0.0.1:5000
确认页面显示正常。
第二步:添加画布基础功能
1. 更新 HTML 添加画布
文件: templates/index.html
<body>
<div class="canvas-container">
<canvas id="main-canvas" width="800" height="600"></canvas>
</div>
</body>
- Canvas元素:创建一个800x600像素的画布,作为绘图区域。
2. 添加基础 CSS
文件: static/css/style.css
.canvas-container {
margin: 20px;
border: 2px solid #ddd;
}
#main-canvas {
background: #f8f8f8;
}
3. 添加 JavaScript 画布交互
创建 static/js/script.js
:
class SimpleEditor {
constructor() {
this.canvas = document.getElementById('main-canvas');
this.ctx = this.canvas.getContext('2d');
this.initEventListeners();
}
initEventListeners() {
this.canvas.addEventListener('mousedown', (e) => {
const rect = this.canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.drawDot(x, y);
});
}
drawDot(x, y) {
this.ctx.fillStyle = '#ff0000';
this.ctx.beginPath();
this.ctx.arc(x, y, 5, 0, Math.PI * 2);
this.ctx.fill();
}
}
const editor = new SimpleEditor();
- 定义SimpleEditor类:封装了Canvas绘图功能,便于管理和扩展。
- 构造函数参数canvas:传入Canvas元素实例。
- 获取Canvas上下文ctx:通过getContext(‘2d’)方法获得绘图环境,用于执行各种绘制操作。
更新 HTML 引入 JS:
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
测试:点击画布应出现红点。
第三步:逐步添加核心功能
1. 功能1 - 绘制线条
更新 script.js
:
class SimpleEditor {
constructor() {
this.isDrawing = false;
this.lastX = 0;
this.lastY = 0;
// ...原有代码
}
initEventListeners() {
this.canvas.addEventListener('mousedown', (e) => this.startDrawing(e));
this.canvas.addEventListener('mousemove', (e) => this.draw(e));
this.canvas.addEventListener('mouseup', () => this.stopDrawing());
}
startDrawing(e) {
this.isDrawing = true;
const rect = this.canvas.getBoundingClientRect();
[this.lastX, this.lastY] = [e.clientX - rect.left, e.clientY - rect.top];
}
draw(e) {
if (!this.isDrawing) return;
const rect = this.canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.ctx.beginPath();
this.ctx.moveTo(this.lastX, this.lastY);
this.ctx.lineTo(x, y);
this.ctx.stroke();
[this.lastX, this.lastY] = [x, y];
}
stopDrawing() {
this.isDrawing = false;
}
}
- 绘制功能实现:startDrawing 方法
- 作用:当鼠标点击Canvas时,初始化绘制状态。
- 获取Canvas位置:getBoundingClientRect()方法返回Canvas的边界信息,包括left和top属性,表示Canvas在页面中的实际位置。
测试:按住鼠标拖动可绘制线条。
2. 功能2 - 切换画笔颜色
更新 HTML(添加颜色选择按钮):
<div class="toolbar">
<button onclick="editor.setColor('#ff0000')">红色</button>
<button onclick="editor.setColor('#00ff00')">绿色</button>
</div>
- 颜色按钮:提供两个按钮,分别设置画笔颜色为红色和绿色。点击按钮会调用JavaScript方法editor.setColor(color)。
更新 script.js
:
class SimpleEditor {
constructor() {
this.currentColor = '#ff0000';
// ...原有代码
}
setColor(color) {
this.currentColor = color;
}
draw(e) {
this.ctx.strokeStyle = this.currentColor;
// ...原有代码
}
}
测试:点击按钮切换颜色,绘制不同颜色的线条。
第四步:模块化扩展(引入蓝图)
1. 创建蓝图目录
xiaoshuo/
└── map_app/
├── __init__.py # 空文件
└── routes.py
2. 编写蓝图路由
文件: map_app/routes.py
from flask import Blueprint
map_bp = Blueprint('map', __name__)
@map_bp.route('/test')
def test():
return "蓝图路由测试成功!"
3. 主程序注册蓝图
更新 app.py
:
from flask import Flask, render_template
from map_app.routes import map_bp # 绝对导入
app = Flask(__name__)
app.register_blueprint(map_bp, url_prefix='/map')
# ...原有路由
测试:访问 http://127.0.0.1:5000/map/test
应显示测试文本。
第五步:分阶段开发计划
阶段 | 目标功能 | 关键技术点 |
---|---|---|
阶段1 | 基础绘图(点、线) | Canvas API、事件监听 |
阶段2 | 颜色/粗细选择 | 状态管理、UI交互 |
阶段3 | 撤销/重做功能 | 操作历史栈、数据持久化 |
阶段4 | 区域绘制(多边形) | 路径闭合算法、坐标存储 |
阶段5 | 数据保存与加载 | Flask API、文件读写 |
阶段6 | 网格系统与吸附功能 | 数学计算、Canvas 绘制优化 |
关键原则
- 单一职责:每个阶段只实现一个核心功能。
- 即时测试:每添加一小段代码立即验证效果。
- 版本备份:使用 Git 或手动备份代码,方便回滚。
- 文档记录:为每个功能添加注释,记录实现思路。