npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geosolution-apps/mapbox-gl-draw-snap-assist

v0.2.0

Published

Snap-to-vertex, snap-to-edge, alignment guides, and vertex deletion for @mapbox/mapbox-gl-draw

Downloads

45

Readme

@geosolution-apps/mapbox-gl-draw-snap-assist

Snap a vertices, snap a bordes, guias de alineacion y eliminacion de vertices para @mapbox/mapbox-gl-draw. Compatible con MapLibre GL JS.

Caracteristicas

  • Snap a vertice — el cursor se ajusta a vertices cercanos de features existentes en el mapa (indicador rojo)
  • Snap a borde — el cursor se ajusta al punto mas cercano en un borde de linea/poligono (indicador azul)
  • Guias de alineacion — lineas visuales que muestran alineacion horizontal, vertical y diagonal con vertices ya colocados
  • Snap a guias — el cursor puede ajustarse a las lineas guia y sus intersecciones
  • Eliminacion de vertices — Shift+Click para eliminar vertices en modo direct select
  • Fuentes de features personalizadas — sobreescribe como se obtienen los candidatos de snap

Instalacion

npm install @geosolution-apps/mapbox-gl-draw-snap-assist

Dependencias peer

Deben estar instaladas en tu proyecto:

npm install @mapbox/mapbox-gl-draw maplibre-gl

Desarrollo local (desde el codigo fuente)

Si trabajas directamente con el codigo fuente:

cd mapbox-gl-draw-snap-assist

# Instalar dependencias
npm install

# Compilar (genera dist/)
npm run build

# Modo watch (recompila al detectar cambios)
npm run dev

La compilacion genera los archivos en dist/:

  • dist/index.js — Modulo ESM
  • dist/index.cjs — Modulo CommonJS
  • dist/index.d.ts — Declaraciones TypeScript

Vincular a un proyecto local

Si la libreria esta como carpeta hermana o submodulo:

# En el package.json del proyecto que consume, agregar:
"dependencies": {
  "@geosolution-apps/mapbox-gl-draw-snap-assist": "file:../mapbox-gl-draw-snap-assist"
}

# Luego instalar
npm install

Importante: Despues de hacer cambios en el codigo fuente de la libreria, debes ejecutar npm run build para que el proyecto consumidor tome los cambios (lee de dist/, no de src/).

Inicio rapido

import MapboxDraw from "@mapbox/mapbox-gl-draw";
import {
  SnapLineMode,
  SnapPolygonMode,
  SnapDirectSelect,
} from "@geosolution-apps/mapbox-gl-draw-snap-assist";

// 1. Registrar los modos en MapboxDraw
const draw = new MapboxDraw({
  modes: {
    ...MapboxDraw.modes,
    snap_line: SnapLineMode,
    snap_polygon: SnapPolygonMode,
    snap_direct: SnapDirectSelect,
  },
});

// 2. Agregar el control de dibujo al mapa
map.addControl(draw);

// 3. Activar un modo snap con opciones
draw.changeMode("snap_line", {
  snapPx: 12,
  showAlignmentGuides: true,
  snapToGuides: true,
});

Modos exportados

| Modo | Reemplaza a | Descripcion | | ------------------ | ------------------ | ---------------------------------------------------------- | | SnapLineMode | draw_line_string | Dibujo de lineas con snap + guias de alineacion | | SnapPolygonMode | draw_polygon | Dibujo de poligonos con snap + guias de alineacion | | SnapDirectSelect | direct_select | Edicion de vertices con snap + eliminacion con Shift+Click |

Registro de modos

Puedes reemplazar los modos nativos o agregarlos como modos adicionales:

// Opcion A: Reemplazar los modos nativos (todo el dibujo usa snap)
const draw = new MapboxDraw({
  modes: {
    ...MapboxDraw.modes,
    draw_line_string: SnapLineMode,
    draw_polygon: SnapPolygonMode,
    direct_select: SnapDirectSelect,
  },
});

