Color palette
Canvas tools
Layer controls
Installation
Copy and paste the following code into your project.
components/ui/canvas-annotations.tsx
import React from "react";
import { cn } from "@/lib/utils";
export interface CanvasAnnotationsProps
extends React.HTMLAttributes<HTMLDivElement> {
annotations?: Array<{
id: string;
x: number;
y: number;
content: React.ReactNode;
}>;
onAnnotationClick?: (id: string) => void;
}
export function CanvasAnnotations({
annotations = [],
onAnnotationClick,
className,
...props
}: CanvasAnnotationsProps) {
return (
<div className={cn("relative h-full w-full", className)} {...props}>
{annotations.map(({ id, x, y, content }) => (
<div
key={id}
className="absolute inline-flex cursor-pointer items-center justify-center"
style={{
left: `${x}%`,
top: `${y}%`,
transform: "translate(-50%, -50%)",
}}
onClick={() => onAnnotationClick?.(id)}
>
<div className="relative">
<div className="absolute -inset-1 animate-ping rounded-full bg-primary/50 opacity-75" />
<div className="relative rounded-full bg-primary p-1" />
</div>
<div className="ml-2 rounded-md bg-muted/95 px-2 py-1 text-sm shadow-md">
{content}
</div>
</div>
))}
</div>
);
}
Update the import paths to match your project setup.
import { CanvasAnnotations } from "@/components/ui/canvas-annotations";
Usage
import { CanvasAnnotations } from "@/components/ui/canvas-annotations";
export function AnnotatedImage() {
const annotations = [
{
id: "1",
x: 25,
y: 30,
content: "Important detail here",
},
{
id: "2",
x: 75,
y: 60,
content: "Another feature",
},
];
return (
<div className="relative h-[500px] w-full">
<img src="/your-image.jpg" className="h-full w-full object-cover" />
<CanvasAnnotations
annotations={annotations}
onAnnotationClick={(id) => {
console.log(`Annotation ${id} clicked`);
}}
/>
</div>
);
}
Features
- Add interactive annotation markers to any canvas, image, or container
- Customizable annotation content using React nodes
- Animated ping effect for better visibility
- Click handling for interactive annotations
- Fully responsive and works with any container size
- Tailwind CSS classes for easy styling customization