If you want to apply the circular mask to the image upon saving so you do not need to bother with border-radius, you can use this code snippet instead.
// Apply circular mask to saved image.
gform.addFilter('image_hopper_filepond_config', function (config, FilePond, $form, currentPage, formId, fieldId, entryId, files, inputField) {
config.imageEditor.editorOptions.willRenderCanvas = function(shapes, state) {
const {
utilVisibility,
selectionRect,
lineColor,
backgroundColor,
} = state;
// Exit if crop utils is not visible
if (utilVisibility.crop <= 0) return shapes;
// Get variable shortcuts to the crop selection rect
const { x, y, width, height } = selectionRect;
return {
// Copy all props from current shapes
...shapes,
// Now we add an inverted ellipse shape to the interface shapes array
interfaceShapes: [
{
x: x + width * 0.5,
y: y + height * 0.5,
rx: width * 0.5,
ry: height * 0.5,
opacity: utilVisibility.crop,
inverted: true,
backgroundColor: [...backgroundColor, 0.5],
strokeWidth: 1,
strokeColor: [...lineColor],
},
// Spread all existing interface shapes onto the array
...shapes.interfaceShapes,
],
}
}
config.imageEditor.imageWriter[1].postprocessImageData = (imageData) =>
new Promise((resolve) => {
// Create a canvas element to handle the imageData
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
// Only draw image where we render our circular mask
ctx.globalCompositeOperation = 'destination-in';
// Draw our circular mask
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(
imageData.width * 0.5,
imageData.height * 0.5,
imageData.width * 0.5,
0,
2 * Math.PI
);
ctx.fill();
// Returns the modified imageData
resolve(
ctx.getImageData(0, 0, canvas.width, canvas.height)
);
})
return config
}, 20)