web-annotation-renderer 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +89 -4
  2. package/README.md +248 -120
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +35 -32
  6. package/dist/index.js.map +1 -1
  7. package/dist/index10.cjs +1 -1
  8. package/dist/index10.js +1 -1
  9. package/dist/index11.cjs +1 -1
  10. package/dist/index11.js +1 -1
  11. package/dist/index12.cjs +1 -1
  12. package/dist/index12.cjs.map +1 -1
  13. package/dist/index12.js +48 -170
  14. package/dist/index12.js.map +1 -1
  15. package/dist/index13.cjs +1 -1
  16. package/dist/index13.cjs.map +1 -1
  17. package/dist/index13.js +170 -29
  18. package/dist/index13.js.map +1 -1
  19. package/dist/index14.cjs +1 -1
  20. package/dist/index14.cjs.map +1 -1
  21. package/dist/index14.js +28 -75
  22. package/dist/index14.js.map +1 -1
  23. package/dist/index15.cjs +1 -1
  24. package/dist/index15.cjs.map +1 -1
  25. package/dist/index15.js +72 -21
  26. package/dist/index15.js.map +1 -1
  27. package/dist/index16.cjs +1 -1
  28. package/dist/index16.cjs.map +1 -1
  29. package/dist/index16.js +21 -51
  30. package/dist/index16.js.map +1 -1
  31. package/dist/index17.cjs +1 -1
  32. package/dist/index17.cjs.map +1 -1
  33. package/dist/index17.js +49 -19
  34. package/dist/index17.js.map +1 -1
  35. package/dist/index18.cjs +1 -1
  36. package/dist/index18.cjs.map +1 -1
  37. package/dist/index18.js +22 -116
  38. package/dist/index18.js.map +1 -1
  39. package/dist/index19.cjs +1 -1
  40. package/dist/index19.cjs.map +1 -1
  41. package/dist/index19.js +83 -69
  42. package/dist/index19.js.map +1 -1
  43. package/dist/index20.cjs +1 -1
  44. package/dist/index20.cjs.map +1 -1
  45. package/dist/index20.js +103 -58
  46. package/dist/index20.js.map +1 -1
  47. package/dist/index21.cjs +1 -1
  48. package/dist/index21.cjs.map +1 -1
  49. package/dist/index21.js +56 -138
  50. package/dist/index21.js.map +1 -1
  51. package/dist/index22.cjs +1 -1
  52. package/dist/index22.cjs.map +1 -1
  53. package/dist/index22.js +139 -36
  54. package/dist/index22.js.map +1 -1
  55. package/dist/index23.cjs +1 -1
  56. package/dist/index23.cjs.map +1 -1
  57. package/dist/index23.js +35 -34
  58. package/dist/index23.js.map +1 -1
  59. package/dist/index24.cjs +1 -1
  60. package/dist/index24.cjs.map +1 -1
  61. package/dist/index24.js +27 -28
  62. package/dist/index24.js.map +1 -1
  63. package/dist/index25.cjs +1 -1
  64. package/dist/index25.cjs.map +1 -1
  65. package/dist/index25.js +38 -40
  66. package/dist/index25.js.map +1 -1
  67. package/dist/index26.cjs +1 -1
  68. package/dist/index26.cjs.map +1 -1
  69. package/dist/index26.js +39 -4
  70. package/dist/index26.js.map +1 -1
  71. package/dist/index27.cjs +1 -1
  72. package/dist/index27.cjs.map +1 -1
  73. package/dist/index27.js +5 -5
  74. package/dist/index27.js.map +1 -1
  75. package/dist/index28.cjs +2 -0
  76. package/dist/index28.cjs.map +1 -0
  77. package/dist/index28.js +8 -0
  78. package/dist/index28.js.map +1 -0
  79. package/dist/index29.cjs +2 -0
  80. package/dist/index29.cjs.map +1 -0
  81. package/dist/index29.js +8 -0
  82. package/dist/index29.js.map +1 -0
  83. package/dist/index5.cjs +1 -1
  84. package/dist/index5.js +5 -5
  85. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,87 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.3] - 2025-01-20
