Image annotation predates digital forms and remains common on paper. People draw on printed diagrams, floorplans, or body outlines to communicate details that are hard to express with text alone. This practice is still widespread in many industries:
Digital forms can enhance this experience by taking advantage of touchscreen input, zooming and panning for precision, color selection for clarity, and the ability to undo mistakes. These improvements make annotation faster, more accurate, and easier to review - especially when submissions are part of a structured workflow.
The signature question type in SurveyJS is typically used for capturing handwritten consent or approvals - think delivery confirmations, patient intake forms, or internal sign-offs. But its capabilities go far beyond signatures.
While SurveyJS doesn’t include a dedicated image annotation widget, the signature pad effectively serves that role. With support for background images and auto-resizing, it can be used as a lightweight annotation tool - no extra coding required. Simply set a background image (like a floorplan or body outline), and users can draw directly over it.
Beyond that, the component includes several features that enhance the drawing experience:
With just a few property tweaks, the signature pad becomes a surprisingly versatile tool for collecting visual input.
SurveyJS supports composite (or panel-based) custom questions, which allow you to group multiple questions into a reusable component with its own behavior and appearance. This makes it easy to build more complex input types that go beyond the built-in widgets.
In this example, we’ll create a custom image annotation question using two parts:
This way, users can upload any image and immediately annotate it - no need for a separate image editor or tool.
ComponentCollection.Instance.add({
name: "annotatedImage",
title: "Image Annotation",
elementsJSON: [
{
type: "file",
name: "imageUpload",
storeDataAsText: true,
acceptedTypes: "image/*",
sourceType: "file-camera",
showPreview: false,
},
{
type: "signaturepad",
name: "signature",
visible: false,
signatureWidth: 400,
signatureHeight: 300,
}
],
onValueChanged: async (question, name, newValue) => {
if (name === "imageUpload" && newValue?.length > 0) {
const imageData = newValue[0].content;
const signatureQuestion = question.contentPanel.getQuestionByName("signature");
const uploadQuestion = question.contentPanel.getQuestionByName("imageUpload");
// Set the uploaded image to the backround of the signature pad
signatureQuestion.backgroundImage = imageData;
// Reveal the signature pad and hide the original image upload
signatureQuestion.visible = true;
uploadQuestion.visible = false;
}
}
});
In the definition of the file upload part of our custom question type we are using two important parameters: acceptedTypes: "image/*"
and sourceType: "file-camera"
. The first one instructs the file browser to allow only extension of image files to be selected. The second one provides to option to take a picture with the device’s camera, if one is available. For more information on how you can use them, check out our video tutorial How to Build Forms with Photo & Video Capture Using SurveyJS and Endatix
One limitation of this approach is that the signature pad has a fixed size. When images with a different aspect ratio are uploaded, this can lead to clipping or other unexpected behavior. To address this, we can add a function that checks the dimensions of the uploaded image and resizes the signature pad accordingly.
function getImageSize(base64: string) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
let width = img.width;
let height = img.height;
if (width > 800 || height > 800) {
const scale = 800 / Math.max(width, height);
width = Math.round(width * scale);
height = Math.round(height * scale);
}
resolve({ width, height });
};
img.onerror = reject;
img.src = base64;
});
}
We need to call this function before we change the visibility of the signature pad in our custom question type, and set its size like this:
const size: any = await getImageSize(imageData);
signatureQuestion.signatureWidth = size.width;
signatureQuestion.signatureHeight = size.height;
By enabling users to annotate the actual image they just uploaded—whether it’s a vehicle, a building, or a medical scan—this approach adds real value to workflows that depend on visual context. It’s more accurate, easier to interpret, and better aligned with real-world tasks than marking up a generic template.
The Endatix Form Management platform lets you define and package your own custom questions, like the image annotation example shown above. These can then be reused by business users or end customers when creating forms - no coding required. This allows teams to standardize complex inputs across workflows while keeping the form-building experience simple and consistent.
We offer expert advice on architecture, provide training for SurveyJS and the Endatix backend, and assist with development and implementation of your solution. Feel free to contact us—we're passionate about software and always happy to chat!