PerfectVector
Por Irene Kim8 min de lectura

Operaciones booleanas SVG en Paper.js: corta y une diseños

Importa trazados SVG en Paper.js, une formas superpuestas, resta una abertura real y comprueba el archivo exportado con un pequeño ejemplo reproducible en navegador.

En esta página

Importa el SVG, encuentra los objetos de trazado previstos y después llama a unite() para unir regiones con relleno o a subtract() para eliminar una región de otra. Conserva los operandos hasta comprobar el resultado y vuelve a abrir el SVG exportado antes de utilizarlo en otro lugar.

La decisión importante ocurre antes de la operación booleana: ¿qué formas pertenecen juntas? Un grupo importado puede contener rectángulos de fondo, trazados de recorte, letras y elementos decorativos. Combinar todos los hijos puede borrar las separaciones que querías conservar. Esta guía utiliza tres trazados cerrados con nombre para que veas exactamente qué cambia.

Empieza por geometría con relleno que puedas identificar

El importador SVG de Paper.js acepta marcado SVG, un elemento SVG o una URL. Esos métodos necesitan tratamientos de carga diferentes: este ejemplo importa una cadena en línea; un archivo remoto debe procesarse en la función de devolución de llamada de la importación, una vez cargado.

Para esta tarea, los operandos deben ser objetos Path o CompoundPath. Un grupo es un contenedor y una imagen rasterizada no proporciona el límite necesario para una operación booleana de trazados. Si un archivo solo se comporta como una única imagen, comprueba primero por qué un SVG no se puede desagrupar.

Utiliza identificadores para las partes que controlas. No supongas que children[0] significa «el logotipo» en cualquier exportación. Inspecciona los diseños desconocidos y asigna las partes deliberadamente. Conserva intacto un trazado compuesto existente cuando sus subtrazados ya definan los huecos previstos.

Ejecuta una pequeña importación, unión y resta

Probamos el siguiente código con Paper.js 0.12.18 en un navegador. La ilustración es un SVG original escrito a mano: un cuerpo cuadrado, una pestaña superpuesta y un cuadrado blanco que marca la abertura prevista. No es una muestra de conversión de PerfectVector.

En una carpeta vacía, instala la biblioteca con la versión fijada:

npm install --save-exact paper@0.12.18

Guarda esto como index.html:

<!doctype html>
<meta charset="utf-8">
<title>SVG Boolean example</title>
<canvas id="work" width="300" height="220" hidden></canvas>
<div id="result" style="background:#d8e8e0; width:300px"></div>
<pre id="svg-output"></pre>
<script src="node_modules/paper/dist/paper-full.min.js"></script>
<script src="example.js"></script>

Guarda esto como example.js y después abre el HTML en un navegador:

paper.setup(document.getElementById('work'));
const source = `<svg xmlns="http://www.w3.org/2000/svg" width="300" height="220" viewBox="0 0 300 220">
  <path id="body" fill="#176b62" d="M40 40H180V180H40Z"/>
  <path id="tab" fill="#ee9852" d="M160 80H260V140H160Z"/>
  <path id="hole" fill="#ffffff" d="M80 80H130V130H80Z"/>
</svg>`;
const imported = paper.project.importSVG(source, { insert: false, expandShapes: true });
function operand(name) {
  const item = imported.getItem({ name });
  if (!(item instanceof paper.Path || item instanceof paper.CompoundPath)) {
    throw new Error(`Expected path geometry for ${name}`);
  }
  return item;
}
const joined = operand('body').unite(operand('tab'), { insert: false });
const cut = joined.subtract(operand('hole'), { insert: false });
cut.fillColor = '#176b62';
cut.strokeColor = null;
paper.project.activeLayer.addChild(cut);
const output = paper.project.exportSVG({ asString: true, bounds: new paper.Rectangle(0, 0, 300, 220) });
document.getElementById('result').innerHTML = output;
document.getElementById('svg-output').textContent = output;

La importación permanece fuera de la escena con insert: false. expandShapes: true pide al importador que convierta las formas primitivas compatibles en trazados; nuestro ejemplo ya contiene elementos de trazado. La comprobación explícita de clase sigue siendo importante porque un identificador importado puede identificar un contenedor u otro tipo de elemento.

La API booleana devuelve un nuevo elemento de trazado. Aquí el resultado se mantiene fuera de la escena hasta añadir la forma final recortada. Las partes originales siguen disponibles bajo imported, por lo que una operación fallida no exige reconstruir el original.

joined.subtract(hole) elimina el hueco de la silueta unida. Invertir los operandos plantea otra pregunta y puede dar un resultado vacío o inesperado. El modo predeterminado de resta de Paper.js trata los operandos como áreas. Su opción trace se refiere a la geometría booleana; no tiene relación con vectorizar un PNG.

Comparación en navegador de tres trazados SVG importados, una silueta unida con una abertura cuadrada transparente y el resultado exportado abierto de nuevo
El fondo rayado queda oculto tras el parche blanco original y se ve a través de la abertura restada. La exportación conserva esa abertura al importarse de nuevo.

Comprueba el resultado como geometría y como archivo