9
+
10
+ ### Fixed
11
+
12
+ - Documentation updates to reflect current implementation
13
+ - Removed outdated ink annotation references from README
14
+ - Updated ARCHITECTURE.md to document StrokeRenderer-based architecture
15
+ - Fixed AI_TOOLS_README.md to match actual exported functions
16
+
17
+ ## [0.5.0] - 2025-01-15
18
+
19
+ ### Added
20
+
21
+ - New annotation types: `underline`, `arrow`, `circle`
22
+ - `underlineToStrokes` converter for underline annotations
23
+ - `arrowToStrokes` converter for arrow annotations with arrowhead
24
+ - `circleToStrokes` converter for circle/ellipse annotations
25
+
26
+ ### Changed
27
+
28
+ - **BREAKING:** Removed `ink` annotation type
29
+ - Text annotations now use single-stroke font for hand-written style
30
+ - Text animations are now character-by-character instead of word-by-word
31
+
32
+ ### Removed
33
+
34
+ - `ink` annotation type and related converter
35
+ - `create_ink_annotation` AI tool schema
36
+
37
+ ## [0.4.0] - 2025-01-10
38
+
39
+ ### Added
40
+
41
+ - `StrokeRenderer` - Unified canvas-based annotation renderer
42
+ - Converter architecture for annotation-to-stroke transformation
43
+ - Support for custom converters via `registerConverter()`
44
+ - Variable-width stroke rendering with pressure simulation
45
+ - High-DPI display support in StrokeRenderer
46
+
47
+ ### Changed
48
+
49
+ - **BREAKING:** Replaced DOM-based layer rendering with canvas-based StrokeRenderer
50
+ - All annotation types now render through unified stroke pipeline
51
+ - Improved progressive animation with endpoint interpolation
52
+
53
+ ### Removed
54
+
55
+ - `LayerManager` class (replaced by StrokeRenderer)
56
+ - `HighlightLayer`, `TextLayer`, `DrawingLayer` classes
57
+ - DOM-based annotation rendering
58
+
59
+ ## [0.3.0] - 2025-01-05
60
+
61
+ ### Added
62
+
63
+ - `textToStrokes` converter using single-stroke font library
64
+ - Single-stroke font JSON data for Latin characters
65
+ - Path subdivision for smoother text animation
66
+ - `uniformScale` support for aspect-ratio preserving text
67
+
68
+ ### Changed
69
+
70
+ - Text annotations render as strokes instead of DOM elements
71
+ - Improved text animation timing with path-aware duration
72
+
73
+ ## [0.2.0] - 2025-12-20
74
+
75
+ ### Added
76
+
77
+ - OpenAI function calling schemas for AI-generated annotations
78
+ - `create_highlight_annotation` tool
79
+ - `create_text_annotation` tool
80
+ - `handleToolCall()` and `handleToolCalls()` functions
81
+ - `createHighlight()` and `createText()` creator functions
82
+ - `sentence_ref` field for timing synchronization
83
+
84
+ ### Changed
85
+
86
+ - AI tools use normalized coordinate format (0-1)
87
+ - Improved validation for annotation parameters
88
+
8
89
  ## [0.1.0] - 2025-10-25
9
90
 
10
91
  ### Added
@@ -12,11 +93,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
93
  - Initial release of @ai-annotator/renderer
13
94
  - Framework-agnostic core rendering engine
14
95
  - PDF rendering with pdf.js integration
15
- - Timeline synchronization system
96
+ - Timeline synchronization system (TimelineSync)
16
97
  - React adapter component (AnnotPdf)
17
98
  - Support for highlight annotations with progressive reveal
18
- - Support for text box annotations with word-by-word reveal
19
- - Support for ink/drawing annotations with progressive strokes
99
+ - Support for text box annotations
100
+ - Support for ink/drawing annotations (later removed in 0.5.0)
20
101
  - Coordinate utilities for normalized positioning
21
102
  - Viewport utilities for responsive rendering
22
103
  - Type validators for annotation data
@@ -25,10 +106,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
106
 
26
107
  ### Features
27
108
 
28
- - Automatic worker configuration (zero config for consumers)
29
109
  - Tree-shakeable exports
30
110
  - Source maps for debugging
31
111
  - TypeScript-friendly JSDoc annotations
32
112
  - Comprehensive error handling
33
113
 
114
+ [0.5.3]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.5.0...v0.5.3
115
+ [0.5.0]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.4.0...v0.5.0
116
+ [0.4.0]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.3.0...v0.4.0
117
+ [0.3.0]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.2.0...v0.3.0
118
+ [0.2.0]: https://github.com/jhl72e/pdfAutoAnnotator/compare/v0.1.0...v0.2.0
34
119
  [0.1.0]: https://github.com/jhl72e/pdfAutoAnnotator/releases/tag/v0.1.0
