Polotno-node
Export Polotno JSON into images and pdf files. NodeJS package to work with Polotno Store API.
Should work fine with lambda functions as well.
Usage
npm install polotno-node
const fs = require('fs');
const { createInstance } = require('polotno-node');
async function run() {
const instance = await createInstance({
key: 'nFA5H9elEytDyPyvKL7T',
});
const json = JSON.parse(fs.readFileSync('polotno.json'));
const imageBase64 = await instance.jsonToImageBase64(json);
fs.writeFileSync('out.png', imageBase64, 'base64');
instance.close();
}
run();
API
createInstance(options)
Create working instance of Polotno Node.
const { createInstance } = require('polotno-node');
const instance = await createInstance({
key: 'nFA5H9elEytDyPyvKL7T',
useParallelPages: false,
url: 'https://yourappdomain.com/client',
browser: browser,
});
instance.jsonToDataURL(json, attrs)
Export json into data URL.
const json = JSON.parse(fs.readFileSync('polotno.json'));
const url = await instance.jsonToDataURL(json);
res.json({ url });
for (const page of json.pages) {
const url = await instance.jsonToDataURL(
{ ...json, pages: [page] },
{ pageId: page.id }
);
}
instance.jsonToImageBase64(json, attrs)
Export json into base64 string of image.
const json = JSON.parse(fs.readFileSync('polotno.json'));
const imageBase64 = await instance.jsonToImageBase64(json, {
mimeType: 'image/png',
});
fs.writeFileSync('out.png', imageBase64, 'base64');
for (const page of json.pages) {
const imageBase64 = await instance.jsonToImageBase64(
{ ...json, pages: [page] },
{ pageId: page.id }
);
}
instance.jsonToPDFBase64(json, attrs)
Export json into base64 string of pdf file.
const json = JSON.parse(fs.readFileSync('polotno.json'));
const pdfBase64 = await instance.jsonToPDFBase64(json);
fs.writeFileSync('out.pdf', pdfBase64, 'base64');
instance.jsonToPDFDataURL(json, attrs)
Export json into data url of pdf file.
const json = JSON.parse(fs.readFileSync('polotno.json'));
const url = await instance.jsonToPDFDataURL(json);
res.json({ url });
instance.run()
Run any Polotno store API directly inside web-page context.
Warning: by default every run
and every export function will create a new page with its own editor and context. If you want to make and export after you use instance.run()
you must do it inside the same run
function.
const url = await instance.run(async (json) => {
window.config.addGlobalFont({
name: 'MyCustomFont',
url: 'https://example.com/font.otf',
});
store.loadJSON(json);
await store.waitLoading();
return store.toDataURL();
}, json);
window.config
usage
window.config
is a global object that has some functions from polotno/config
module. You can use it to add custom fonts and customize some settings.
Not all options are supported yet. If you see anything missing, please create an issue. You can see all available options in client.js
file.
You should be able to change config before you call store.loadJSON
function and do you export.
const url = await instance.run(async (json) => {
window.config.unstable_setTextVerticalResizeEnabled(true);
store.loadJSON(json);
return store.toDataURL();
}, json);
Your own client
By default polotno-node
ships with the default Polotno Editor with its (hopefully) last version. If you use experimental API such as unstable_registerShapeModel
and unstable_registerShapeComponent
, the rendering may fail if you use unknown elements types.
In that case you can use your own client editor. You need to create a public html page with store
as global variable and mount just <Workspace />
component from polotno/canvas
module. Take a look into client.html
file and client.js
file in this repo as a demo. In your own version of the Editor you can use experimental API to define custom components.
Pass url
option to createInstance
function with public url of your client editor.
**Note: you will have to maintain the last version of your client editor by yourself. Better to keep using the last **
const { createInstance } = require('polotno-node');
const instance = await createInstance({
key: 'KEY',
url: 'https://yourappdomain.com/client',
});
Browserless usage
By default polotno-node
will import browser bundle using chrome-aws-lambda
. But you can use browserless
instead, to keep your cloud function smaller.
const { createInstance } = require('polotno-node/instance');
const puppeteer = require('puppeteer');
const instance = await createInstance({
key: 'nFA5H9elEytDyPyvKL7T',
browser: await puppeteer.connect({
browserWSEndpoint: 'wss://chrome.browserless.io?token=API_KEY',
}),
});
Troubleshooting
If you have an error like this
Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"Error: Evaluation failed: ReferenceError: store is not defined\n at __puppeteer_evaluation_script__:3:9"
It may mean that Polotno Client Editor was not loaded in puppeteer
instance. It is possible that you are missing required files in node_modules
folder. I got this error when I was trying to run polotno-node
on Vercel. To fix the issue you need to add this config into vercel.json
:
"functions": {
"api/render.js": { // remember to replace this line with your function name
"includeFiles": "node_modules/polotno-node/**"
},
}