跪拜 Guibai
← Back to the summary

A Library-Agnostic Geometry Editor That Runs Without a UI

Frontend Universal Interactive Geometry Editor: Design Series Guide

1. Why Write This

Most frontend developers have encountered the requirement to "draw something on a map." Drawing a point, connecting a line, or outlining an area seems simple, but turning it into an editor that can be integrated by business systems and extended by others is where most available tools fall short:

What they lack is not functionality, but an engineering aesthetic: making an editor as trustworthy as a library — with clear boundaries, unidirectional dependencies, composability, replaceability, and long-term maintainability.

Thus came this skill (geometry-interactive-editor) and this series of articles.

https://github.com/maanfa/skills/tree/master/skills/geometry-interactive-editor

They essentially do two things:

  1. Propose applicable scenarios: An interactive geometry editor is not just for "maps" — 2D canvases, 3D scenes, and any canvas geometry editing are its stage; it should exist cross-library, UI-less, and purely imperative.
  2. Summarize lessons learned: These are the design trade-offs forced by years of developing editing features, stepping into pitfalls, refactoring, and being pushed by "integration requirements." If it can help readers and fellow practitioners avoid detours, that would be an honor for me.

There is no mysticism in this series, only "why it's divided this way, and when you can skip it."

2. Overall Design Overview

First, look at a "master diagram"; each subsequent article will expand on it:

PixPin_2026-08-09_22-04-40.png

Key points for reading the diagram:

3. Two Classic Flows

Here's a sneak peek at two "minimum closed loops" to feel what the interaction between the host and the library looks like (full versions in articles 4 and 5).

Drawing a polygon:

sequenceDiagram
    actor U as User
    participant F as Facade
    participant D as Drawer
    participant A as MapAdapter

    U->>F: startDraw('polygon')
    loop Each vertex click
        U->>D: leftdown (via MouseManager)
        D->>D: Strategy appends vertex
    end
    U->>D: doubleclick to finish
    D-->>F: draw:finished
    F->>A: updateElement (incremental render)

Dragging a vertex:

sequenceDiagram
    actor U as User
    participant F as Facade
    participant M as Modifier
    participant A as MapAdapter

    U->>F: select(id) + startEdit(id)
    F->>M: Create vertex handles
    U->>M: Drag handle
    M-->>F: edit:vertex-dragged
    F->>A: updateElement (incremental render)

A common flavor in both: the host only touches the Facade, drawing/editing logic never directly touches the map library, and rendering always goes through the adapter.

4. Series Articles

5. Reading Order

1 → 2 → 3 → 4 → 5 → 6 → 7. Each article is independently readable, but later ones will reference concepts from earlier ones; each article ends with "When to use / When not to" — because good design also knows when to stop where it's not needed.

6. Diagram Legend Conventions

All diagrams in the text are mermaid:

May this body of work spare a fellow practitioner, agonizing late at night over "how to get this editor integrated," a little bit of struggle.