En este ejemplo, la unión devolvió un Path; la resta devolvió un CompoundPath con dos contornos. Los límites finales fueron x = 40, y = 40, width = 220, height = 140 en unidades SVG. La ilustración está dentro de una ventana de exportación de 300 × 220, por lo que los límites y el tamaño del documento son diferentes deliberadamente.

Comprobamos el centro de la abertura en (105, 105): estaba dentro de la silueta unida y fuera del resultado restado. Un punto del cuerpo sólido en (60, 60) permaneció dentro. Volver a importar el SVG exportado conservó los límites y volvió a excluir el centro del hueco. Son resultados de este ejemplo sencillo, no una garantía para todos los archivos importados.

La API de exportación puede devolver una cadena SVG y aceptar límites explícitos. Copia el marcado mostrado debajo del resultado en result.svg y después abre ese archivo de forma independiente. Nuestra exportación guardada contenía un elemento de trazado con dos subtrazados cerrados; también se renderizó correctamente al abrirla directamente en el navegador.

Para tu propio diseño, comprueba:

  • la silueta y cada abertura frente al original;
  • si se incluyó por accidente algún fondo o forma auxiliar oculta;
  • el relleno previsto, porque una forma unida no puede conservar dos rellenos planos editables de forma independiente;
  • la ventana de exportación, especialmente cuando el diseño llega al borde del documento;
  • el archivo en la aplicación que realmente lo utilizará.

Una superposición blanca puede parecer una abertura sobre papel blanco. Coloca el resultado sobre un fondo de contraste para comprobar la transparencia. La guía de huecos SVG que se rellenan explica los problemas relacionados de trazados compuestos y reglas de relleno.

Cuando la operación produce la forma incorrecta

Falta un método. Inspecciona la clase del elemento seleccionado. Encuentra el trazado previsto dentro de un grupo o convierte formas primitivas compatibles durante la importación. No lo resuelvas combinando todos los descendientes: los trazados compuestos también contienen hijos y sus relaciones de huecos importan.

El resultado parece igual. Asegúrate de mostrar el elemento devuelto. Dejar visibles los originales puede cubrir una resta correcta. En el ejemplo, solo entra el resultado final en la capa activa.

Un trazo desaparece o cambia de significado. Este ejemplo trabaja con regiones cerradas con relleno. Una línea gruesa visible no es automáticamente la misma forma que el área que ocupa su trazo. Si necesitas ese contorno como operando con relleno, prepara una copia con el trazo convertido en contorno en un editor vectorial e inspecciónala antes de importar. Conserva el original editable.

Un diseño detallado se comporta mal. Aísla dos operandos e inspecciona sus contornos antes de aplicar una secuencia a toda una ilustración. Los duplicados, las autointersecciones y los fragmentos diminutos necesitan comprobaciones específicas. Este pequeño ejemplo no mide rendimiento ni compatibilidad amplia con SVG. Para una reparación puntual, las herramientas de selección y nodos de un editor vectorial pueden ser más sencillas que escribir un proceso de geometría.

Cuando tu original sigue siendo PNG o JPG

Si falta el original editable, el proceso de imagen a vector de PerfectVector puede ayudarte a preparar un SVG a partir de un diseño rasterizado adecuado. Previsualiza el resultado, inspecciona los contornos y los espacios negativos y descarga una alternativa para probar en Paper.js.

La vectorización no identifica qué partes debe unir o restar tu programa. Aun así debes inspeccionar la estructura importada, seleccionar los operandos correctos y comprobar el resultado exportado. Utiliza el vector original cuando lo tengas; dibuja directamente un cuadrado o círculo sencillo en lugar de trazarlo. La introducción a la vectorización de imágenes explica esa decisión sobre el archivo original.

Preguntas frecuentes

¿Puedo llamar a unite sobre un grupo SVG importado? Selecciona primero los operandos Path o CompoundPath previstos dentro del grupo. Un grupo describe la organización y combinar todos los hijos puede incluir fondos o destruir separaciones intencionadas.

¿Elimina subtract los trazados originales? Devuelve un nuevo elemento de trazado. Este ejemplo utiliza insert: false para la importación y los resultados booleanos y después inserta solo el resultado final. Los operandos originales siguen disponibles bajo el contenedor importado.

¿Por qué un hueco sigue pareciendo blanco? Compruébalo sobre un fondo de color. Un objeto blanco con relleno cubre lo que tiene detrás; una abertura restada deja ver ese fondo. Vuelve a abrir el archivo exportado para confirmar que la relación se conserva.

¿Realizará la vectorización la limpieza booleana por mí? No. Puede recuperar trazados a partir de un original rasterizado adecuado, pero tu aplicación sigue teniendo que elegir qué geometría unir, qué área eliminar y cómo validar el resultado.

Fuentes

  1. Paper.js — Referencia de Project — documenta la importación y exportación SVG, los límites y el contenido del proyecto.
  2. Paper.js — Referencia de Path — define la unión y la resta, los elementos de trazado devueltos y las opciones booleanas.
  3. Paper.js — Referencia de CompoundPath — describe la geometría compuesta y sus trazados constituyentes.

Si una imagen rasterizada es tu único original, prepara una alternativa SVG, inspecciona sus partes y después prueba la operación booleana mínima útil antes de procesar el resto de la ilustración.

Más del blog

Empieza con un SVG más limpio
y fácil de editar