@visant/psd-engine
v0.1.0
Published
Isomorphic PSD mockup compositor — ag-psd tree → canvas (perspective warp, blend modes, raster masks, linked smart objects) + Scene Packages for client-side render.
Downloads
143
Maintainers
Readme
@visant/psd-engine
Isomorphic PSD mockup compositor. Takes an ag-psd layer tree and composites it to a canvas — perspective warp, blend modes, raster masks, and linked smart objects — running identically on the server (node-canvas), in the browser (DOM canvas), or in a local CLI.
It powers the Visant Labs mockup render pipeline and the Scene Package format, which pre-processes a PSD once into compact geometry + flattened layer images so the per-art render is a trivial warp + blend on any canvas (no PSD shipped to the client, minimal RAM).
The engine is a generic compositor. The value/secret is the PSD templates — which never ship inside this package.
Install
npm i @visant/psd-engine
# server-side rendering also needs the optional peers:
npm i ag-psd canvasag-psd and canvas are optional peer dependencies. The engine core and scene/render never import them — you inject a canvas factory (CreateCanvas). Browser builds pull in nothing extra.
Exports
| Entry | Purpose |
| --- | --- |
| . | composePsd, flattenLayers, replaceLinkedSmartObjects, perspectiveWarp, coverArtCanvas, BLEND_MAP, computeFaces, constants, types |
| ./scene | extractScene (PSD tree → SceneDoc + layer canvases), renderScene (SceneDoc + art → canvas) |
| ./adapters/node | createNodeAdapter() → { createCanvas, loadImage, toBuffer }, initializeAgPsdCanvas(agPsd) |
| ./adapters/browser | createCanvas, loadImage, toBlob |
Server render (full PSD)
import { flattenLayers, replaceLinkedSmartObjects, composePsd } from '@visant/psd-engine';
import { createNodeAdapter, initializeAgPsdCanvas } from '@visant/psd-engine/adapters/node';
import * as agPsd from 'ag-psd';
const { createCanvas, loadImage, toBuffer } = await createNodeAdapter();
await initializeAgPsdCanvas(agPsd);
const psd = agPsd.readPsd(buffer, { skipThumbnail: true, skipCompositeImageData: true });
const allLayers = flattenLayers(psd.children);
const target = allLayers.find((l) => l.name === 'Design Here');
replaceLinkedSmartObjects(allLayers, target, await loadImage(artBuffer), createCanvas);
const out = toBuffer(composePsd(psd, createCanvas), 'image/png');Scene Package
import { extractScene, renderScene } from '@visant/psd-engine/scene';
// Once per PSD (server, node adapter):
const { doc, assets } = extractScene(psd, createCanvas);
// → upload `assets` (canvases) + persist `doc` (SceneDoc JSON)
// Per render (browser or node):
const out = renderScene(doc, loadedAssets, { [faceKey]: artImage }, createCanvas);doc.warnings flags blend modes the Canvas-2D mapping can't reproduce 1:1 — a hint to fall back to the full server compose.
License
MIT
