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
{
"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.
| Tipo | Para qué sirve |
|---|---|
frame | Contenedor con layout, relleno, borde y recorte. Es la base de pantallas, láminas y componentes |
group | Agrupa nodos sin layout propio |
rectangle, ellipse, polygon | Formas básicas |
path | Trazo vectorial con geometría SVG |
text | Texto con fuente, tamaño, peso y alineación |
icon | Icono de una librería (lucide, phosphor, Material Symbols…) |
ref | Instancia de un componente |
note, prompt, context | Notas y contexto para personas y agentes dentro del canvas |
script | Contenido generado por un script en un entorno aislado |
browser | Página web embebida (canvappen la muestra como recuadro de reemplazo) |
Propiedades comunes
| Propiedad | Valor |
|---|---|
name | Nombre visible en capas |
x, y, width, height | Posición y tamaño |
opacity | De 0 a 1 |
rotation | Grados, en sentido antihorario |
flipX, flipY, enabled | Volteo y visibilidad |
layoutPosition | auto o absolute (ignora el layout del padre) |
reusable | true convierte el nodo en componente |
theme, metadata | Selección de tema y datos libres |
Tamaños
| Valor | Significado |
|---|---|
320 | Pí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".
{
"type": "frame",
"layout": "vertical",
"gap": 16,
"padding": [24, 32],
"justifyContent": "start",
"alignItems": "center",
"clip": true,
"children": []
}| Propiedad | Valores |
|---|---|
gap | Espacio entre hijos |
padding | n, [vertical, horizontal] o [arriba, derecha, abajo, izquierda] |
justifyContent | start, center, end, space_between, space_around |
alignItems | start, center, end |
clip | Recorta 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.
"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" }
]| Propiedad | Valores |
|---|---|
stroke | Igual que fill |
strokeWidth | n o { top, right, bottom, left } |
strokeAlignment | inner, center u outer |
cornerRadius | n o [sup. izq., sup. der., inf. der., inf. izq.] |
effect | Sombra (shadow exterior o interior), blur o background_blur |
"effect": { "type": "shadow", "shadowType": "outer", "offset": { "x": 0, "y": 4 }, "blur": 12, "color": "#00000033" }Texto
{
"type": "text",
"content": "Hola",
"fontFamily": "Inter",
"fontSize": 16,
"fontWeight": "600",
"fill": "#111111",
"textGrowth": "fixed-width",
"width": 320,
"lineHeight": 1.4,
"textAlign": "left"
}Iconos
{ "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.
{
"type": "ref",
"ref": "boton",
"descendants": {
"etiqueta": { "content": "Comprar" },
"icono/trazo": { "fill": "#FFFFFF" }
}
}- Con
typedentro de un override se reemplaza el nodo completo. - Con
apply_operationspuedes editar un descendiente conupdatey el idinstancia/descendiente. - Los componentes de una librería importada llevan el prefijo de su alias:
"N:abc12"; sus variables,"$N:color".
Variables y temas
"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.