package/README.md CHANGED
@@ -11,14 +11,15 @@ This library renders structured annotation data (highlights, text boxes, drawing
11
11
 
12
12
  - 📄 **PDF Rendering** - Built on pdf.js for reliable PDF display
13
13
  - ⏱️ **Timeline Synchronization** - Sync annotations with audio/video playback or manual controls
14
- - 🎨 **Multiple Annotation Types** - Highlights, text boxes, and ink drawings
14
+ - 🎨 **Multiple Annotation Types** - Highlights, text, underlines, arrows, and circles
15
+ - 🌏 **Multilingual Text** - Full support for Latin, Korean (11,172 syllables), and CJK characters
15
16
  - ⚛️ **Framework Agnostic** - Core engine works with any framework
16
17
  - ⚛️ **React Adapter** - Ready-to-use React component included
17
18
  - 🎯 **Progressive Animations** - Smooth reveal animations based on timeline
18
19
  - 🎬 **Continuous Sync** - Built-in support for real-time audio/video synchronization
19
20
  - 📦 **Simple Setup** - One-line worker configuration
20
21
  - 🌲 **Tree-shakeable** - Import only what you need
21
- - ⚡ **Performance Optimized** - Efficient rendering without unnecessary re-draws
22
+ - ⚡ **Performance Optimized** - Efficient canvas-based rendering with StrokeRenderer
22
23
 
23
24
  ## Installation
24
25
 
@@ -245,6 +246,81 @@ function VideoSyncViewer() {
245
246
 
246
247
  **For manual controls** (sliders, buttons), simply use `renderer.setTime()` or the `currentTime` prop - continuous sync is not needed.
247
248
 
249
+ ## Multilingual Text Support
250
+
251
+ The library supports hand-written style text rendering for multiple languages using single-stroke fonts.
252
+
253
+ ### Supported Languages
254
+
255
+ | Language | Unicode Range | Characters | Loading | Status |
256
+ |----------|---------------|------------|---------|--------|
257
+ | **Latin** | `U+0000-007F` | 78 (A-Z, a-z, 0-9, punctuation) | Bundled | ✅ Ready |
258
+ | **Korean** | `U+AC00-D7A3` | 11,172 (가-힣, all syllables) | Bundled | ✅ Ready |
259
+ | **CJK (Chinese/Japanese Kanji)** | `U+4E00-9FFF` | 20,976 | Dynamic | ⚠️ Requires preload |
260
+
261
+ ### Bundle Size
262
+
263
+ | Configuration | Size (gzip) |
264
+ |---------------|-------------|
265
+ | Core + Latin | ~50 KB |
266
+ | Core + Latin + Korean | ~639 KB |
267
+ | CJK data (separate) | ~2 MB |
268
+
269
+ ### Using CJK Characters (Chinese/Japanese Kanji)
270
+
271
+ CJK character data is **not bundled** by default due to its large size (~10MB uncompressed). You must preload it before rendering CJK text.
272
+
273
+ #### Step 1: Serve the CJK data file
274
+
275
+ Copy `node_modules/web-annotation-renderer/public/cjk.json` to your public assets folder.
276
+
277
+ #### Step 2: Preload before rendering
278
+
279
+ ```javascript
280
+ import { preloadCJK } from "web-annotation-renderer";
281
+
282
+ // Option 1: Default path (/cjk.json)
283
+ await preloadCJK();
284
+
285
+ // Option 2: Custom path
286
+ await preloadCJK("/assets/fonts/cjk.json");
287
+
288
+ // Now CJK characters will render correctly
289
+ renderer.setAnnotations([
290
+ {
291
+ id: "chinese-text",
292
+ type: "text",
293
+ page: 1,
294
+ start: 0,
295
+ end: 5,
296
+ content: "中文文字", // Chinese text
297
+ x: 0.1,
298
+ y: 0.2,
299
+ fontSize: 24,
300
+ },
301
+ ]);
302
+ ```
303
+
304
+ #### Important Notes
305
+
306
+ - **Without preloading:** CJK characters will silently fail to render (no error, just blank)
307
+ - **Preload timing:** Call `preloadCJK()` early in your app initialization
308
+ - **Caching:** The library caches CJK data after first load; subsequent calls are no-ops
309
+ - **Mixed text:** Latin and Korean render immediately; only CJK requires preloading
310
+
311
+ ### Unsupported Characters
312
+
313
+ The following character ranges are **not currently supported**:
314
+
315
+ | Type | Examples | Workaround |
316
+ |------|----------|------------|
317
+ | Extended Latin | é, ñ, ü, ø | Use ASCII equivalents |
318
+ | Korean Jamo | ㄱ, ㅏ, ㄴ | Use complete syllables (가, 나) |
319
+ | Japanese Hiragana/Katakana | あ, ア | Not supported |
320
+ | Emoji | 😀, 🎉 | Not supported |
321
+
322
+ Unsupported characters are skipped during rendering with default spacing.
323
+
248
324
  ## API Reference
249
325
 
250
326
  ### AnnotationRenderer Class
@@ -530,13 +606,13 @@ All annotations use **normalized coordinates** (0-1 range) for positioning, maki
530
606
 
531
607
  All annotation types share these base fields:
532
608
 
533
- | Field | Type | Required | Description |
534
- | ------- | ------ | -------- | ---------------------------------------------------- |
535
- | `id` | string | ✅ Yes | Unique identifier for the annotation |
536
- | `type` | string | ✅ Yes | Annotation type: `"highlight"`, `"text"`, or `"ink"` |
537
- | `page` | number | ✅ Yes | Page number (1-indexed) |
538
- | `start` | number | ✅ Yes | Timeline start time in seconds |
539
- | `end` | number | ✅ Yes | Timeline end time in seconds |
609
+ | Field | Type | Required | Description |
610
+ | ------- | ------ | -------- | ------------------------------------------------------------------------ |
611
+ | `id` | string | ✅ Yes | Unique identifier for the annotation |
612
+ | `type` | string | ✅ Yes | Annotation type: `"highlight"`, `"text"`, `"underline"`, `"arrow"`, or `"circle"` |
613
+ | `page` | number | ✅ Yes | Page number (1-indexed) |
614
+ | `start` | number | ✅ Yes | Timeline start time in seconds |
615
+ | `end` | number | ✅ Yes | Timeline end time in seconds |
540
616
 
541
617
  ---
542
618
 
@@ -603,7 +679,7 @@ Highlights rectangular regions on the PDF with progressive reveal animation.
603
679
 
604
680
  ### Text Annotations
605
681
 
606
- Display text boxes with progressive typing animation.
682
+ Display hand-written style text with progressive character-by-character animation using single-stroke fonts. Supports **Latin**, **Korean** (가-힣), and **CJK** characters (see [Multilingual Text Support](#multilingual-text-support)).
607
683
 
608
684
  **Type:** `"text"`
609
685
 
@@ -616,31 +692,27 @@ Display text boxes with progressive typing animation.
616
692
  page: 1,
617
693
  start: 3,
618
694
  end: 8,
619
- content: "This is the annotation text content",
620
- x: 0.5, // Left position (normalized)
621
- y: 0.2, // Top position (normalized)
622
- w: 0.3, // Width (normalized)
623
- h: 0.1, // Height (normalized)
695
+ content: "This is the annotation text",
696
+ x: 0.5, // Left position (normalized)
697
+ y: 0.2, // Top position (normalized)
698
+ fontSize: 16, // Font size in pixels
624
699
  style: {
625
- bg: "rgba(255, 255, 255, 0.95)", // Background color
626
- color: "#1f2937" // Text color
700
+ color: "rgba(220, 20, 60, 1.0)" // Text color
627
701
  }
628
702
  }
629
703
  ```
630
704
 
631
705
  **Fields:**
632
706
 
633
- | Field | Type | Required | Default | Description |
634
- | ------------- | ------ | -------- | ------------------------- | ------------------------------- |
635
- | `content` | string | ✅ Yes | - | Text to display |
636
- | `x` | number | ✅ Yes | - | Left position (0-1, normalized) |
637
- | `y` | number | ✅ Yes | - | Top position (0-1, normalized) |
638
- | `w` | number | ✅ Yes | - | Width (0-1, normalized) |
639
- | `h` | number | Yes | - | Height (0-1, normalized) |
640
- | `style.bg` | string | No | `"rgba(255,255,255,0.9)"` | Background color |
641
- | `style.color` | string | No | `"#1f2937"` | Text color |
707
+ | Field | Type | Required | Default | Description |
708
+ | ------------- | ------ | -------- | ---------------------------- | ------------------------------- |
709
+ | `content` | string | ✅ Yes | - | Text to display |
710
+ | `x` | number | ✅ Yes | - | Left position (0-1, normalized) |
711
+ | `y` | number | ✅ Yes | - | Top position (0-1, normalized) |
712
+ | `fontSize` | number | No | `16` | Font size in pixels |
713
+ | `style.color` | string | No | `"rgba(220, 20, 60, 1.0)"` | Text stroke color |
642
714
 
643
- **Animation:** Text appears word-by-word with a typing effect during the `start` to `end` timeline.
715
+ **Animation:** Text is drawn character-by-character using single-stroke font glyphs, creating a hand-written writing effect.
644
716
 
645
717
  **Example:**
646
718
 
@@ -651,102 +723,127 @@ Display text boxes with progressive typing animation.
651
723
  page: 1,
652
724
  start: 5.0,
653
725
  end: 12.0,
654
- content: "Important concept to remember",
726
+ content: "Important concept",
655
727
  x: 0.6,
656
728
  y: 0.4,
657
- w: 0.25,
658
- h: 0.08,
729
+ fontSize: 18,
659
730
  style: {
660
- bg: "rgba(255, 255, 200, 0.95)",
661
- color: "#0066cc"
731
+ color: "rgba(0, 100, 200, 1.0)"
662
732
  }
663
733
  }
664
734
  ```
665
735
 
666
736
  ---
667
737
 
668
- ### Ink Annotations
738
+ ### Underline Annotations
669
739
 
670
- Draw strokes/paths with progressive reveal animation.
740
+ Draw underlines beneath text regions with progressive reveal animation.
671
741
 
672
- **Type:** `"ink"`
742
+ **Type:** `"underline"`
673
743
 
674
744
  **Structure:**
675
745
 
676
746
  ```javascript
677
747
  {
678
- id: "ink-1",
679
- type: "ink",
748
+ id: "underline-1",
749
+ type: "underline",
680
750
  page: 1,
681
- start: 10,
682
- end: 15,
683
- strokes: [
684
- {
685
- color: "rgb(255, 0, 0)",
686
- size: 3,
687
- points: [
688
- { t: 0.0, x: 0.2, y: 0.5 },
689
- { t: 0.5, x: 0.3, y: 0.45 },
690
- { t: 1.0, x: 0.4, y: 0.5 }
691
- ]
692
- }
693
- ]
751
+ start: 0,
752
+ end: 2,
753
+ quads: [
754
+ { x: 0.1, y: 0.2, w: 0.8, h: 0.05 }
755
+ ],
756
+ style: { color: "rgba(0, 0, 255, 0.8)" }
694
757
  }
695
758
  ```
696
759
 
697
760
  **Fields:**
698
761
 
699
- | Field | Type | Required | Default | Description |
700
- | ------------------ | ------ | -------- | ----------- | ------------------------------------ |
701
- | `strokes` | Array | ✅ Yes | - | Array of stroke objects |
702
- | `strokes[].color` | string | No | `"#1f2937"` | CSS color for stroke |
703
- | `strokes[].size` | number | No | `3` | Line width in pixels |
704
- | `strokes[].points` | Array | ✅ Yes | - | Array of point objects |
705
- | `points[].t` | number | ✅ Yes | - | Time within stroke (0-1, normalized) |
706
- | `points[].x` | number | Yes | - | X position (0-1, normalized) |
707
- | `points[].y` | number | ✅ Yes | - | Y position (0-1, normalized) |
762
+ | Field | Type | Required | Default | Description |
763
+ | ------------- | ------ | -------- | ------------------------ | ------------------------------- |
764
+ | `quads` | Array | ✅ Yes | - | Array of quad objects |
765
+ | `quads[].x` | number | ✅ Yes | - | Left position (0-1, normalized) |
766
+ | `quads[].y` | number | ✅ Yes | - | Top position (0-1, normalized) |
767
+ | `quads[].w` | number | ✅ Yes | - | Width (0-1, normalized) |
768
+ | `quads[].h` | number | ✅ Yes | - | Height (0-1, normalized) |
769
+ | `style.color` | string | No | `"rgba(0, 0, 255, 0.8)"` | Underline color |
770
+
771
+ **Animation:** Underlines draw progressively at the bottom edge of each quad from left to right.
708
772
 
709
- **Important:**
773
+ ---
710
774
 
711
- - Each point **must have a `t` parameter** representing its position in time within the stroke (0-1 range)
712
- - The `t` values are used for progressive drawing animation
713
- - Points should be ordered by increasing `t` values
775
+ ### Arrow Annotations
714
776
 
715
- **Animation:** Strokes are drawn progressively based on the `t` parameter of each point during the `start` to `end` timeline.
777
+ Draw arrows pointing from source to target with progressive reveal animation.
716
778
 
717
- **Example:**
779
+ **Type:** `"arrow"`
780
+
781
+ **Structure:**
718
782
 
719
783
  ```javascript
720
784
  {
721
- id: "ink-1",
722
- type: "ink",
785
+ id: "arrow-1",
786
+ type: "arrow",
723
787
  page: 1,
724
- start: 8.0,
725
- end: 13.0,
726
- strokes: [
727
- {
728
- color: "rgb(255, 0, 0)",
729
- size: 2,
730
- points: [
731
- { t: 0.0, x: 0.2, y: 0.4 },
732
- { t: 0.25, x: 0.25, y: 0.38 },
733
- { t: 0.5, x: 0.3, y: 0.4 },
734
- { t: 0.75, x: 0.35, y: 0.42 },
735
- { t: 1.0, x: 0.4, y: 0.4 }
736
- ]
737
- },
738
- {
739
- color: "rgb(255, 0, 0)",
740
- size: 2,
741
- points: [
742
- { t: 0.0, x: 0.22, y: 0.45 },
743
- { t: 1.0, x: 0.38, y: 0.45 }
744
- ]
745
- }
746
- ]
788
+ start: 0,
789
+ end: 2,
790
+ from_x: 0.2,
791
+ from_y: 0.3,
792
+ to_x: 0.8,
793
+ to_y: 0.7,
794
+ style: { color: "rgba(255, 0, 0, 0.8)" }
795
+ }
796
+ ```
797
+
798
+ **Fields:**
799
+
800
+ | Field | Type | Required | Default | Description |
801
+ | ------------- | ------ | -------- | ------------------------ | --------------------------------- |
802
+ | `from_x` | number | ✅ Yes | - | Source x position (0-1) |
803
+ | `from_y` | number | ✅ Yes | - | Source y position (0-1) |
804
+ | `to_x` | number | ✅ Yes | - | Target x position (0-1) |
805
+ | `to_y` | number | ✅ Yes | - | Target y position (0-1) |
806
+ | `style.color` | string | No | `"rgba(255, 0, 0, 0.8)"` | Arrow color |
807
+
808
+ **Animation:** Line draws first (70% of duration), then arrowhead wings draw (30% of duration).
809
+
810
+ ---
811
+
812
+ ### Circle Annotations
813
+
814
+ Draw circles/ellipses with progressive reveal animation around the perimeter.
815
+
816
+ **Type:** `"circle"`
817
+
818
+ **Structure:**
819
+
820
+ ```javascript
821
+ {
822
+ id: "circle-1",
823
+ type: "circle",
824
+ page: 1,
825
+ start: 0,
826
+ end: 2,
827
+ cx: 0.5,
828
+ cy: 0.5,
829
+ rx: 0.1,
830
+ ry: 0.1,
831
+ style: { color: "rgba(255, 165, 0, 0.8)" }
747
832
  }
748
833
  ```
749
834
 
835
+ **Fields:**
836
+
837
+ | Field | Type | Required | Default | Description |
838
+ | ------------- | ------ | -------- | -------------------------- | ----------------------------- |
839
+ | `cx` | number | ✅ Yes | - | Center x position (0-1) |
840
+ | `cy` | number | ✅ Yes | - | Center y position (0-1) |
841
+ | `rx` | number | ✅ Yes | - | Horizontal radius (0-1) |
842
+ | `ry` | number | ✅ Yes | - | Vertical radius (0-1) |
843
+ | `style.color` | string | No | `"rgba(255, 165, 0, 0.8)"` | Circle color |
844
+
845
+ **Animation:** Circle draws progressively around the perimeter from 0° to 360°.
846
+
750
847
  ---
751
848
 
752
849
  ### Coordinate System
@@ -783,7 +880,7 @@ const annotations = [
783
880
  style: { color: "rgba(255, 255, 0, 0.4)" },
784
881
  },
785
882
 
786
- // Text
883
+ // Text (hand-written style)
787
884
  {
788
885
  id: "t1",
789
886
  type: "text",
@@ -793,32 +890,47 @@ const annotations = [
793
890
  content: "Key concept here",
794
891
  x: 0.6,
795
892
  y: 0.2,
796
- w: 0.25,
797
- h: 0.08,
798
- style: {
799
- bg: "rgba(255, 255, 255, 0.95)",
800
- color: "#0066cc",
801
- },
893
+ fontSize: 16,
894
+ style: { color: "rgba(220, 20, 60, 1.0)" },
802
895
  },
803
896
 
804
- // Ink
897
+ // Underline
805
898
  {
806
- id: "i1",
807
- type: "ink",
899
+ id: "u1",
900
+ type: "underline",
808
901
  page: 1,
809
- start: 6,
902
+ start: 5,
903
+ end: 7,
904
+ quads: [{ x: 0.1, y: 0.3, w: 0.4, h: 0.03 }],
905
+ style: { color: "rgba(0, 0, 255, 0.8)" },
906
+ },
907
+
908
+ // Arrow
909
+ {
910
+ id: "a1",
911
+ type: "arrow",
912
+ page: 1,
913
+ start: 7,
810
914
  end: 10,
811
- strokes: [
812
- {
813
- color: "rgb(255, 0, 0)",
814
- size: 3,
815
- points: [
816
- { t: 0.0, x: 0.2, y: 0.5 },
817
- { t: 0.5, x: 0.3, y: 0.45 },
818
- { t: 1.0, x: 0.4, y: 0.5 },
819
- ],
820
- },
821
- ],
915
+ from_x: 0.2,
916
+ from_y: 0.5,
917
+ to_x: 0.6,
918
+ to_y: 0.6,
919
+ style: { color: "rgba(255, 0, 0, 0.8)" },
920
+ },
921
+
922
+ // Circle
923
+ {
924
+ id: "c1",
925
+ type: "circle",
926
+ page: 1,
927
+ start: 10,
928
+ end: 13,
929
+ cx: 0.75,
930
+ cy: 0.4,
931
+ rx: 0.08,
932
+ ry: 0.06,
933
+ style: { color: "rgba(255, 165, 0, 0.8)" },
822
934
  },
823
935
  ];
824
936
  ```
@@ -846,10 +958,10 @@ Requires:
846
958
  **Solutions:**
847
959
 
848
960
  1. Check that highlight annotations include `mode: "quads"` field
849
- 2. Verify text annotations use `type: "text"` (not `"textBox"`)
850
- 3. Ensure ink annotation points have `t` parameter
851
- 4. Check browser console for validation warnings
852
- 5. Verify timeline position is within annotation `start`/`end` range
961
+ 2. Verify annotation `type` is one of: `"highlight"`, `"text"`, `"underline"`, `"arrow"`, `"circle"`
962
+ 3. Check browser console for validation warnings (unknown type warnings)
963
+ 4. Verify timeline position is within annotation `start`/`end` range
964
+ 5. Ensure coordinates are normalized (0-1 range)
853
965
 
854
966
  ### Worker errors
855
967
 
@@ -884,6 +996,21 @@ npm install --save-dev @types/react @types/react-dom
884
996
  - For manual controls (sliders, buttons): Use `renderer.setTime()` or the `currentTime` prop directly - the system is optimized for discrete updates
885
997
  - For audio/video: Use `timelineSync.startContinuousSync()` for smooth 60fps synchronization
886
998
 
999
+ ### CJK characters not rendering
1000
+
1001
+ **Symptoms:** Chinese or Japanese kanji characters appear blank while Latin and Korean text renders correctly
1002
+
1003
+ **Solution:** CJK data must be preloaded before rendering:
1004
+
1005
+ ```javascript
1006
+ import { preloadCJK } from "web-annotation-renderer";
1007
+
1008
+ // Call early in your app initialization
1009
+ await preloadCJK("/path/to/cjk.json");
1010
+ ```
1011
+
1012
+ See [Multilingual Text Support](#multilingual-text-support) for details.
1013
+
887
1014
  ## Migration Guide
888
1015
 
889
1016
  If you're upgrading from documentation examples that used the old format:
@@ -893,8 +1020,9 @@ If you're upgrading from documentation examples that used the old format:
893
1020
  1. **Package name:** `@ai-annotator/renderer` → `web-annotation-renderer`
894
1021
  2. **Method name:** `renderer.updateTimeline()` → `renderer.setTime()`
895
1022
  3. **Highlight annotations:** Must include `mode: "quads"` field
896
- 4. **Text annotations:** Use `type: "text"` (not `"textBox"`), `content` (not `text`), flat coordinates, and `style.bg`/`style.color`
897
- 5. **Ink annotations:** Use `strokes` (not `paths`), `size` (not `width`), and points must have `t` parameter
1023
+ 4. **Text annotations:** Now render as hand-written style using single-stroke font; use `fontSize` instead of `w`/`h`
1024
+ 5. **Ink annotations:** Removed in v0.5.0; use `arrow`, `underline`, or `circle` instead
1025
+ 6. **New annotation types:** `underline`, `arrow`, `circle` added in v0.5.0
898
1026
 
899
1027
  ### Quick Migration
900
1028
 
@@ -926,8 +1054,8 @@ Both examples include:
926
1054
  - PDF loading and rendering
927
1055
  - Page navigation and zoom controls
928
1056
  - Timeline slider with annotation synchronization
929
- - All three annotation types (highlight, text, ink)
930
- - Optimized rendering for smooth, flicker-free updates
1057
+ - All five annotation types (highlight, text, underline, arrow, circle)
1058
+ - Optimized canvas-based rendering for smooth, flicker-free updates
931
1059
 
932
1060
  **Use Cases:**
933
1061
  - **Manual timeline control** (sliders, buttons): Use `setTime()` for discrete updates
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index2.cjs"),l=require("./index3.cjs"),a=require("./index4.cjs"),s=require("./index5.cjs"),e=require("./index6.cjs"),c=require("./index7.cjs"),d=require("./index8.cjs"),r=require("./index9.cjs"),u=require("./index10.cjs"),T=require("./index11.cjs"),g=require("./index12.cjs"),q=require("./index13.cjs"),p=require("./index14.cjs"),S=require("./index15.cjs"),h=require("./index16.cjs"),k=require("./index17.cjs"),P=require("./index18.cjs"),A=require("./index19.cjs"),t=require("./index20.cjs"),o=require("./index21.cjs"),n=require("./index22.cjs"),R=require("./index23.cjs"),x=require("./index24.cjs"),y="1.0.0",m="web-annotation-renderer";exports.AnnotationRenderer=i.AnnotationRenderer;exports.PDFRenderer=l.PDFRenderer;exports.TimelineSync=a.TimelineSync;exports.StrokeRenderer=s.StrokeRenderer;exports.applyJitter=e.applyJitter;exports.applyPressure=e.applyPressure;exports.applyWobble=e.applyWobble;exports.deepMerge=e.deepMerge;exports.seededRandom=e.seededRandom;exports.coordinateUtils=c;exports.viewportUtils=d;exports.extractAllBlocks=r.extractAllBlocks;exports.extractMultiplePages=r.extractMultiplePages;exports.extractPDFBlocks=r.extractAllBlocks;exports.normalizeAnnotationArray=u.normalizeAnnotationArray;exports.TypeValidators=T;exports.AnnotPdf=g.default;exports.highlightToStrokes=q.highlightToStrokes;exports.textToStrokes=p.textToStrokes;exports.underlineToStrokes=S.underlineToStrokes;exports.arrowToStrokes=h.arrowToStrokes;exports.circleToStrokes=k.circleToStrokes;exports.GradualRenderer=P.default;exports.StrokeDrawer=A.default;exports.getPenPreset=t.getPreset;exports.getPenPresetNames=t.getPresetNames;exports.annotationTools=o.annotationTools;exports.getAnnotationTools=o.getAnnotationTools;exports.handleToolCall=n.handleToolCall;exports.handleToolCalls=n.handleToolCalls;exports.createHighlight=R.createHighlight;exports.createText=x.createText;exports.LIB_NAME=m;exports.VERSION=y;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index2.cjs"),i=require("./index3.cjs"),s=require("./index4.cjs"),c=require("./index5.cjs"),e=require("./index6.cjs"),d=require("./index7.cjs"),u=require("./index8.cjs"),r=require("./index9.cjs"),T=require("./index10.cjs"),g=require("./index11.cjs"),t=require("./index12.cjs"),p=require("./index13.cjs"),q=require("./index14.cjs"),h=require("./index15.cjs"),S=require("./index16.cjs"),k=require("./index17.cjs"),P=require("./index18.cjs"),A=require("./index19.cjs"),R=require("./index20.cjs"),o=require("./index21.cjs"),n=require("./index22.cjs"),l=require("./index23.cjs"),y=require("./index24.cjs"),x=require("./index25.cjs"),m="0.5.3",f="web-annotation-renderer";exports.AnnotationRenderer=a.AnnotationRenderer;exports.PDFRenderer=i.PDFRenderer;exports.TimelineSync=s.TimelineSync;exports.StrokeRenderer=c.StrokeRenderer;exports.applyJitter=e.applyJitter;exports.applyPressure=e.applyPressure;exports.applyWobble=e.applyWobble;exports.deepMerge=e.deepMerge;exports.seededRandom=e.seededRandom;exports.coordinateUtils=d;exports.viewportUtils=u;exports.extractAllBlocks=r.extractAllBlocks;exports.extractMultiplePages=r.extractMultiplePages;exports.extractPDFBlocks=r.extractAllBlocks;exports.normalizeAnnotationArray=T.normalizeAnnotationArray;exports.TypeValidators=g;exports.preloadCJK=t.preloadCJK;exports.setCJKDataUrl=t.setCJKDataUrl;exports.AnnotPdf=p.default;exports.highlightToStrokes=q.highlightToStrokes;exports.textToStrokes=h.textToStrokes;exports.underlineToStrokes=S.underlineToStrokes;exports.arrowToStrokes=k.arrowToStrokes;exports.circleToStrokes=P.circleToStrokes;exports.GradualRenderer=A.default;exports.StrokeDrawer=R.default;exports.getPenPreset=o.getPreset;exports.getPenPresetNames=o.getPresetNames;exports.annotationTools=n.annotationTools;exports.getAnnotationTools=n.getAnnotationTools;exports.handleToolCall=l.handleToolCall;exports.handleToolCalls=l.handleToolCalls;exports.createHighlight=y.createHighlight;exports.createText=x.createText;exports.LIB_NAME=f;exports.VERSION=m;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\n\n// ============================================================================\n// Pen Effects - Hand-Drawn Feel Utilities\n// ============================================================================\n\nimport {\n applyJitter,\n applyPressure,\n applyWobble,\n deepMerge,\n seededRandom\n} from './pen/effects.js';\n\nexport { applyJitter };\nexport { applyPressure };\nexport { applyWobble };\nexport { deepMerge };\nexport { seededRandom };\n\n// ============================================================================\n// Pen Module - Legacy Stroke Rendering (Retained for Compatibility)\n// ============================================================================\n\nimport { GradualRenderer, StrokeDrawer, getPreset, getPresetNames } from './pen/index.js';\n\nexport { GradualRenderer };\nexport { StrokeDrawer };\nexport { getPreset as getPenPreset };\nexport { getPresetNames as getPenPresetNames };\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nimport * as coordinateUtils from './utils/coordinateUtils.js';\nimport * as viewportUtils from './utils/viewportUtils.js';\n\nexport { coordinateUtils };\nexport { viewportUtils };\n\n// ============================================================================\n// PDF Extraction Utilities\n// ============================================================================\n\nimport { extractAllBlocks, extractMultiplePages } from './utils/pdfExtractor.js';\n\nexport { extractAllBlocks };\nexport { extractMultiplePages };\nexport { extractAllBlocks as extractPDFBlocks };\n\n// ============================================================================\n// Type Definitions & Validators\n// ============================================================================\n\nexport { normalizeAnnotationArray } from './types/validators.js';\nexport * as TypeValidators from './types/index.js';\n\n// ============================================================================\n// Framework Adapters\n// ============================================================================\n\nexport { AnnotPdf } from './adapters/index.js';\n\n// ============================================================================\n// AI Tools for Annotation Generation\n// ============================================================================\n\nexport {\n annotationTools,\n getAnnotationTools,\n handleToolCall,\n handleToolCalls,\n createHighlight,\n createText\n} from './ai-tools/index.js';\n\n// ============================================================================\n// Package Metadata\n// ============================================================================\n\nexport const VERSION = '1.0.0';\nexport const LIB_NAME = 'web-annotation-renderer';\n"],"names":["VERSION","LIB_NAME"],"mappings":"2rBA8HaA,EAAU,QACVC,EAAW"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["/**\n * @ai-annotator/renderer - Public API\n *\n * Single entry point for the Dynamic PDF Annotation Renderer library.\n * Exports all core subsystems, utilities, and types.\n *\n * @module @ai-annotator/renderer\n */\n\n// ============================================================================\n// Core Rendering Engine\n// ============================================================================\n\nimport { AnnotationRenderer } from './core/AnnotationRenderer.js';\nimport { PDFRenderer } from './core/PDFRenderer.js';\nimport { TimelineSync } from './core/TimelineSync.js';\n\nexport { AnnotationRenderer };\nexport { PDFRenderer };\nexport { TimelineSync };\n\n// ============================================================================\n// Stroke Renderer - Unified Canvas-Based Annotation Rendering\n// ============================================================================\n\nimport { StrokeRenderer } from './renderer/StrokeRenderer.js';\n\nexport { StrokeRenderer };\n\n// ============================================================================\n// Converters - Annotation to Stroke Conversion\n// ============================================================================\n\nimport {\n highlightToStrokes,\n textToStrokes,\n underlineToStrokes,\n arrowToStrokes,\n circleToStrokes\n} from './converters/index.js';\n\nexport { highlightToStrokes };\nexport { textToStrokes };\nexport { underlineToStrokes };\nexport { arrowToStrokes };\nexport { circleToStrokes };\n\n// ============================================================================\n// Pen Effects - Hand-Drawn Feel Utilities\n// ============================================================================\n\nimport {\n applyJitter,\n applyPressure,\n applyWobble,\n deepMerge,\n seededRandom\n} from './pen/effects.js';\n\nexport { applyJitter };\nexport { applyPressure };\nexport { applyWobble };\nexport { deepMerge };\nexport { seededRandom };\n\n// ============================================================================\n// Pen Module - Legacy Stroke Rendering (Retained for Compatibility)\n// ============================================================================\n\nimport { GradualRenderer, StrokeDrawer, getPreset, getPresetNames } from './pen/index.js';\n\nexport { GradualRenderer };\nexport { StrokeDrawer };\nexport { getPreset as getPenPreset };\nexport { getPresetNames as getPenPresetNames };\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nimport * as coordinateUtils from './utils/coordinateUtils.js';\nimport * as viewportUtils from './utils/viewportUtils.js';\n\nexport { coordinateUtils };\nexport { viewportUtils };\n\n// ============================================================================\n// PDF Extraction Utilities\n// ============================================================================\n\nimport { extractAllBlocks, extractMultiplePages } from './utils/pdfExtractor.js';\n\nexport { extractAllBlocks };\nexport { extractMultiplePages };\nexport { extractAllBlocks as extractPDFBlocks };\n\n// ============================================================================\n// Type Definitions & Validators\n// ============================================================================\n\nexport { normalizeAnnotationArray } from './types/validators.js';\nexport * as TypeValidators from './types/index.js';\n\n// ============================================================================\n// Framework Adapters\n// ============================================================================\n\nexport { AnnotPdf } from './adapters/index.js';\n\n// ============================================================================\n// AI Tools for Annotation Generation\n// ============================================================================\n\nexport {\n annotationTools,\n getAnnotationTools,\n handleToolCall,\n handleToolCalls,\n createHighlight,\n createText\n} from './ai-tools/index.js';\n\n// ============================================================================\n// Multilingual Text Support\n// ============================================================================\n\nexport { preloadCJK, setCJKDataUrl } from './converters/glyphResolver.js';\n\n// ============================================================================\n// Package Metadata\n// ============================================================================\n\nexport const VERSION = '0.5.3';\nexport const LIB_NAME = 'web-annotation-renderer';\n"],"names":["VERSION","LIB_NAME"],"mappings":"stBAoIaA,EAAU,QACVC,EAAW"}