Xây dựng công cụ Flask đơn giản theo phương pháp Phát triển Tăng dần: Ghi chép quá trình tạo trình chỉnh sửa bản đồ phẳng

Bài viết này ghi lại quá trình phát triển một trình chỉnh sửa bản đồ phẳng bằng Flask theo phương pháp Phát triển Tăng dần. Phương pháp tiếp cận là xây dựng từng chức năng nhỏ một cách có hệ thống.

Bước 1: Khởi tạo cấu trúc dự án

1. Tạo thư mục cơ bản

F:/deepseek/xiaoshuo/
├── app.py            # Điểm vào chính của ứng dụng
└── static/           # Tài nguyên tĩnh
    └── css/
        └── style.css
└── templates/        # Các mẫu HTML
    └── index.html

2. Viết ứng dụng Flask tối giản

Tệp: app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)
Tệp: templates/index.html
<html>
<head>
    <title>Trình chỉnh sửa bản đồ đơn giản</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>Chào mừng đến với trình chỉnh sửa bản đồ</h1>
</body>
</html>

Chạy thử:

python app.py

Truy cập http://127.0.0.1:5000 để xác nhận trang hiển thị bình thường.

Bước 2: Thêm chức năng cơ bản cho vùng vẽ

1. Cập nhật HTML để thêm vùng vẽ

Tệp: templates/index.html
<body>
    <div class="canvas-container">
        <canvas id="main-canvas" width="800" height="600"></canvas>
    </div>
</body>
  • Phần tử Canvas: Tạo một vùng vẽ có kích thước 800x600 pixel để làm khu vực vẽ.

2. Thêm CSS cơ bản

Tệp: static/css/style.css
.canvas-container {
    margin: 20px;
    border: 2px solid #ddd;
}

#main-canvas {
    background: #f8f8f8;
}

3. Thêm tương tác JavaScript cho vùng vẽ

Tạo tệp 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();
  • Định nghĩa lớp SimpleEditor: Đóng gói chức năng vẽ Canvas, giúp quản lý và mở rộng dễ dàng.
  • Tham số constructor canvas: Truyền thể hiện của phần tử Canvas.
  • Lấy ngữ cảnh Canvas ctx: Sử dụng phương thức getContext('2d') để lấy môi trường vẽ, dùng để thực thi các thao tác vẽ khác nhau.

Cập nhật HTML để nhúng JS:

<script src="{{ url_for('static', filename='js/script.js') }}"></script>

Kiểm tra: Nhấp vào vùng vẽ sẽ xuất hiện một dấu chấm đỏ.

Bước 3: Từng bước thêm chức năng cốt lõi

1. Chức năng 1 - Vẽ đường thẳng

Cập nhật script.js:

class SimpleEditor {
    constructor() {
        this.isDrawing = false;
        this.lastX = 0;
        this.lastY = 0;
        // ... mã gốc
    }

    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;
    }
}
  • Thực hiện chức năng vẽ: Phương thức startDrawing.
  • Mục đích: Khởi tạo trạng thái vẽ khi người dùng nhấp chuột vào vùng vẽ.
  • Lấy vị trí Canvas: Phương thức getBoundingClientRect() trả về thông tin biên của Canvas, bao gồm thuộc tính left và top, biểu thị vị trí thực tế của Canvas trên trang.

Kiểm tra: Giữ chuột và kéo để vẽ đường thẳng.

2. Chức năng 2 - Thay đổi màu bút vẽ

Cập nhật HTML (thêm nút chọn màu):

<div class="toolbar">
    <button onclick="editor.setColor('#ff0000')">Đỏ</button>
    <button onclick="editor.setColor('#00ff00')">Xanh lá</button>
</div>
  • Nút màu: Cung cấp hai nút để đặt màu bút vẽ thành đỏ và xanh lá cây. Nhấp vào nút sẽ gọi phương thức JavaScript editor.setColor(color).

Cập nhật script.js:

class SimpleEditor {
    constructor() {
        this.currentColor = '#ff0000';
        // ... mã gốc
    }

    setColor(color) {
        this.currentColor = color;
    }

    draw(e) {
        this.ctx.strokeStyle = this.currentColor;
        // ... mã gốc
    }
}

Kiểm tra: Nhấp vào nút để thay đổi màu, vẽ các đường thẳng có màu khác nhau.

Bước 4: Mở rộng bằng cách module hóa (giới thiệu Blueprint)

1. Tạo thư mục Blueprint

xiaoshuo/
└── map_app/
    ├── __init__.py     # Tệp trống
    └── routes.py

2. Viết các route của Blueprint

Tệp: map_app/routes.py
from flask import Blueprint

map_bp = Blueprint('map', __name__)

@map_bp.route('/test')
def test():
    return "Kiểm tra route Blueprint thành công!"

3. Đăng ký Blueprint vào ứng dụng chính

Cập nhật app.py:

from flask import Flask, render_template
from map_app.routes import map_bp  # Import tuyệt đối

app = Flask(__name__)
app.register_blueprint(map_bp, url_prefix='/map')

# ... các route gốc

Kiểm tra: Truy cập http://127.0.0.1:5000/map/test sẽ hiển thị văn bản kiểm tra.

Bước 5: Kế hoạch phát triển theo giai đoạn

Giai đoạn Mục tiêu chức năng Điểm kỹ thuật chính
Giai đoạn 1 Vẽ cơ bản (điểm, đường thẳng) Canvas API, lắng nghe sự kiện
Giai đoạn 2 Chọn màu/độ dày Quản lý trạng thái, tương tác UI
Giai đoạn 3 Chức năng hoàn tác/làm lại Ngăn xếp lịch sử thao tác, lưu trữ dữ liệu
Giai đoạn 4 Vẽ vùng (đa giác) Thuật toán đóng đường dẫn, lưu trữ tọa độ
Giai đoạn 5 Lưu và tải dữ liệu API Flask, đọc/ghi tệp
Giai đoạn 6 Hệ thống lưới và chức năng hút Tính toán toán học, tối ưu hóa vẽ Canvas

Các nguyên tắc chính

  1. Đơn nhiệm: Mỗi giai đoạn chỉ thực hiện một chức năng cốt lõi.
  2. Kiểm tra tức thì: Xác minh kết quả ngay sau khi thêm một đoạn mã nhỏ.
  3. Sao lưu phiên bản: Sử dụng Git hoặc sao lưu thủ công để dễ dàng quay lại.
  4. Ghi lại tài liệu: Thêm chú thích cho mỗi chức năng, ghi lại ý tưởng triển khai.

Thẻ: Flask python Web Development Canvas API JavaScript

Đăng vào ngày 10 tháng 10 lúc 13:59