This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
jQuery Image Annotation Plugin - creates Flickr-like comment annotations on images embedded in web pages. Users can draw rectangular regions on images, add text notes, and save/load annotations via AJAX or static data. Licensed under GNU GPL v2.
Runtime dependencies: jQuery 3.x/4.x.
# Install all dependencies
npm install
# Build (type-check, bundle core + jQuery adapters, minify CSS)
npm run build
# Type-check only (no emit)
npm run build:check
# Clean dist directory only
npm run clean
# Run tests
npm test
# Run tests against jQuery 4
npm run test:jquery4The plugin is written in TypeScript with vanilla DOM internals. jQuery is only used in the thin adapter layer (src/jquery.annotate.ts) that registers $.fn.annotateImage. Drag/resize uses vanilla pointer events (src/interactions.ts).
src/
index.ts - Core entry point (annotate() factory, type exports)
types.ts - Shared interfaces (AnnotationNote, AnnotateImageOptions, InteractionHandlers)
annotate-image.ts - AnnotateImage class (canvas, load/save, hover, add note, destroy)
annotate-edit.ts - AnnotateEdit class (edit mode, drag/resize area, form, save/delete/cancel)
annotate-view.ts - AnnotateView class (annotation display, hover, click-to-edit)
interactions.ts - Vanilla drag/resize via pointer events (InteractionHandlers)
jquery.annotate.ts - jQuery adapter ($.fn.annotateImage registration + destroy dispatch)
annotation.css - Plugin styles (icons are inline SVG data URIs)
demo/
static.html - Demo with hardcoded annotations
ajax.html - Demo with AJAX endpoints
fixtures/ - Mock AJAX endpoint files (get.json, save.json, delete.json)
images/ - Demo-only images
test/ - Vitest test suite
dist/ - Built output (gitignored)
docs/ - Migration plans and design documents
AnnotateImage(src/annotate-image.ts) — Orchestrates the plugin. Wraps the target image in a canvas div with view/edit overlays (image provides intrinsic sizing, overlays use CSSinset: 0). Loads annotations (static or viafetch), manages mode switching, creates icon-only "Add Note" button inside the canvas (hover-to-show, always visible on touch). Coordinates stored in natural image pixels;toRendered()/toNatural()convert between natural and scaled coordinates. Rescale is deferred during active edits. Instance stored via$(img).data('annotateImage').AnnotateEdit(src/annotate-edit.ts) — Edit mode. Manages the draggable/resizable area (via injectedInteractionHandlers), inline form with textarea, save/delete/cancel buttons. Usesapi.save/api.deletecallbacks for persistence.AnnotateView(src/annotate-view.ts) — View mode. Renders annotation area + tooltip, hover show/hide, click-to-edit for editable annotations. Helper functionsreadInlinePosition/readInlineSizeread from inline styles (jsdom-compatible).
src/index.ts is the vanilla entry point. It exports:
annotate(img, options?)— factory function, returnsAnnotateImageinstanceAnnotateImageclass (for typing/instanceof)AnnotationNote,AnnotateImageOptionstypes
Unified defaults (both core and jQuery): editable: true, notes: [], autoResize: true.
src/jquery.annotate.ts is the jQuery entry point. It:
- Registers
$.fn.annotateImage(options)which creates anAnnotateImageinstance - Supports method dispatch:
$(img).annotateImage('destroy') - Stores the instance via
$(img).data('annotateImage')
{
editable: true, // Enable editing
notes: [], // Static annotation data
api?: { // Server persistence (omit for static-only mode)
load: string | (() => Promise<AnnotationNote[]>),
save: string | ((note: NoteData) => Promise<SaveResult>),
delete: string | ((note: NoteData) => Promise<void>),
},
labels?: { // Configurable button labels (omit for English defaults)
addNote?: string, // default: "Add Note"
save?: string, // default: "OK"
delete?: string, // default: "Delete"
cancel?: string, // default: "Cancel"
placeholder?: string // default: "" (no placeholder)
},
autoResize?: boolean, // Re-scale on container resize (default: true)
onError?: (context: AnnotateErrorContext) => void,
}Each api field accepts either a URL string (shorthand for default fetch) or a function (full control). Omitting api entirely means static mode — no network calls.
{ top: number, left: number, width: number, height: number, text: string, id: string, editable: boolean }dist/ contains the built artifacts (gitignored):
dist/core.js— Core library (ESM, no dependencies)dist/core.min.js— Core library (IIFE, minified,AnnotateImageglobal)dist/jquery.js— jQuery adapter (ESM, jQuery external)dist/jquery.min.js— jQuery adapter (IIFE, minified, jQuery external)dist/css/annotate.min.css— Minified styles (icons embedded as SVG data URIs)dist/types/— TypeScript declaration files (.d.ts)
Package exports: "." (core), "./jquery" (jQuery adapter), "./css" (styles).
All classes are prefixed image-annotate- (e.g., .image-annotate-canvas, .image-annotate-view, .image-annotate-edit, .image-annotate-area, .image-annotate-note).