Referencia

Formato .pen

Un .pen es un archivo JSON en UTF-8. canvappen lee las versiones 2.0 a 2.21 y guarda en 2.21, conservando cualquier propiedad que no reconoce.

Estructura del archivo

design.pen
{
  "version": "2.21",
  "children": [
    { "type": "frame", "id": "home", "name": "Inicio", "width": 1440, "height": 900, "children": [] }
  ],
  "variables": {},
  "themes": {},
  "imports": {},
  "fonts": []
}

Nodos

Todos los nodos tienen type e id. El id es único y no lleva /; al insertar puedes omitirlo y canvappen lo genera.

TipoPara qué sirve
frameContenedor con layout, relleno, borde y recorte. Es la base de pantallas, láminas y componentes
groupAgrupa nodos sin layout propio
rectangle, ellipse, polygonFormas básicas
pathTrazo vectorial con geometría SVG
textTexto con fuente, tamaño, peso y alineación
iconIcono de una librería (lucide, phosphor, Material Symbols…)
refInstancia de un componente
note, prompt, contextNotas y contexto para personas y agentes dentro del canvas
scriptContenido generado por un script en un entorno aislado
browserPágina web embebida (canvappen la muestra como recuadro de reemplazo)

Propiedades comunes

PropiedadValor
nameNombre visible en capas
x, y, width, heightPosición y tamaño
opacityDe 0 a 1
rotationGrados, en sentido antihorario
flipX, flipY, enabledVolteo y visibilidad
layoutPositionauto o absolute (ignora el layout del padre)
reusabletrue convierte el nodo en componente
theme, metadataSelección de tema y datos libres

Tamaños

ValorSignificado
320Píxeles
"$ancho"Valor de una variable
"fit_content"Se ajusta a su contenido. Requiere layout en el propio nodo
"fill_container"Ocupa el espacio del padre. Requiere layout en el padre
"fit_content(100)"Con un valor de respaldo

Layout

Solo los frames tienen layout: none, horizontal o vertical. Dentro de un frame con layout, la posición x/y de los hijos se ignora salvo que tengan layoutPosition: "absolute".

JSON
{
  "type": "frame",
  "layout": "vertical",
  "gap": 16,
  "padding": [24, 32],
  "justifyContent": "start",
  "alignItems": "center",
  "clip": true,
  "children": []
}
PropiedadValores
gapEspacio entre hijos
paddingn, [vertical, horizontal] o [arriba, derecha, abajo, izquierda]
justifyContentstart, center, end, space_between, space_around
alignItemsstart, center, end
clipRecorta los hijos al borde del frame

Apariencia

fill acepta un color hexadecimal (#RGB, #RRGGBB, #RRGGBBAA), una variable ("$primario"), un objeto o una lista de capas, donde la última queda encima.

JSON
"fill": [
  { "type": "color", "color": "#FF0000" },
  { "type": "gradient", "gradientType": "linear", "rotation": 0,
    "colors": [{ "color": "#000000", "position": 0 }, { "color": "#FFFFFF", "position": 1 }] },
  { "type": "image", "url": "images/foto.png", "mode": "cover" }
]
PropiedadValores
strokeIgual que fill
strokeWidthn o { top, right, bottom, left }
strokeAlignmentinner, center u outer
cornerRadiusn o [sup. izq., sup. der., inf. der., inf. izq.]
effectSombra (shadow exterior o interior), blur o background_blur
JSON
"effect": { "type": "shadow", "shadowType": "outer", "offset": { "x": 0, "y": 4 }, "blur": 12, "color": "#00000033" }

Texto

JSON
{
  "type": "text",
  "content": "Hola",
  "fontFamily": "Inter",
  "fontSize": 16,
  "fontWeight": "600",
  "fill": "#111111",
  "textGrowth": "fixed-width",
  "width": 320,
  "lineHeight": 1.4,
  "textAlign": "left"
}

Iconos

JSON
{ "type": "icon", "library": "lucide", "icon": "house", "width": 24, "height": 24, "fill": "#000000" }

Librerías: lucide, phosphor (con variantes como apple-logo-fill) y Material Symbols, entre otras.

Componentes e instancias

Un componente es cualquier nodo con "reusable": true. Una instancia es un nodo ref que apunta a él; sus propiedades sobrescriben las de la raíz del componente, y descendants cambia nodos internos.

JSON
{
  "type": "ref",
  "ref": "boton",
  "descendants": {
    "etiqueta": { "content": "Comprar" },
    "icono/trazo": { "fill": "#FFFFFF" }
  }
}
  • Con type dentro de un override se reemplaza el nodo completo.
  • Con apply_operations puedes editar un descendiente con update y el id instancia/descendiente.
  • Los componentes de una librería importada llevan el prefijo de su alias: "N:abc12"; sus variables, "$N:color".

Variables y temas

JSON
"themes": { "modo": ["claro", "oscuro"] },
"variables": {
  "primario": { "type": "color", "value": "#2563EB" },
  "fondo": { "type": "color", "value": [
    { "value": "#FFFFFF", "theme": { "modo": "claro" } },
    { "value": "#000000", "theme": { "modo": "oscuro" } }
  ] }
}

El primer valor de cada eje es el predeterminado. Se usan con $: "fill": "$fondo". Para editarlas, usa set_variables y set_themes.