Infinite Canvas — Manual Rápido
Un espacio visual libre para organizar ideas, flujos, estructuras o prototipos.
Basado en nodos, aristas, zoom infinito y persistencia automática.
🎮 Gestos del Mouse
- Doble clic en vacío → crea nueva tarjeta.
- Doble clic en el título → editar (Enter confirma · Esc cancela · blur confirma).
- Arrastre en vacío → panning.
- Shift + arrastre → marquee selection (caja de selección).
- Rueda del mouse → zoom centrado en el cursor.
🔀 Selección y Movimiento
- Clic en vacío → limpia la selección.
- Ctrl/⌘ + clic en tarjeta → (de)selecciona sin afectar las demás.
- Arrastrar con varias seleccionadas → mueve el grupo.
- Al soltar un arrastre → snap a la grilla.
- Mantén Ctrl/⌘ para SNAP OFF.
- Shift + clic entre dos tarjetas → crea una arista (link).
- Mantén Alt dentro del canvas → modo borrar (clic para eliminar, con confirmación).
🗑️ Borrado
- Delete/Backspace → borra tarjetas seleccionadas y sus aristas.
- Alt + clic en tarjeta o arista → borrar con confirmación.
🧭 Controles del HUD
- Zoom + / Zoom − / Reset / Fit → control de cámara.
- Export → descarga JSON del grafo.
- Import → carga un archivo JSON.
- Clear → elimina el grafo guardado en esta ruta y recarga.
📁 Drag & Drop
- Arrastra un archivo
.jsonal canvas → importa el grafo.
⌨️ Atajos del Teclado
+o=→ Zoom in-→ Zoom out0→ Reset de cámaraF→ Fit to screenEsc→ cancela linking o limpia selección- Ctrl/⌘ (mantenido) → SNAP OFF
💾 Persistencia y Grilla
- Nodos, aristas y cámara se guardan en localStorage según la ruta.
- La grilla se basa en
:root --grid-sizey realinea automáticamente mediante ResizeObserver. - El HUD muestra nivel de Zoom + estado de SNAP.
🔌 Origen del Grafo al Iniciar (prioridad)
data-prefer-storage="true"→ si existe guardado, lo carga.window.INIT_GRAPHdata-graph-url- LocalStorage
<script id="graphData">- Grafo por defecto (demo)
📝 Notas Técnicas
- Aristas con trazo no escalable y zona de clic amplia.
- Con Alt, el SVG de aristas vuelve a aceptar eventos (borrado fino).
- Import/Export y drag-&-drop validan y sanitizan el JSON.