Layout adaptation engine for auto-sizing canvas elements across different dimensions. Ports the proven frontend auto-adapt algorithm to a reusable package for use in both client and server environments.
@rocketium/auto-adapt intelligently adapts canvas layouts from one size to another. Given a set of canvas elements (text, images, shapes, groups, SVGs) designed for one dimension, it produces a proportionally adapted layout for a target dimension while preserving alignment, edge-snapping, and visual hierarchy.
- Closest-size matching -- finds the best reference size from available sizes using aspect-ratio + Euclidean distance scoring
- Smart skew detection -- decides whether to stretch (skew) or proportionally scale each element based on its canvas coverage
- Per-element-type adaptation -- specialized handling for text (font sizes, word styles, autofit), images (crop offsets, scale), shapes (SVG, rounded-rect, path), and groups (recursive child adaptation)
- Edge-aware positioning -- preserves alignment to canvas edges and centering
- Override system -- stores adapted layouts as per-size overrides on the original objects, keeping the base variant untouched
npm install @rocketium/auto-adaptFor local development (before publishing):
npm install ../auto-adapt| Package | Version | Required |
|---|---|---|
@types/fabric | ^5.3.9 | Optional (compile-time only) |
The package uses @types/fabric for canvas element type definitions. If you're consuming typed APIs, ensure it's installed as a devDependency.
import{generateBaseLayoutForSize}from'@rocketium/auto-adapt';constnewCapsule=generateBaseLayoutForSize({
originalCapsule,// ServerCapsule with existing sizes and objectscapsuleId: 'abc123',creativeId: null,// null = auto-detect best reference sizesizeId: 'new-size-id',sizeToGenerate: '300x250',sizeName: 'Medium Rectangle',sizeCategory: 'Display',});Main entry point. Generates a complete adapted capsule for a target size.
Parameters:
| Param | Type | Description |
|---|---|---|
originalCapsule | ServerCapsule | Source capsule with canvas data, sizes, and objects |
capsuleId | string | ID of the capsule being adapted |
creativeId | string | null | Reference size ID to adapt from. Pass null to auto-detect the closest match |
sizeId | string | ID for the new size entry |
sizeToGenerate | string | Target dimensions as "WIDTHxHEIGHT" (e.g. "1080x1080") |
sizeName | string? | Display name for the new size |
sizeCategory | string? | Category label for the new size |
Returns:ServerCapsule -- a deep copy of the original capsule with the new size added, objects adapted as overrides, and metadata updated.
Core adaptation algorithm. Adapts a flat record of canvas elements from one size to another.
Parameters:
| Param | Type | Description |
|---|---|---|
adaptSize | string | Target dimensions ("WIDTHxHEIGHT") |
objects | Record<string, CanvasElementJSON> | Source elements keyed by ID |
closestSize | string | Reference dimensions ("WIDTHxHEIGHT") |
Returns:Record<string, CanvasElementJSON> -- adapted elements.
Finds the closest matching size from a list, with match-quality scores.
Parameters:
| Param | Type | Description |
|---|---|---|
availableSizes | string[] | Array of dimension strings |
adaptSize | string | Target dimension string |
Returns:{ closestSize: string; sortedMatches: Record<string, number> } -- best match and percentage scores for all sizes.
Finds the best reference size ID from a sizes record.
Parameters:
| Param | Type | Description |
|---|---|---|
availableSizes | Record<string, { width: number; height: number }> | Available sizes keyed by ID |
targetSize | string | Target dimension string |
Returns:string -- the key of the best matching size.
| Function | Description |
|---|---|
resolveObjectsForSize(objects, sizeId) | Flatten overrides for a specific size into base objects |
applyAdaptedAsOverrides(originals, adapted, sizeId) | Store adapted objects as overrides on originals |
getNormalizedSizeValue(sizeValue) | Normalize named sizes ("square" -> "720x720") |
getEuclideanDistanceBetweenSizes({ size1, size2 }) | Distance between two size strings |
| Function | Checks for |
|---|---|
isTextJSON(object) | TextContainerJSON |
isImageJSON(object) | ImageContainerJSON |
isShapeJSON(object) | PathJSON | RoundedRectJSON | SvgJSON |
isSVGContainerJSON(object) | SvgJSON |
isRoundedRectJSON(object) | RoundedRectJSON |
isGroupJSON(object) | GroupContainerJSON |
isCreativeBoxJSON(object) | Creative box elements |
isAudioJSON(object) | Audio elements |
Uses a weighted scoring system combining:
- Aspect ratio similarity (90% weight) -- prefers sizes with matching proportions
- Euclidean distance (10% weight) -- tiebreaks with absolute dimension proximity
For each element, the algorithm decides between two paths:
Skew path -- stretches the element to fill proportionally. Used when:
- Element covers >90% of the canvas area
- Element spans the full width or full height of the canvas
- Groups are excluded from skewing
Non-skew path -- proportionally scales while preserving position. Uses:
- Edge alignment detection (snaps to nearest edge within 1px threshold)
- Horizontal centering detection (area-based left/right balance)
- Quadrant-based positioning for non-centered, non-edge-aligned elements
| Type | Special Handling |
|---|---|
| Text | Scales fontSize, wordStyle font sizes (px only), autoFitSizes, padding, wordSpacing |
| Image | Scales imageScale, imageLeft/imageTop offsets, cornerRadius |
| SVG | Same as image + colorMap passthrough |
| RoundedRect | Scales cornerRadius |
| Path/Shape | Scales scaleX/scaleY instead of width/height |
| Group | Recursively adapts all children with group-relative scaling |
| CreativeBox | Resized to target dimensions (canvas background) |
| Audio | Passed through unchanged |
src/
├── index.ts # Public API exports
├── adapter.ts # Core adapt logic + entry function
├── constants.ts # Thresholds and defaults
├── types/
│ ├── index.ts # Type barrel exports
│ ├── canvas.ts # Canvas element type definitions
│ └── capsule.ts # ServerCapsule type
└── utils/
├── sizeMatching.ts # Size comparison and closest-match algorithms
├── scaling.ts # Element scaling, border, padding helpers
└── typeGuards.ts # Runtime type guards for canvas elements
# Install dependencies
npm install
# Type check
npm run typecheck
# Build (CJS + ESM + .d.ts)
npm run build
# Lint
npm run lint
# Format
npm run formatFor local linking: npm install ../auto-adapt from a consumer project.
Publishing uses the Rocketium org account. Personal ~/.npmrc is left unchanged.
Create
.npmrcin the project root (gitignored). Use this structure://registry.npmjs.org/:_authToken=REPLACE_WITH_ROCKETIUM_NPM_TOKENReplace
REPLACE_WITH_ROCKETIUM_NPM_TOKENwith the actual token (or${NPM_TOKEN}for env-based auth).Publish:
npm run release:patch/minor/major
as per the requirement
Proprietary - All Rights Reserved. No use, copy, or distribution without written permission from Rocketium.