Skip to content

Apply a circular mask on save

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)