Objective
The feature allows users to draw and pin annotations on an image. The objective is to provide an interactive and collaborative tool for marking and annotating floor plans, blueprints, or images in a web application.
Where It Can Be Used
In many applications, users need the ability to annotate images by adding pins or drawing freehand. This feature is useful in industries such as real estate, construction, and education, where users need to highlight specific areas of an image dynamically. This component integrates image zooming, panning, pinning, and drawing functionalities.
Step-by-Step Explanation
- Image Loading and Resizing
The image is loaded dynamically and resized based on the viewport to maintain a responsive design and user accessibility across devices. - Zoom and Pan (Using
react-zoom-pan-pinch)
This package provides built-in functionality for pinch-to-zoom and dragging (panning) on both mobile and desktop environments. Wrapping the image inTransformWrapperandTransformComponentallows users to zoom in/out and move the image freely without disrupting annotations.
<TransformWrapper>
<TransformComponent>
<img src="image.jpg" alt="Annotatable" />
</TransformComponent>
</TransformWrapper>
- Pin Placement and Management
When the user clicks on the image in pin mode, a pin is placed at the clicked location using cursor coordinates relative to the image position. Each pin is stored in a state array.
const handleImageClick = (e) => {
if (mode === 'pin') {
const rect = imageRef.current.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
setPins([...pins, { x, y, id: Date.now() }]);
}
};
- Drawing Mode (Using
ReactSketchCanvas)
Allows users to draw on the image freely. Users can choose stroke color, and each stroke is rendered over the image using canvas layers.
<ReactSketchCanvas
ref={canvasRef}
strokeColor={selectedColor}
strokeWidth={4}
/>
- Eraser and Reset
Users can switch to eraser mode to remove specific strokes or clear the entire canvas to reset the drawing.
canvasRef.current.eraseMode(true); // Enable eraser
canvasRef.current.clearCanvas(); // Clear all drawings
- Undo/Redo Feature
Provides control over annotation history by allowing users to undo or redo actions.
canvasRef.current.undo();
canvasRef.current.redo();
- Save and Load Annotations
Pins and drawing paths are serialized and saved (e.g., inlocalStorage), allowing users to return later and restore their work.
const saveAnnotations = async () => {
const paths = await canvasRef.current.exportPaths();
localStorage.setItem('annotations', JSON.stringify({ pins, paths }));
};
const loadAnnotations = async () => {
const data = JSON.parse(localStorage.getItem('annotations'));
setPins(data.pins);
canvasRef.current.loadPaths(data.paths);
};
- State Management
ReactuseStatemanages the drawing mode, pin list, and current drawing attributes. This ensures real-time UI updates and user interactivity. - UI Controls
A set of buttons allows toggling between drawing and pinning modes, clearing the canvas, and switching to eraser mode.
<button onClick={() => setMode('draw')}>Draw</button>
<button onClick={() => setMode('pin')}>Pin</button>
<button onClick={() => canvasRef.current.clearCanvas()}>Reset</button>
Resources Needed
react-zoom-pan-pinchfor zooming and panning.ReactSketchCanvasfor drawing.- Image assets for pin icons and UI controls.
Findings/Results
- The component successfully integrates pinning and drawing on images.
- The zoom and pan functionalities work as expected without interfering with annotations.
- The undo, redo, erase and reset functionality improves user experience.
- Saving and loading annotations enhance workflow efficiency.
Documentation and References
react-zoom-pan-pinchdocumentation: https://www.npmjs.com/package/react-zoom-pan-pinchReactSketchCanvasdocumentation: https://www.npmjs.com/package/react-sketch-canvas- React official documentation: https://react.dev/