Skip to content
Apexify.jsDocs
Apexify.js version v5.4.5

Node / Images Shapes · guide

Masking, distortion & mesh warp

Current Apexify.js 6.0.0 documentation for Masking, distortion & mesh warp.

apexify.jsRuntime: nodeCURRENTSince 6.0.0

These options apply only when source is a bitmap (string / Buffer). Shape layers use drawShape — use clipPath / borderRadius on the layer instead.


Mask compositing — mask

SOURCEtypescript
typescript
Studio
mask?: {  source: string | Buffer;  mode?: 'alpha' | 'luminance' | 'inverse';};
FieldRole
sourceSecondary image used as mask channel
modealpha (default): mask alpha drives visibility · luminance: brightness drives visibility · inverse: flips the contribution

The masked bitmap still honours fit / align into the layout box before masking runs.

SOURCEtypescript
typescript
Studio
await painter.createImage(  {    source: './subject.png',    x: 40,    y: 40,    width: 280,    height: 280,    fit: 'cover',    mask: {      source: './mask-soft.png',      mode: 'luminance',    },  },  buffer);

Distortion — distortion

SOURCEtypescript
typescript
Studio
distortion?: {  type: 'perspective' | 'warp' | 'bulge' | 'pinch';  points?: Array<{ x: number; y: number }>;  intensity?: number;};

Implemented today

typeRequirementsNotes
perspectiveExactly four { x, y } corners in pointsMaps the fitted quad into those canvas coordinates
bulgeOptional intensity (default 0.5)Lens bulge centred on the fitted bitmap
pinchOptional intensityNegative bulge

Not wired on the bitmap path

The union includes warp, but ImageCreator.drawImageBitmap currently handles perspective, bulge, and pinch only. warp falls through — leave meshWarp for grid deformation instead.

Distortion branches return immediately after drawing — stroke, effects, and filterOrder: 'post' filters do not run afterward for that layer (see Paint order).

SOURCEtypescript
typescript
Studio
await painter.createImage(  {    source: './poster.jpg',    x: 60,    y: 80,    width: 320,    height: 220,    fit: 'cover',    distortion: {      type: 'perspective',      points: [        { x: 40, y: 40 },        { x: 380, y: 20 },        { x: 360, y: 260 },        { x: 20, y: 240 },      ],    },  },  buffer);

Mesh warp — meshWarp

SOURCEtypescript
typescript
Studio
meshWarp?: {  gridX?: number;  gridY?: number;  controlPoints?: Array<Array<{ x: number; y: number }>>;};
FieldDefaultRole
gridX / gridY10Warp subdivision grid
controlPointsRequired for warpNested arrays of displaced lattice nodes

Like distortion, meshWarp ends the bitmap pipeline early — combine stroke/effects only if you redesign ordering or split layers.


Interaction summary

Use either mask or the straight drawImage path — mesh/distortion branches skip masks.

Do not combine meshWarp + distortion expecting automatic chaining — whichever branch triggers first wins (distortion is evaluated before meshWarp).


Next steps