// Opcion B: Agregar como modos separados (conservar los originales)
const draw = new MapboxDraw({
  modes: {
    ...MapboxDraw.modes,
    snap_line: SnapLineMode,
    snap_polygon: SnapPolygonMode,
    snap_direct: SnapDirectSelect,
  },
});

Opciones (SnapAssistOptions)

Las opciones se pasan como segundo argumento de draw.changeMode():

draw.changeMode("snap_line", {
  // Todas las opciones listadas abajo
});

| Opcion | Tipo | Default | Descripcion | | --------------------- | ---------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | snapPx | number | 10 | Radio de snap en pixeles de pantalla. Las features dentro de esta distancia del cursor se consideran candidatas. | | snapToDrawFeatures | boolean | true | Incluir features ya dibujadas en el canvas de draw como candidatas de snap. La feature que se esta dibujando actualmente se excluye automaticamente. | | showAlignmentGuides | boolean | false | Mostrar lineas guia de alineacion entre los vertices colocados y el cursor. | | snapToGuides | boolean | false | Ajustar el cursor a las lineas guia y sus intersecciones. Requiere showAlignmentGuides: true para funcionar. | | alignTolerance | number | 8 | Tolerancia en pixeles para activar las guias de alineacion. Menor = las guias aparecen solo cuando estas muy cerca de la alineacion. | | alignAngles | number[] | [0, 45, 90, 135,180, 225, 270, 315] | Angulos (grados, sentido horario desde el norte) en los que se detecta alineacion. 0/180 = horizontal, 90/270 = vertical, otros = diagonal. | | layerIds | string[] | undefined | Lista blanca de IDs de capas MapLibre para buscar candidatos de snap. Si se omite, se consultan todas las capas renderizadas. | | sourceIds | string[] | undefined | Lista blanca de IDs de source. Los features se filtran por coincidencia parcial (ej: 'CABLE' coincide con el source 'MV_TRAMO_DE_CABLE'). | | snapGetFeatures | function | undefined | Funcion personalizada para sobreescribir la obtencion de features. Ver Fuentes personalizadas. |

Guias de alineacion

Cuando showAlignmentGuides: true, la libreria dibuja segmentos cortos punteados desde un vertice de referencia hasta la proyeccion del cursor sobre ese eje de alineacion.

Colores de las guias

| Alineacion | Color | Angulos | | ---------- | ----------------- | --------------------- | | Horizontal | Cyan #06b6d4 | 0°, 180° | | Vertical | Magenta #d946ef | 90°, 270° | | Diagonal | Gold #f59e0b | 45°, 135°, 225°, 315° |

Cada guia tambien muestra un pequeno circulo del mismo color en el vertice de referencia, para indicar cual vertice esta generando la guia.

Como funcionan

  1. Colocas uno o mas vertices
  2. Al mover el cursor, el engine verifica si el cursor esta alineado (dentro de alignTolerance pixeles) con algun vertice ya colocado
  3. Si esta alineado, se dibuja un segmento corto punteado desde ese vertice hasta la proyeccion del cursor en el eje de alineacion
  4. Si snapToGuides: true, el cursor se ajusta a la linea guia mas cercana. Cuando dos guias se cruzan (ej: horizontal desde vertice A + vertical desde vertice B), el cursor se ajusta al punto de interseccion

Desactivar guias diagonales

Pasar solo angulos cardinales:

draw.changeMode("snap_line", {
  showAlignmentGuides: true,
  alignAngles: [0, 90, 180, 270],
});

Comportamiento del snap

Prioridad

  1. Snap a vertice (mayor prioridad) — Si el cursor esta dentro de snapPx de un vertice, se ajusta ahi
  2. Snap a borde — Si no hay vertice cercano pero un borde esta dentro de snapPx, se ajusta al punto mas cercano en ese borde
  3. Snap a guia (menor prioridad) — Si no hubo snap a feature y snapToGuides: true, se ajusta a la linea guia o interseccion mas cercana

Indicadores visuales

  • Circulo rojo — Snap a vertice
  • Circulo azul — Snap a borde
  • Las lineas guia son solo visuales (segmentos punteados); el circulo indicador de snap aparece por separado

