Used to create a custom transform extension.
Example
Below we use the createTransformExtension function to create an image editor extension powered by Pintura.
To further improve the media uploading experience we can combine this extension with the MediaResolutionValidator and ImageBitmapTransform extensions.
import { defineFilePond, createTransformExtension } from 'filepond';
import { locale } from 'filepond/locales/en-gb.js';
import { createFilePondEntryList, appendEntryImageView } from 'filepond/templates/index.js';
import { ConsoleView } from 'filepond/extensions/console-view.js';
// helper function to load stylesheets
function link(src) {
return new Promise((resolve) => {
// already added this link
if (document.querySelector(`link[href="${src}"]`)) {
resolve();
return;
}
// new link
const link = document.createElement('link');
link.rel = 'stylesheet';
link.onload = resolve;
link.href = src;
document.head.append(link);
});
}
// our custom transform
const PinturaTransform = createTransformExtension(
// The name of our extension
'PinturaTransform',
// Default settings
{
actionTransform: 'editMedia',
},
// Extension internals, these are used by `createTransformExtension`
({ extensionName }) => ({
// The `canTransformEntry` is called to test if we can transform an image
// Here we use a cheap, but not always accurate, method to test if an entry can be transformed
canTransformEntry: (entry) => /video|image/.test(entry.type),
// Use the `prepareTransformEntry` hook to preload dependencies
prepareTransformEntry: async (entry, { onprogress, abortController }) => {
// load styles
await link('https://unpkg.com/@pqina/pintura@8/pintura.css');
// load scripts
await import('@pqina/pintura');
},
// The `transformEntry` function is called when we're ready to transform an entry
transformEntry: async (entry, { onprogress, abortController }) => {
// @pqina/pintura should be cached, so it's instantly available now
const { openDefaultEditor } = await import('@pqina/pintura');
// Get props
const { file, extension } = entry;
const { input, history = [] } = extension[extensionName];
// Determine which file to edit
const src = input || file;
// Open the file in the editor
const editor = openDefaultEditor({
src,
// We require a square crop
imageCropAspectRatio: 1,
});
// Restore any previously stored history state
if (history.length) {
editor.on('load', () => {
editor.history.write(history.pop());
});
}
// Returns the edited file and its image state
const { dest, imageState } = await new Promise((resolve) => {
editor.on('process', resolve);
editor.on('close', () =>
resolve({
// We don't return a result
})
);
});
// clean up the editor
editor.destroy();
// User closed the editor
if (!dest) {
return;
}
// Return transformed file and optionally update history
return {
file: dest,
history: [...history, imageState],
};
},
})
);
// Add image view to default template
const template = createFilePondEntryList();
appendEntryImageView(template);
// Now we can use `PinturaTransform` like this
const elements = defineFilePond({
locale,
// Load extensions
extensions: [PinturaTransform, ConsoleView],
// Pass custom template to EntryListView
EntryListView: {
template,
},
});