Que se ajusta

  • onClick / onTap: la coordenada del vertice colocado es la posicion snapeada
  • onMouseMove: la linea de rubber-band sigue el cursor real (no el snapeado). Esto es intencional — la vista previa usa el cursor real mientras que el punto final colocado usa el snap

Eliminacion de vertices (SnapDirectSelect)

En el modo SnapDirectSelect, Shift+Click sobre un vertice lo elimina:

  • LineString: minimo 2 vertices (no permite eliminar si quedan 2)
  • Polygon: minimo 3 vertices unicos (no permite eliminar si quedan 3)

La tecla Delete tambien funciona a traves del handler estandar onTrash de MapboxDraw.

Fuentes de features personalizadas

Usa snapGetFeatures para controlar completamente que features estan disponibles para snap:

draw.changeMode("snap_line", {
  snapGetFeatures: (map, cursor, snapPx) => {
    // Ejemplo: solo hacer snap a capas especificas
    const point = map.project(cursor);
    return map.queryRenderedFeatures(
      [
        [point.x - snapPx, point.y - snapPx],
        [point.x + snapPx, point.y + snapPx],
      ],
      { layers: ["my-cables-layer", "my-poles-layer"] },
    );
  },
});

Cuando se proporciona snapGetFeatures:

  • layerIds, sourceIds y snapToDrawFeatures se ignoran
  • El array de Feature[] retornado se usa directamente como candidatos de snap
  • La funcion recibe (map, cursor: [lng, lat], snapPx: number)

Ejemplos de uso

Snap basico (sin guias)

draw.changeMode("snap_line", {
  snapPx: 10,
  snapToDrawFeatures: true,
});

Snap a sources especificos con guias

draw.changeMode("snap_line", {
  snapPx: 12,
  sourceIds: ["MV_TRAMO_DE_CABLE", "MV_POSTE"],
  showAlignmentGuides: true,
  snapToGuides: true,
});

Poligono con solo guias H/V

draw.changeMode("snap_polygon", {
  snapPx: 10,
  showAlignmentGuides: true,
  snapToGuides: true,
  alignAngles: [0, 90, 180, 270],
});

Desactivar snap para herramientas de seleccion

draw.changeMode("snap_line", {
  snapPx: 0,
});

Editar vertices con snap

draw.changeMode("snap_direct", {
  featureId: "some-feature-id",
  snapPx: 10,
  sourceIds: ["MV_TRAMO_DE_CABLE"],
});

Nota: SnapDirectSelect no soporta guias de alineacion — solo snap a vertices/bordes.

Limpieza

La limpieza es automatica. Cuando draw.changeMode() cambia a otro modo, se ejecuta onStop internamente y todos los sources/layers del mapa agregados por la libreria se eliminan. No se necesita limpieza manual.

TypeScript

La libreria incluye declaraciones TypeScript. Importar los tipos:

import type {
  SnapAssistOptions,
  SnapResult,
} from "@geosolution-apps/mapbox-gl-draw-snap-assist";

Arquitectura

src/
  index.ts                      # Exports publicos
  types.ts                      # Interfaces TypeScript
  modes/
    SnapLineMode.ts             # Modo de dibujo de lineas con snap
    SnapPolygonMode.ts          # Modo de dibujo de poligonos con snap
    SnapDirectSelect.ts         # Modo de edicion de vertices con snap + eliminacion
    helpers.ts                  # resolveOptions (merge de defaults)
  core/
    SnapEngine.ts               # Consulta de features + calculo de distancia vertice/borde
    AlignmentEngine.ts          # Deteccion de guias de alineacion + snap a guias
    FeatureCache.ts             # Wrapper de queryRenderedFeatures
    CoordUtils.ts               # Distancia en pixeles, bbox, extraccion de coordenadas
  overlays/
    SnapOverlay.ts              # Circulo indicador en el punto de snap
    GuideOverlay.ts             # Lineas guia punteadas + circulos en vertices

Licencia

MIT