web-annotation-renderer 0.5.1 → 0.5.3

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 (71) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +39 -33
  4. package/dist/index.js.map +1 -1
  5. package/dist/index10.cjs +1 -1
  6. package/dist/index10.cjs.map +1 -1
  7. package/dist/index10.js +154 -119
  8. package/dist/index10.js.map +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.js +1 -1
  13. package/dist/index14.cjs +1 -1
  14. package/dist/index14.js +1 -1
  15. package/dist/index15.cjs +1 -1
  16. package/dist/index15.cjs.map +1 -1
  17. package/dist/index15.js +23 -117
  18. package/dist/index15.js.map +1 -1
  19. package/dist/index16.cjs +1 -1
  20. package/dist/index16.cjs.map +1 -1
  21. package/dist/index16.js +53 -103
  22. package/dist/index16.js.map +1 -1
  23. package/dist/index17.cjs +1 -1
  24. package/dist/index17.cjs.map +1 -1
  25. package/dist/index17.js +22 -57
  26. package/dist/index17.js.map +1 -1
  27. package/dist/index18.cjs +1 -1
  28. package/dist/index18.cjs.map +1 -1
  29. package/dist/index18.js +113 -136
  30. package/dist/index18.js.map +1 -1
  31. package/dist/index19.cjs +1 -1
  32. package/dist/index19.cjs.map +1 -1
  33. package/dist/index19.js +101 -35
  34. package/dist/index19.js.map +1 -1
  35. package/dist/index20.cjs +1 -1
  36. package/dist/index20.cjs.map +1 -1
  37. package/dist/index20.js +58 -36
  38. package/dist/index20.js.map +1 -1
  39. package/dist/index21.cjs +1 -1
  40. package/dist/index21.cjs.map +1 -1
  41. package/dist/index21.js +140 -37
  42. package/dist/index21.js.map +1 -1
  43. package/dist/index22.cjs +1 -1
  44. package/dist/index22.cjs.map +1 -1
  45. package/dist/index22.js +37 -21
  46. package/dist/index22.js.map +1 -1
  47. package/dist/index23.cjs +1 -1
  48. package/dist/index23.cjs.map +1 -1
  49. package/dist/index23.js +37 -5
  50. package/dist/index23.js.map +1 -1
  51. package/dist/index24.cjs +1 -1
  52. package/dist/index24.cjs.map +1 -1
  53. package/dist/index24.js +37 -4
  54. package/dist/index24.js.map +1 -1
  55. package/dist/index25.cjs +2 -0
  56. package/dist/index25.cjs.map +1 -0
  57. package/dist/index25.js +43 -0
  58. package/dist/index25.js.map +1 -0
  59. package/dist/index26.cjs +2 -0
  60. package/dist/index26.cjs.map +1 -0
  61. package/dist/index26.js +8 -0
  62. package/dist/index26.js.map +1 -0
  63. package/dist/index27.cjs +2 -0
  64. package/dist/index27.cjs.map +1 -0
  65. package/dist/index27.js +8 -0
  66. package/dist/index27.js.map +1 -0
  67. package/dist/index5.cjs +1 -1
  68. package/dist/index5.cjs.map +1 -1
  69. package/dist/index5.js +57 -36
  70. package/dist/index5.js.map +1 -1
  71. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index15.cjs","sources":["../src/pen/GradualRenderer.js"],"sourcesContent":["import StrokeDrawer from './StrokeDrawer.js';\n\n/**\n * GradualRenderer - Progressive stroke rendering synced to timeline\n *\n * Renders stroke commands with progressive reveal based on current\n * audio/video timeline position.\n *\n * Features:\n * - Progressive stroke reveal synced to audio timeline\n * - High-DPI canvas support for crisp rendering\n * - Efficient single-pass render per timeline update\n * - Accepts timing in seconds (start/end fields)\n *\n * @example\n * const renderer = new GradualRenderer(canvas, { width: 800, height: 600 });\n * renderer.setStrokeCommands(commands);\n * renderer.setTime(1.5); // seconds\n * renderer.render();\n */\nclass GradualRenderer {\n /**\n * Creates a new GradualRenderer instance\n *\n * @param {HTMLCanvasElement} canvas - Canvas element for rendering\n * @param {Object} pdfDimensions - PDF page dimensions\n * @param {number} pdfDimensions.width - Page width in pixels\n * @param {number} pdfDimensions.height - Page height in pixels\n */\n constructor(canvas, pdfDimensions) {\n this.canvas = canvas;\n this.dimensions = { ...pdfDimensions };\n this.ctx = null;\n this.strokeDrawer = null;\n this.strokeCommands = [];\n this.currentTime = 0; // seconds\n this.isDestroyed = false;\n\n this._setupCanvas();\n }\n\n /**\n * Configures canvas for high-DPI rendering\n *\n * @private\n */\n _setupCanvas() {\n const dpr = window.devicePixelRatio || 1;\n const { width, height } = this.dimensions;\n\n // Set canvas buffer resolution (high-res)\n this.canvas.width = Math.round(width * dpr);\n this.canvas.height = Math.round(height * dpr);\n\n // Set canvas display size (CSS)\n this.canvas.style.width = `${width}px`;\n this.canvas.style.height = `${height}px`;\n\n // Get context and scale for DPR\n this.ctx = this.canvas.getContext('2d');\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n // Create stroke drawer\n this.strokeDrawer = new StrokeDrawer(this.ctx, this.dimensions);\n }\n\n /**\n * Sets the stroke commands to render\n *\n * @param {Array} commands - Array of stroke command objects\n * @param {string} commands[].id - Unique stroke identifier\n * @param {Array} commands[].points - [[x, y], ...] normalized coordinates\n * @param {string} commands[].color - Stroke color\n * @param {number} commands[].width - Stroke width in pixels\n * @param {number} commands[].start - Start time in seconds\n * @param {number} commands[].end - End time in seconds\n */\n setStrokeCommands(commands) {\n if (this.isDestroyed) return;\n\n this.strokeCommands = commands || [];\n\n // Sort by start time for efficient rendering\n this.strokeCommands.sort((a, b) => {\n const startA = a.start ?? 0;\n const startB = b.start ?? 0;\n return startA - startB;\n });\n }\n\n /**\n * Sets the current timeline position\n *\n * @param {number} time - Current time in seconds\n */\n setTime(time) {\n if (this.isDestroyed) return;\n this.currentTime = time;\n }\n\n /**\n * Updates dimensions when viewport changes\n *\n * @param {Object} dimensions - New dimensions\n * @param {number} dimensions.width - Width in pixels\n * @param {number} dimensions.height - Height in pixels\n */\n setDimensions(dimensions) {\n if (this.isDestroyed) return;\n\n this.dimensions = { ...dimensions };\n this._setupCanvas();\n }\n\n /**\n * Renders all visible strokes at current timeline position\n *\n * Called once per timeline update. Clears canvas and redraws\n * all strokes with appropriate progress.\n */\n render() {\n if (this.isDestroyed || !this.ctx) return;\n\n // Clear canvas\n this.strokeDrawer.clear();\n\n // Draw each stroke based on timing\n for (const stroke of this.strokeCommands) {\n const start = stroke.start ?? 0;\n const end = stroke.end ?? start + 1;\n\n // Skip strokes that haven't started\n if (this.currentTime < start) {\n continue;\n }\n\n // Calculate progress\n const progress = this._calculateProgress(start, end);\n\n // Draw stroke with progress\n this.strokeDrawer.drawStroke(stroke, progress);\n }\n }\n\n /**\n * Calculates stroke progress based on timing\n *\n * @private\n * @param {number} start - Stroke start time in seconds\n * @param {number} end - Stroke end time in seconds\n * @returns {number} Progress from 0 to 1\n */\n _calculateProgress(start, end) {\n if (this.currentTime >= end) {\n return 1.0; // Fully visible\n }\n\n const duration = end - start;\n if (duration <= 0) return 1.0;\n\n const elapsed = this.currentTime - start;\n return Math.max(0, Math.min(1, elapsed / duration));\n }\n\n /**\n * Clears the canvas\n */\n clear() {\n if (this.isDestroyed || !this.strokeDrawer) return;\n this.strokeDrawer.clear();\n }\n\n /**\n * Gets visible stroke count at current time\n *\n * @returns {number} Number of visible strokes\n */\n getVisibleStrokeCount() {\n let count = 0;\n for (const stroke of this.strokeCommands) {\n const start = stroke.start ?? 0;\n if (this.currentTime >= start) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Destroys the renderer and releases resources\n */\n destroy() {\n if (this.isDestroyed) return;\n\n this.strokeCommands = [];\n this.strokeDrawer = null;\n this.ctx = null;\n this.canvas = null;\n this.isDestroyed = true;\n }\n}\n\nexport default GradualRenderer;\n"],"names":["GradualRenderer","canvas","pdfDimensions","dpr","width","height","StrokeDrawer","commands","a","b","startA","startB","time","dimensions","stroke","start","end","progress","duration","elapsed","count"],"mappings":"6IAoBA,MAAMA,CAAgB,CASpB,YAAYC,EAAQC,EAAe,CACjC,KAAK,OAASD,EACd,KAAK,WAAa,CAAE,GAAGC,CAAa,EACpC,KAAK,IAAM,KACX,KAAK,aAAe,KACpB,KAAK,eAAiB,CAAA,EACtB,KAAK,YAAc,EACnB,KAAK,YAAc,GAEnB,KAAK,aAAY,CACnB,CAOA,cAAe,CACb,MAAMC,EAAM,OAAO,kBAAoB,EACjC,CAAE,MAAAC,EAAO,OAAAC,CAAM,EAAK,KAAK,WAG/B,KAAK,OAAO,MAAQ,KAAK,MAAMD,EAAQD,CAAG,EAC1C,KAAK,OAAO,OAAS,KAAK,MAAME,EAASF,CAAG,EAG5C,KAAK,OAAO,MAAM,MAAQ,GAAGC,CAAK,KAClC,KAAK,OAAO,MAAM,OAAS,GAAGC,CAAM,KAGpC,KAAK,IAAM,KAAK,OAAO,WAAW,IAAI,EACtC,KAAK,IAAI,aAAaF,EAAK,EAAG,EAAGA,EAAK,EAAG,CAAC,EAG1C,KAAK,aAAe,IAAIG,EAAAA,QAAa,KAAK,IAAK,KAAK,UAAU,CAChE,CAaA,kBAAkBC,EAAU,CACtB,KAAK,cAET,KAAK,eAAiBA,GAAY,CAAA,EAGlC,KAAK,eAAe,KAAK,CAACC,EAAGC,IAAM,CACjC,MAAMC,EAASF,EAAE,OAAS,EACpBG,EAASF,EAAE,OAAS,EAC1B,OAAOC,EAASC,CAClB,CAAC,EACH,CAOA,QAAQC,EAAM,CACR,KAAK,cACT,KAAK,YAAcA,EACrB,CASA,cAAcC,EAAY,CACpB,KAAK,cAET,KAAK,WAAa,CAAE,GAAGA,CAAU,EACjC,KAAK,aAAY,EACnB,CAQA,QAAS,CACP,GAAI,OAAK,aAAe,CAAC,KAAK,KAG9B,MAAK,aAAa,MAAK,EAGvB,UAAWC,KAAU,KAAK,eAAgB,CACxC,MAAMC,EAAQD,EAAO,OAAS,EACxBE,EAAMF,EAAO,KAAOC,EAAQ,EAGlC,GAAI,KAAK,YAAcA,EACrB,SAIF,MAAME,EAAW,KAAK,mBAAmBF,EAAOC,CAAG,EAGnD,KAAK,aAAa,WAAWF,EAAQG,CAAQ,CAC/C,EACF,CAUA,mBAAmBF,EAAOC,EAAK,CAC7B,GAAI,KAAK,aAAeA,EACtB,MAAO,GAGT,MAAME,EAAWF,EAAMD,EACvB,GAAIG,GAAY,EAAG,MAAO,GAE1B,MAAMC,EAAU,KAAK,YAAcJ,EACnC,OAAO,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGI,EAAUD,CAAQ,CAAC,CACpD,CAKA,OAAQ,CACF,KAAK,aAAe,CAAC,KAAK,cAC9B,KAAK,aAAa,MAAK,CACzB,CAOA,uBAAwB,CACtB,IAAIE,EAAQ,EACZ,UAAWN,KAAU,KAAK,eAAgB,CACxC,MAAMC,EAAQD,EAAO,OAAS,EAC1B,KAAK,aAAeC,GACtBK,GAEJ,CACA,OAAOA,CACT,CAKA,SAAU,CACJ,KAAK,cAET,KAAK,eAAiB,CAAA,EACtB,KAAK,aAAe,KACpB,KAAK,IAAM,KACX,KAAK,OAAS,KACd,KAAK,YAAc,GACrB,CACF"}
1
+ {"version":3,"file":"index15.cjs","sources":["../src/converters/underline.js"],"sourcesContent":["/**\n * Underline Converter - Converts underline annotations to stroke commands\n *\n * Transforms quads into horizontal stroke paths at the bottom edge\n * that can be rendered progressively on canvas.\n *\n * @module converters/underline\n */\n\n/**\n * Converts an underline annotation to stroke commands\n *\n * Each quad in the annotation becomes a horizontal stroke at the\n * bottom edge of the quad. Multiple quads are staggered in timing.\n *\n * @param {Object} annotation - Underline annotation object\n * @param {string} annotation.id - Unique identifier\n * @param {number} annotation.start - Start time in seconds\n * @param {number} annotation.end - End time in seconds\n * @param {Array<{x: number, y: number, w: number, h: number}>} annotation.quads - Array of quads\n * @param {Object} [annotation.style] - Optional style overrides\n * @param {Object} style - Resolved style configuration\n * @param {string} style.color - Stroke color\n * @param {number} style.width - Stroke width in pixels\n * @param {string} [style.lineCap='round'] - Line cap style\n * @returns {Array<Object>} Array of stroke commands\n */\nexport function underlineToStrokes(annotation, style) {\n const { id, start, end, quads } = annotation;\n\n if (!quads || quads.length === 0) {\n return [];\n }\n\n const strokes = [];\n const totalDuration = end - start;\n const quadCount = quads.length;\n const quadDuration = totalDuration / quadCount;\n\n for (let i = 0; i < quads.length; i++) {\n const quad = quads[i];\n const { x, y, w, h } = quad;\n\n // Line at bottom edge of quad\n const lineY = y + h;\n const points = [\n [x, lineY],\n [x + w, lineY]\n ];\n\n // Calculate timing for this quad\n const quadStart = start + i * quadDuration;\n const quadEnd = quadStart + quadDuration;\n\n strokes.push({\n id: `${id}-${i}`,\n points,\n start: quadStart,\n end: quadEnd,\n color: style.color || 'rgba(0, 0, 255, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n }\n\n return strokes;\n}\n\nexport default underlineToStrokes;\n"],"names":["underlineToStrokes","annotation","style","id","start","end","quads","strokes","totalDuration","quadCount","quadDuration","i","quad","x","y","w","h","lineY","points","quadStart","quadEnd"],"mappings":"4GA2BO,SAASA,EAAmBC,EAAYC,EAAO,CACpD,KAAM,CAAE,GAAAC,EAAI,MAAAC,EAAO,IAAAC,EAAK,MAAAC,CAAK,EAAKL,EAElC,GAAI,CAACK,GAASA,EAAM,SAAW,EAC7B,MAAO,CAAA,EAGT,MAAMC,EAAU,CAAA,EACVC,EAAgBH,EAAMD,EACtBK,EAAYH,EAAM,OAClBI,EAAeF,EAAgBC,EAErC,QAASE,EAAI,EAAGA,EAAIL,EAAM,OAAQK,IAAK,CACrC,MAAMC,EAAON,EAAMK,CAAC,EACd,CAAE,EAAAE,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAC,EAAKJ,EAGjBK,EAAQH,EAAIE,EACZE,EAAS,CACb,CAACL,EAAGI,CAAK,EACT,CAACJ,EAAIE,EAAGE,CAAK,CACnB,EAGUE,EAAYf,EAAQO,EAAID,EACxBU,EAAUD,EAAYT,EAE5BH,EAAQ,KAAK,CACX,GAAI,GAAGJ,CAAE,IAAIQ,CAAC,GACd,OAAAO,EACA,MAAOC,EACP,IAAKC,EACL,MAAOlB,EAAM,OAAS,uBACtB,MAAOA,EAAM,OAAS,EACtB,QAASA,EAAM,SAAW,OAChC,CAAK,CACH,CAEA,OAAOK,CACT"}
package/dist/index15.js CHANGED
@@ -1,121 +1,27 @@
1
- import n from "./index16.js";
2
- class h {
3
- /**
4
- * Creates a new GradualRenderer instance
5
- *
6
- * @param {HTMLCanvasElement} canvas - Canvas element for rendering
7
- * @param {Object} pdfDimensions - PDF page dimensions
8
- * @param {number} pdfDimensions.width - Page width in pixels
9
- * @param {number} pdfDimensions.height - Page height in pixels
10
- */
11
- constructor(t, s) {
12
- this.canvas = t, this.dimensions = { ...s }, this.ctx = null, this.strokeDrawer = null, this.strokeCommands = [], this.currentTime = 0, this.isDestroyed = !1, this._setupCanvas();
13
- }
14
- /**
15
- * Configures canvas for high-DPI rendering
16
- *
17
- * @private
18
- */
19
- _setupCanvas() {
20
- const t = window.devicePixelRatio || 1, { width: s, height: e } = this.dimensions;
21
- this.canvas.width = Math.round(s * t), this.canvas.height = Math.round(e * t), this.canvas.style.width = `${s}px`, this.canvas.style.height = `${e}px`, this.ctx = this.canvas.getContext("2d"), this.ctx.setTransform(t, 0, 0, t, 0, 0), this.strokeDrawer = new n(this.ctx, this.dimensions);
22
- }
23
- /**
24
- * Sets the stroke commands to render
25
- *
26
- * @param {Array} commands - Array of stroke command objects
27
- * @param {string} commands[].id - Unique stroke identifier
28
- * @param {Array} commands[].points - [[x, y], ...] normalized coordinates
29
- * @param {string} commands[].color - Stroke color
30
- * @param {number} commands[].width - Stroke width in pixels
31
- * @param {number} commands[].start - Start time in seconds
32
- * @param {number} commands[].end - End time in seconds
33
- */
34
- setStrokeCommands(t) {
35
- this.isDestroyed || (this.strokeCommands = t || [], this.strokeCommands.sort((s, e) => {
36
- const r = s.start ?? 0, i = e.start ?? 0;
37
- return r - i;
38
- }));
39
- }
40
- /**
41
- * Sets the current timeline position
42
- *
43
- * @param {number} time - Current time in seconds
44
- */
45
- setTime(t) {
46
- this.isDestroyed || (this.currentTime = t);
47
- }
48
- /**
49
- * Updates dimensions when viewport changes
50
- *
51
- * @param {Object} dimensions - New dimensions
52
- * @param {number} dimensions.width - Width in pixels
53
- * @param {number} dimensions.height - Height in pixels
54
- */
55
- setDimensions(t) {
56
- this.isDestroyed || (this.dimensions = { ...t }, this._setupCanvas());
57
- }
58
- /**
59
- * Renders all visible strokes at current timeline position
60
- *
61
- * Called once per timeline update. Clears canvas and redraws
62
- * all strokes with appropriate progress.
63
- */
64
- render() {
65
- if (!(this.isDestroyed || !this.ctx)) {
66
- this.strokeDrawer.clear();
67
- for (const t of this.strokeCommands) {
68
- const s = t.start ?? 0, e = t.end ?? s + 1;
69
- if (this.currentTime < s)
70
- continue;
71
- const r = this._calculateProgress(s, e);
72
- this.strokeDrawer.drawStroke(t, r);
73
- }
74
- }
75
- }
76
- /**
77
- * Calculates stroke progress based on timing
78
- *
79
- * @private
80
- * @param {number} start - Stroke start time in seconds
81
- * @param {number} end - Stroke end time in seconds
82
- * @returns {number} Progress from 0 to 1
83
- */
84
- _calculateProgress(t, s) {
85
- if (this.currentTime >= s)
86
- return 1;
87
- const e = s - t;
88
- if (e <= 0) return 1;
89
- const r = this.currentTime - t;
90
- return Math.max(0, Math.min(1, r / e));
91
- }
92
- /**
93
- * Clears the canvas
94
- */
95
- clear() {
96
- this.isDestroyed || !this.strokeDrawer || this.strokeDrawer.clear();
97
- }
98
- /**
99
- * Gets visible stroke count at current time
100
- *
101
- * @returns {number} Number of visible strokes
102
- */
103
- getVisibleStrokeCount() {
104
- let t = 0;
105
- for (const s of this.strokeCommands) {
106
- const e = s.start ?? 0;
107
- this.currentTime >= e && t++;
108
- }
109
- return t;
110
- }
111
- /**
112
- * Destroys the renderer and releases resources
113
- */
114
- destroy() {
115
- this.isDestroyed || (this.strokeCommands = [], this.strokeDrawer = null, this.ctx = null, this.canvas = null, this.isDestroyed = !0);
116
- }
1
+ function x(c, o) {
2
+ const { id: i, start: r, end: l, quads: t } = c;
3
+ if (!t || t.length === 0)
4
+ return [];
5
+ const s = [], h = l - r, q = t.length, a = h / q;
6
+ for (let n = 0; n < t.length; n++) {
7
+ const p = t[n], { x: d, y: f, w: g, h: w } = p, u = f + w, C = [
8
+ [d, u],
9
+ [d + g, u]
10
+ ], e = r + n * a, k = e + a;
11
+ s.push({
12
+ id: `${i}-${n}`,
13
+ points: C,
14
+ start: e,
15
+ end: k,
16
+ color: o.color || "rgba(0, 0, 255, 0.8)",
17
+ width: o.width || 2,
18
+ lineCap: o.lineCap || "round"
19
+ });
20
+ }
21
+ return s;
117
22
  }
118
23
  export {
119
- h as default
24
+ x as default,
25
+ x as underlineToStrokes
120
26
  };
121
27
  //# sourceMappingURL=index15.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index15.js","sources":["../src/pen/GradualRenderer.js"],"sourcesContent":["import StrokeDrawer from './StrokeDrawer.js';\n\n/**\n * GradualRenderer - Progressive stroke rendering synced to timeline\n *\n * Renders stroke commands with progressive reveal based on current\n * audio/video timeline position.\n *\n * Features:\n * - Progressive stroke reveal synced to audio timeline\n * - High-DPI canvas support for crisp rendering\n * - Efficient single-pass render per timeline update\n * - Accepts timing in seconds (start/end fields)\n *\n * @example\n * const renderer = new GradualRenderer(canvas, { width: 800, height: 600 });\n * renderer.setStrokeCommands(commands);\n * renderer.setTime(1.5); // seconds\n * renderer.render();\n */\nclass GradualRenderer {\n /**\n * Creates a new GradualRenderer instance\n *\n * @param {HTMLCanvasElement} canvas - Canvas element for rendering\n * @param {Object} pdfDimensions - PDF page dimensions\n * @param {number} pdfDimensions.width - Page width in pixels\n * @param {number} pdfDimensions.height - Page height in pixels\n */\n constructor(canvas, pdfDimensions) {\n this.canvas = canvas;\n this.dimensions = { ...pdfDimensions };\n this.ctx = null;\n this.strokeDrawer = null;\n this.strokeCommands = [];\n this.currentTime = 0; // seconds\n this.isDestroyed = false;\n\n this._setupCanvas();\n }\n\n /**\n * Configures canvas for high-DPI rendering\n *\n * @private\n */\n _setupCanvas() {\n const dpr = window.devicePixelRatio || 1;\n const { width, height } = this.dimensions;\n\n // Set canvas buffer resolution (high-res)\n this.canvas.width = Math.round(width * dpr);\n this.canvas.height = Math.round(height * dpr);\n\n // Set canvas display size (CSS)\n this.canvas.style.width = `${width}px`;\n this.canvas.style.height = `${height}px`;\n\n // Get context and scale for DPR\n this.ctx = this.canvas.getContext('2d');\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n // Create stroke drawer\n this.strokeDrawer = new StrokeDrawer(this.ctx, this.dimensions);\n }\n\n /**\n * Sets the stroke commands to render\n *\n * @param {Array} commands - Array of stroke command objects\n * @param {string} commands[].id - Unique stroke identifier\n * @param {Array} commands[].points - [[x, y], ...] normalized coordinates\n * @param {string} commands[].color - Stroke color\n * @param {number} commands[].width - Stroke width in pixels\n * @param {number} commands[].start - Start time in seconds\n * @param {number} commands[].end - End time in seconds\n */\n setStrokeCommands(commands) {\n if (this.isDestroyed) return;\n\n this.strokeCommands = commands || [];\n\n // Sort by start time for efficient rendering\n this.strokeCommands.sort((a, b) => {\n const startA = a.start ?? 0;\n const startB = b.start ?? 0;\n return startA - startB;\n });\n }\n\n /**\n * Sets the current timeline position\n *\n * @param {number} time - Current time in seconds\n */\n setTime(time) {\n if (this.isDestroyed) return;\n this.currentTime = time;\n }\n\n /**\n * Updates dimensions when viewport changes\n *\n * @param {Object} dimensions - New dimensions\n * @param {number} dimensions.width - Width in pixels\n * @param {number} dimensions.height - Height in pixels\n */\n setDimensions(dimensions) {\n if (this.isDestroyed) return;\n\n this.dimensions = { ...dimensions };\n this._setupCanvas();\n }\n\n /**\n * Renders all visible strokes at current timeline position\n *\n * Called once per timeline update. Clears canvas and redraws\n * all strokes with appropriate progress.\n */\n render() {\n if (this.isDestroyed || !this.ctx) return;\n\n // Clear canvas\n this.strokeDrawer.clear();\n\n // Draw each stroke based on timing\n for (const stroke of this.strokeCommands) {\n const start = stroke.start ?? 0;\n const end = stroke.end ?? start + 1;\n\n // Skip strokes that haven't started\n if (this.currentTime < start) {\n continue;\n }\n\n // Calculate progress\n const progress = this._calculateProgress(start, end);\n\n // Draw stroke with progress\n this.strokeDrawer.drawStroke(stroke, progress);\n }\n }\n\n /**\n * Calculates stroke progress based on timing\n *\n * @private\n * @param {number} start - Stroke start time in seconds\n * @param {number} end - Stroke end time in seconds\n * @returns {number} Progress from 0 to 1\n */\n _calculateProgress(start, end) {\n if (this.currentTime >= end) {\n return 1.0; // Fully visible\n }\n\n const duration = end - start;\n if (duration <= 0) return 1.0;\n\n const elapsed = this.currentTime - start;\n return Math.max(0, Math.min(1, elapsed / duration));\n }\n\n /**\n * Clears the canvas\n */\n clear() {\n if (this.isDestroyed || !this.strokeDrawer) return;\n this.strokeDrawer.clear();\n }\n\n /**\n * Gets visible stroke count at current time\n *\n * @returns {number} Number of visible strokes\n */\n getVisibleStrokeCount() {\n let count = 0;\n for (const stroke of this.strokeCommands) {\n const start = stroke.start ?? 0;\n if (this.currentTime >= start) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Destroys the renderer and releases resources\n */\n destroy() {\n if (this.isDestroyed) return;\n\n this.strokeCommands = [];\n this.strokeDrawer = null;\n this.ctx = null;\n this.canvas = null;\n this.isDestroyed = true;\n }\n}\n\nexport default GradualRenderer;\n"],"names":["GradualRenderer","canvas","pdfDimensions","dpr","width","height","StrokeDrawer","commands","a","b","startA","startB","time","dimensions","stroke","start","end","progress","duration","elapsed","count"],"mappings":"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"}
1
+ {"version":3,"file":"index15.js","sources":["../src/converters/underline.js"],"sourcesContent":["/**\n * Underline Converter - Converts underline annotations to stroke commands\n *\n * Transforms quads into horizontal stroke paths at the bottom edge\n * that can be rendered progressively on canvas.\n *\n * @module converters/underline\n */\n\n/**\n * Converts an underline annotation to stroke commands\n *\n * Each quad in the annotation becomes a horizontal stroke at the\n * bottom edge of the quad. Multiple quads are staggered in timing.\n *\n * @param {Object} annotation - Underline annotation object\n * @param {string} annotation.id - Unique identifier\n * @param {number} annotation.start - Start time in seconds\n * @param {number} annotation.end - End time in seconds\n * @param {Array<{x: number, y: number, w: number, h: number}>} annotation.quads - Array of quads\n * @param {Object} [annotation.style] - Optional style overrides\n * @param {Object} style - Resolved style configuration\n * @param {string} style.color - Stroke color\n * @param {number} style.width - Stroke width in pixels\n * @param {string} [style.lineCap='round'] - Line cap style\n * @returns {Array<Object>} Array of stroke commands\n */\nexport function underlineToStrokes(annotation, style) {\n const { id, start, end, quads } = annotation;\n\n if (!quads || quads.length === 0) {\n return [];\n }\n\n const strokes = [];\n const totalDuration = end - start;\n const quadCount = quads.length;\n const quadDuration = totalDuration / quadCount;\n\n for (let i = 0; i < quads.length; i++) {\n const quad = quads[i];\n const { x, y, w, h } = quad;\n\n // Line at bottom edge of quad\n const lineY = y + h;\n const points = [\n [x, lineY],\n [x + w, lineY]\n ];\n\n // Calculate timing for this quad\n const quadStart = start + i * quadDuration;\n const quadEnd = quadStart + quadDuration;\n\n strokes.push({\n id: `${id}-${i}`,\n points,\n start: quadStart,\n end: quadEnd,\n color: style.color || 'rgba(0, 0, 255, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n }\n\n return strokes;\n}\n\nexport default underlineToStrokes;\n"],"names":["underlineToStrokes","annotation","style","id","start","end","quads","strokes","totalDuration","quadCount","quadDuration","i","quad","x","y","w","h","lineY","points","quadStart","quadEnd"],"mappings":"AA2BO,SAASA,EAAmBC,GAAYC,GAAO;AACpD,QAAM,EAAE,IAAAC,GAAI,OAAAC,GAAO,KAAAC,GAAK,OAAAC,EAAK,IAAKL;AAElC,MAAI,CAACK,KAASA,EAAM,WAAW;AAC7B,WAAO,CAAA;AAGT,QAAMC,IAAU,CAAA,GACVC,IAAgBH,IAAMD,GACtBK,IAAYH,EAAM,QAClBI,IAAeF,IAAgBC;AAErC,WAASE,IAAI,GAAGA,IAAIL,EAAM,QAAQK,KAAK;AACrC,UAAMC,IAAON,EAAMK,CAAC,GACd,EAAE,GAAAE,GAAG,GAAAC,GAAG,GAAAC,GAAG,GAAAC,EAAC,IAAKJ,GAGjBK,IAAQH,IAAIE,GACZE,IAAS;AAAA,MACb,CAACL,GAAGI,CAAK;AAAA,MACT,CAACJ,IAAIE,GAAGE,CAAK;AAAA,IACnB,GAGUE,IAAYf,IAAQO,IAAID,GACxBU,IAAUD,IAAYT;AAE5B,IAAAH,EAAQ,KAAK;AAAA,MACX,IAAI,GAAGJ,CAAE,IAAIQ,CAAC;AAAA,MACd,QAAAO;AAAA,MACA,OAAOC;AAAA,MACP,KAAKC;AAAA,MACL,OAAOlB,EAAM,SAAS;AAAA,MACtB,OAAOA,EAAM,SAAS;AAAA,MACtB,SAASA,EAAM,WAAW;AAAA,IAChC,CAAK;AAAA,EACH;AAEA,SAAOK;AACT;"}
package/dist/index16.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class d{constructor(t,o){this.ctx=t,this.viewport=o}setViewport(t){this.viewport=t}drawStroke(t,o=1){const{points:i,color:e,width:s,pressures:h}=t;if(!i||i.length<2)return;const n=Math.max(2,Math.floor(i.length*o)),r=i.slice(0,n);this.ctx.strokeStyle=e||"rgba(0, 0, 0, 0.5)",this.ctx.lineCap="round",this.ctx.lineJoin="round",h&&h.length>=r.length?this._drawVariableWidthStroke(r,s,h.slice(0,n)):this._drawConstantWidthStroke(r,s)}_drawConstantWidthStroke(t,o){this.ctx.lineWidth=o||2,this.ctx.beginPath();for(let i=0;i<t.length;i++){const[e,s]=this._normalizedToPixel(t[i]);i===0?this.ctx.moveTo(e,s):this.ctx.lineTo(e,s)}this.ctx.stroke()}_drawVariableWidthStroke(t,o,i){for(let e=1;e<t.length;e++){const[s,h]=this._normalizedToPixel(t[e-1]),[n,r]=this._normalizedToPixel(t[e]),l=i[e-1]||1,c=i[e]||1,a=(l+c)/2,x=Math.max(.5,o*a);this.ctx.lineWidth=x,this.ctx.beginPath(),this.ctx.moveTo(s,h),this.ctx.lineTo(n,r),this.ctx.stroke()}}drawPoint(t,o,i,e){const[s,h]=this._normalizedToPixel([t,o]);this.ctx.fillStyle=e||"rgba(0, 0, 0, 0.5)",this.ctx.beginPath(),this.ctx.arc(s,h,i,0,Math.PI*2),this.ctx.fill()}clear(){const t=window.devicePixelRatio||1;this.ctx.clearRect(0,0,this.viewport.width*t,this.viewport.height*t)}_normalizedToPixel(t){const[o,i]=t;return[o*this.viewport.width,i*this.viewport.height]}}exports.default=d;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function w(C,t){const{id:h,start:e,end:S,from_x:r,from_y:i,to_x:o,to_y:n}=C;if(typeof r!="number"||typeof i!="number"||typeof o!="number"||typeof n!="number")return[];const a=[],p=S-e,f=p*.7,_=p*.3,g=20,M=[];for(let l=0;l<=g;l++){const m=l/g;M.push([r+(o-r)*m,i+(n-i)*m])}a.push({id:`${h}-0`,points:M,start:e,end:e+f,color:t.color||"rgba(255, 0, 0, 0.8)",width:t.width||2,lineCap:t.lineCap||"round"});const D=Math.sqrt((o-r)**2+(n-i)**2),s=Math.min(D*.2,.03),c=Math.atan2(n-i,o-r),u=Math.PI/6,P=[[o,n],[o-s*Math.cos(c-u),n-s*Math.sin(c-u)]],k=[[o,n],[o-s*Math.cos(c+u),n-s*Math.sin(c+u)]],d=e+f,b=_/2;return a.push({id:`${h}-1`,points:P,start:d,end:d+b,color:t.color||"rgba(255, 0, 0, 0.8)",width:t.width||2,lineCap:t.lineCap||"round"}),a.push({id:`${h}-2`,points:k,start:d,end:d+b,color:t.color||"rgba(255, 0, 0, 0.8)",width:t.width||2,lineCap:t.lineCap||"round"}),a}exports.arrowToStrokes=w;exports.default=w;
2
2
  //# sourceMappingURL=index16.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index16.cjs","sources":["../src/pen/StrokeDrawer.js"],"sourcesContent":["/**\n * StrokeDrawer - Low-level canvas stroke drawing utilities\n *\n * Handles the actual drawing of strokes on canvas with support for:\n * - Progressive stroke reveal (partial drawing based on progress)\n * - Normalized to pixel coordinate conversion\n * - Variable width based on pressure data\n * - Smooth line rendering with round caps/joins\n */\nclass StrokeDrawer {\n /**\n * Creates a new StrokeDrawer instance\n *\n * @param {CanvasRenderingContext2D} ctx - Canvas 2D rendering context\n * @param {Object} viewport - Viewport dimensions for coordinate conversion\n * @param {number} viewport.width - Viewport width in pixels\n * @param {number} viewport.height - Viewport height in pixels\n */\n constructor(ctx, viewport) {\n this.ctx = ctx;\n this.viewport = viewport;\n }\n\n /**\n * Updates the viewport dimensions\n *\n * @param {Object} viewport - New viewport dimensions\n */\n setViewport(viewport) {\n this.viewport = viewport;\n }\n\n /**\n * Draws a stroke with optional progress for progressive reveal\n *\n * @param {Object} stroke - Stroke command object\n * @param {Array} stroke.points - Array of [x, y] normalized coordinates\n * @param {string} stroke.color - Stroke color (CSS color string)\n * @param {number} stroke.width - Base stroke width in pixels\n * @param {Array} [stroke.pressures] - Optional pressure values for variable width\n * @param {number} [progress=1.0] - Progress from 0 to 1 (for progressive reveal)\n */\n drawStroke(stroke, progress = 1.0) {\n const { points, color, width, pressures } = stroke;\n\n if (!points || points.length < 2) return;\n\n // Calculate how many points to draw based on progress\n const pointCount = Math.max(2, Math.floor(points.length * progress));\n const visiblePoints = points.slice(0, pointCount);\n\n // Configure stroke style\n this.ctx.strokeStyle = color || 'rgba(0, 0, 0, 0.5)';\n this.ctx.lineCap = 'round';\n this.ctx.lineJoin = 'round';\n\n // Draw with variable width if pressures provided\n if (pressures && pressures.length >= visiblePoints.length) {\n this._drawVariableWidthStroke(visiblePoints, width, pressures.slice(0, pointCount));\n } else {\n this._drawConstantWidthStroke(visiblePoints, width);\n }\n }\n\n /**\n * Draws a stroke with constant width\n *\n * @private\n * @param {Array} points - Array of [x, y] normalized coordinates\n * @param {number} width - Stroke width in pixels\n */\n _drawConstantWidthStroke(points, width) {\n this.ctx.lineWidth = width || 2;\n this.ctx.beginPath();\n\n for (let i = 0; i < points.length; i++) {\n const [px, py] = this._normalizedToPixel(points[i]);\n\n if (i === 0) {\n this.ctx.moveTo(px, py);\n } else {\n this.ctx.lineTo(px, py);\n }\n }\n\n this.ctx.stroke();\n }\n\n /**\n * Draws a stroke with variable width based on pressure\n *\n * Uses multiple line segments with varying widths for natural pen feel.\n *\n * @private\n * @param {Array} points - Array of [x, y] normalized coordinates\n * @param {number} baseWidth - Base stroke width in pixels\n * @param {Array} pressures - Pressure values (0-1) for each point\n */\n _drawVariableWidthStroke(points, baseWidth, pressures) {\n for (let i = 1; i < points.length; i++) {\n const [x1, y1] = this._normalizedToPixel(points[i - 1]);\n const [x2, y2] = this._normalizedToPixel(points[i]);\n\n // Average pressure between two points\n const p1 = pressures[i - 1] || 1;\n const p2 = pressures[i] || 1;\n const avgPressure = (p1 + p2) / 2;\n\n // Apply pressure to width (min 0.5, max 2x base width)\n const width = Math.max(0.5, baseWidth * avgPressure);\n\n this.ctx.lineWidth = width;\n this.ctx.beginPath();\n this.ctx.moveTo(x1, y1);\n this.ctx.lineTo(x2, y2);\n this.ctx.stroke();\n }\n }\n\n /**\n * Draws a single point (dot)\n *\n * Useful for single-point strokes or debugging.\n *\n * @param {number} x - Normalized x coordinate (0-1)\n * @param {number} y - Normalized y coordinate (0-1)\n * @param {number} radius - Dot radius in pixels\n * @param {string} color - Fill color\n */\n drawPoint(x, y, radius, color) {\n const [px, py] = this._normalizedToPixel([x, y]);\n\n this.ctx.fillStyle = color || 'rgba(0, 0, 0, 0.5)';\n this.ctx.beginPath();\n this.ctx.arc(px, py, radius, 0, Math.PI * 2);\n this.ctx.fill();\n }\n\n /**\n * Clears the entire canvas\n */\n clear() {\n const dpr = window.devicePixelRatio || 1;\n this.ctx.clearRect(0, 0, this.viewport.width * dpr, this.viewport.height * dpr);\n }\n\n /**\n * Converts normalized coordinates (0-1) to pixel coordinates\n *\n * @private\n * @param {Array} point - [x, y] normalized coordinates\n * @returns {Array} [x, y] pixel coordinates\n */\n _normalizedToPixel(point) {\n const [normX, normY] = point;\n return [\n normX * this.viewport.width,\n normY * this.viewport.height\n ];\n }\n}\n\nexport default StrokeDrawer;\n"],"names":["StrokeDrawer","ctx","viewport","stroke","progress","points","color","width","pressures","pointCount","visiblePoints","px","py","baseWidth","i","x1","y1","x2","y2","p1","p2","avgPressure","x","y","radius","dpr","point","normX","normY"],"mappings":"4GASA,MAAMA,CAAa,CASjB,YAAYC,EAAKC,EAAU,CACzB,KAAK,IAAMD,EACX,KAAK,SAAWC,CAClB,CAOA,YAAYA,EAAU,CACpB,KAAK,SAAWA,CAClB,CAYA,WAAWC,EAAQC,EAAW,EAAK,CACjC,KAAM,CAAE,OAAAC,EAAQ,MAAAC,EAAO,MAAAC,EAAO,UAAAC,CAAS,EAAKL,EAE5C,GAAI,CAACE,GAAUA,EAAO,OAAS,EAAG,OAGlC,MAAMI,EAAa,KAAK,IAAI,EAAG,KAAK,MAAMJ,EAAO,OAASD,CAAQ,CAAC,EAC7DM,EAAgBL,EAAO,MAAM,EAAGI,CAAU,EAGhD,KAAK,IAAI,YAAcH,GAAS,qBAChC,KAAK,IAAI,QAAU,QACnB,KAAK,IAAI,SAAW,QAGhBE,GAAaA,EAAU,QAAUE,EAAc,OACjD,KAAK,yBAAyBA,EAAeH,EAAOC,EAAU,MAAM,EAAGC,CAAU,CAAC,EAElF,KAAK,yBAAyBC,EAAeH,CAAK,CAEtD,CASA,yBAAyBF,EAAQE,EAAO,CACtC,KAAK,IAAI,UAAYA,GAAS,EAC9B,KAAK,IAAI,UAAS,EAElB,QAAS,EAAI,EAAG,EAAIF,EAAO,OAAQ,IAAK,CACtC,KAAM,CAACM,EAAIC,CAAE,EAAI,KAAK,mBAAmBP,EAAO,CAAC,CAAC,EAE9C,IAAM,EACR,KAAK,IAAI,OAAOM,EAAIC,CAAE,EAEtB,KAAK,IAAI,OAAOD,EAAIC,CAAE,CAE1B,CAEA,KAAK,IAAI,OAAM,CACjB,CAYA,yBAAyBP,EAAQQ,EAAWL,EAAW,CACrD,QAASM,EAAI,EAAGA,EAAIT,EAAO,OAAQS,IAAK,CACtC,KAAM,CAACC,EAAIC,CAAE,EAAI,KAAK,mBAAmBX,EAAOS,EAAI,CAAC,CAAC,EAChD,CAACG,EAAIC,CAAE,EAAI,KAAK,mBAAmBb,EAAOS,CAAC,CAAC,EAG5CK,EAAKX,EAAUM,EAAI,CAAC,GAAK,EACzBM,EAAKZ,EAAUM,CAAC,GAAK,EACrBO,GAAeF,EAAKC,GAAM,EAG1Bb,EAAQ,KAAK,IAAI,GAAKM,EAAYQ,CAAW,EAEnD,KAAK,IAAI,UAAYd,EACrB,KAAK,IAAI,UAAS,EAClB,KAAK,IAAI,OAAOQ,EAAIC,CAAE,EACtB,KAAK,IAAI,OAAOC,EAAIC,CAAE,EACtB,KAAK,IAAI,OAAM,CACjB,CACF,CAYA,UAAUI,EAAGC,EAAGC,EAAQlB,EAAO,CAC7B,KAAM,CAACK,EAAIC,CAAE,EAAI,KAAK,mBAAmB,CAACU,EAAGC,CAAC,CAAC,EAE/C,KAAK,IAAI,UAAYjB,GAAS,qBAC9B,KAAK,IAAI,UAAS,EAClB,KAAK,IAAI,IAAIK,EAAIC,EAAIY,EAAQ,EAAG,KAAK,GAAK,CAAC,EAC3C,KAAK,IAAI,KAAI,CACf,CAKA,OAAQ,CACN,MAAMC,EAAM,OAAO,kBAAoB,EACvC,KAAK,IAAI,UAAU,EAAG,EAAG,KAAK,SAAS,MAAQA,EAAK,KAAK,SAAS,OAASA,CAAG,CAChF,CASA,mBAAmBC,EAAO,CACxB,KAAM,CAACC,EAAOC,CAAK,EAAIF,EACvB,MAAO,CACLC,EAAQ,KAAK,SAAS,MACtBC,EAAQ,KAAK,SAAS,MAC5B,CACE,CACF"}
1
+ {"version":3,"file":"index16.cjs","sources":["../src/converters/arrow.js"],"sourcesContent":["/**\n * Arrow Converter - Converts arrow annotations to stroke commands\n *\n * Transforms arrow data into a line stroke with arrowhead strokes\n * that can be rendered progressively on canvas.\n *\n * @module converters/arrow\n */\n\n/**\n * Converts an arrow annotation to stroke commands\n *\n * Creates a main line stroke from source to target, followed by\n * two wing strokes forming the arrowhead. Line draws first (70%),\n * then arrowhead (30%).\n *\n * @param {Object} annotation - Arrow annotation object\n * @param {string} annotation.id - Unique identifier\n * @param {number} annotation.start - Start time in seconds\n * @param {number} annotation.end - End time in seconds\n * @param {number} annotation.from_x - Source x position (0-1 normalized)\n * @param {number} annotation.from_y - Source y position (0-1 normalized)\n * @param {number} annotation.to_x - Target x position (0-1 normalized)\n * @param {number} annotation.to_y - Target y position (0-1 normalized)\n * @param {Object} [annotation.style] - Optional style overrides\n * @param {Object} style - Resolved style configuration\n * @param {string} style.color - Stroke color\n * @param {number} style.width - Stroke width in pixels\n * @param {string} [style.lineCap='round'] - Line cap style\n * @returns {Array<Object>} Array of stroke commands\n */\nexport function arrowToStrokes(annotation, style) {\n const { id, start, end, from_x, from_y, to_x, to_y } = annotation;\n\n if (typeof from_x !== 'number' || typeof from_y !== 'number' ||\n typeof to_x !== 'number' || typeof to_y !== 'number') {\n return [];\n }\n\n const strokes = [];\n const totalDuration = end - start;\n const lineDuration = totalDuration * 0.7;\n const headDuration = totalDuration * 0.3;\n\n // Subdivide line for smooth progressive reveal\n const numPoints = 20;\n const linePoints = [];\n for (let i = 0; i <= numPoints; i++) {\n const t = i / numPoints;\n linePoints.push([\n from_x + (to_x - from_x) * t,\n from_y + (to_y - from_y) * t\n ]);\n }\n\n // Main line stroke\n strokes.push({\n id: `${id}-0`,\n points: linePoints,\n start: start,\n end: start + lineDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n // Arrow head calculation\n const lineLength = Math.sqrt((to_x - from_x) ** 2 + (to_y - from_y) ** 2);\n const headSize = Math.min(lineLength * 0.2, 0.03);\n const angle = Math.atan2(to_y - from_y, to_x - from_x);\n const headAngle = Math.PI / 6; // 30 degrees\n\n // Left wing\n const leftWing = [\n [to_x, to_y],\n [\n to_x - headSize * Math.cos(angle - headAngle),\n to_y - headSize * Math.sin(angle - headAngle)\n ]\n ];\n\n // Right wing\n const rightWing = [\n [to_x, to_y],\n [\n to_x - headSize * Math.cos(angle + headAngle),\n to_y - headSize * Math.sin(angle + headAngle)\n ]\n ];\n\n const headStart = start + lineDuration;\n const wingDuration = headDuration / 2;\n\n strokes.push({\n id: `${id}-1`,\n points: leftWing,\n start: headStart,\n end: headStart + wingDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n strokes.push({\n id: `${id}-2`,\n points: rightWing,\n start: headStart,\n end: headStart + wingDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n return strokes;\n}\n\nexport default arrowToStrokes;\n"],"names":["arrowToStrokes","annotation","style","id","start","end","from_x","from_y","to_x","to_y","strokes","totalDuration","lineDuration","headDuration","numPoints","linePoints","i","t","lineLength","headSize","angle","headAngle","leftWing","rightWing","headStart","wingDuration"],"mappings":"4GA+BO,SAASA,EAAeC,EAAYC,EAAO,CAChD,KAAM,CAAE,GAAAC,EAAI,MAAAC,EAAO,IAAAC,EAAK,OAAAC,EAAQ,OAAAC,EAAQ,KAAAC,EAAM,KAAAC,CAAI,EAAKR,EAEvD,GAAI,OAAOK,GAAW,UAAY,OAAOC,GAAW,UAChD,OAAOC,GAAS,UAAY,OAAOC,GAAS,SAC9C,MAAO,CAAA,EAGT,MAAMC,EAAU,CAAA,EACVC,EAAgBN,EAAMD,EACtBQ,EAAeD,EAAgB,GAC/BE,EAAeF,EAAgB,GAG/BG,EAAY,GACZC,EAAa,CAAA,EACnB,QAASC,EAAI,EAAGA,GAAKF,EAAWE,IAAK,CACnC,MAAMC,EAAID,EAAIF,EACdC,EAAW,KAAK,CACdT,GAAUE,EAAOF,GAAUW,EAC3BV,GAAUE,EAAOF,GAAUU,CACjC,CAAK,CACH,CAGAP,EAAQ,KAAK,CACX,GAAI,GAAGP,CAAE,KACT,OAAQY,EACR,MAAOX,EACP,IAAKA,EAAQQ,EACb,MAAOV,EAAM,OAAS,uBACtB,MAAOA,EAAM,OAAS,EACtB,QAASA,EAAM,SAAW,OAC9B,CAAG,EAGD,MAAMgB,EAAa,KAAK,MAAMV,EAAOF,IAAW,GAAKG,EAAOF,IAAW,CAAC,EAClEY,EAAW,KAAK,IAAID,EAAa,GAAK,GAAI,EAC1CE,EAAQ,KAAK,MAAMX,EAAOF,EAAQC,EAAOF,CAAM,EAC/Ce,EAAY,KAAK,GAAK,EAGtBC,EAAW,CACf,CAACd,EAAMC,CAAI,EACX,CACED,EAAOW,EAAW,KAAK,IAAIC,EAAQC,CAAS,EAC5CZ,EAAOU,EAAW,KAAK,IAAIC,EAAQC,CAAS,CAClD,CACA,EAGQE,EAAY,CAChB,CAACf,EAAMC,CAAI,EACX,CACED,EAAOW,EAAW,KAAK,IAAIC,EAAQC,CAAS,EAC5CZ,EAAOU,EAAW,KAAK,IAAIC,EAAQC,CAAS,CAClD,CACA,EAEQG,EAAYpB,EAAQQ,EACpBa,EAAeZ,EAAe,EAEpC,OAAAH,EAAQ,KAAK,CACX,GAAI,GAAGP,CAAE,KACT,OAAQmB,EACR,MAAOE,EACP,IAAKA,EAAYC,EACjB,MAAOvB,EAAM,OAAS,uBACtB,MAAOA,EAAM,OAAS,EACtB,QAASA,EAAM,SAAW,OAC9B,CAAG,EAEDQ,EAAQ,KAAK,CACX,GAAI,GAAGP,CAAE,KACT,OAAQoB,EACR,MAAOC,EACP,IAAKA,EAAYC,EACjB,MAAOvB,EAAM,OAAS,uBACtB,MAAOA,EAAM,OAAS,EACtB,QAASA,EAAM,SAAW,OAC9B,CAAG,EAEMQ,CACT"}
package/dist/index16.js CHANGED
@@ -1,107 +1,57 @@
1
- class w {
2
- /**
3
- * Creates a new StrokeDrawer instance
4
- *
5
- * @param {CanvasRenderingContext2D} ctx - Canvas 2D rendering context
6
- * @param {Object} viewport - Viewport dimensions for coordinate conversion
7
- * @param {number} viewport.width - Viewport width in pixels
8
- * @param {number} viewport.height - Viewport height in pixels
9
- */
10
- constructor(t, o) {
11
- this.ctx = t, this.viewport = o;
12
- }
13
- /**
14
- * Updates the viewport dimensions
15
- *
16
- * @param {Object} viewport - New viewport dimensions
17
- */
18
- setViewport(t) {
19
- this.viewport = t;
20
- }
21
- /**
22
- * Draws a stroke with optional progress for progressive reveal
23
- *
24
- * @param {Object} stroke - Stroke command object
25
- * @param {Array} stroke.points - Array of [x, y] normalized coordinates
26
- * @param {string} stroke.color - Stroke color (CSS color string)
27
- * @param {number} stroke.width - Base stroke width in pixels
28
- * @param {Array} [stroke.pressures] - Optional pressure values for variable width
29
- * @param {number} [progress=1.0] - Progress from 0 to 1 (for progressive reveal)
30
- */
31
- drawStroke(t, o = 1) {
32
- const { points: i, color: e, width: s, pressures: h } = t;
33
- if (!i || i.length < 2) return;
34
- const n = Math.max(2, Math.floor(i.length * o)), r = i.slice(0, n);
35
- this.ctx.strokeStyle = e || "rgba(0, 0, 0, 0.5)", this.ctx.lineCap = "round", this.ctx.lineJoin = "round", h && h.length >= r.length ? this._drawVariableWidthStroke(r, s, h.slice(0, n)) : this._drawConstantWidthStroke(r, s);
36
- }
37
- /**
38
- * Draws a stroke with constant width
39
- *
40
- * @private
41
- * @param {Array} points - Array of [x, y] normalized coordinates
42
- * @param {number} width - Stroke width in pixels
43
- */
44
- _drawConstantWidthStroke(t, o) {
45
- this.ctx.lineWidth = o || 2, this.ctx.beginPath();
46
- for (let i = 0; i < t.length; i++) {
47
- const [e, s] = this._normalizedToPixel(t[i]);
48
- i === 0 ? this.ctx.moveTo(e, s) : this.ctx.lineTo(e, s);
49
- }
50
- this.ctx.stroke();
51
- }
52
- /**
53
- * Draws a stroke with variable width based on pressure
54
- *
55
- * Uses multiple line segments with varying widths for natural pen feel.
56
- *
57
- * @private
58
- * @param {Array} points - Array of [x, y] normalized coordinates
59
- * @param {number} baseWidth - Base stroke width in pixels
60
- * @param {Array} pressures - Pressure values (0-1) for each point
61
- */
62
- _drawVariableWidthStroke(t, o, i) {
63
- for (let e = 1; e < t.length; e++) {
64
- const [s, h] = this._normalizedToPixel(t[e - 1]), [n, r] = this._normalizedToPixel(t[e]), l = i[e - 1] || 1, c = i[e] || 1, a = (l + c) / 2, x = Math.max(0.5, o * a);
65
- this.ctx.lineWidth = x, this.ctx.beginPath(), this.ctx.moveTo(s, h), this.ctx.lineTo(n, r), this.ctx.stroke();
66
- }
67
- }
68
- /**
69
- * Draws a single point (dot)
70
- *
71
- * Useful for single-point strokes or debugging.
72
- *
73
- * @param {number} x - Normalized x coordinate (0-1)
74
- * @param {number} y - Normalized y coordinate (0-1)
75
- * @param {number} radius - Dot radius in pixels
76
- * @param {string} color - Fill color
77
- */
78
- drawPoint(t, o, i, e) {
79
- const [s, h] = this._normalizedToPixel([t, o]);
80
- this.ctx.fillStyle = e || "rgba(0, 0, 0, 0.5)", this.ctx.beginPath(), this.ctx.arc(s, h, i, 0, Math.PI * 2), this.ctx.fill();
81
- }
82
- /**
83
- * Clears the entire canvas
84
- */
85
- clear() {
86
- const t = window.devicePixelRatio || 1;
87
- this.ctx.clearRect(0, 0, this.viewport.width * t, this.viewport.height * t);
88
- }
89
- /**
90
- * Converts normalized coordinates (0-1) to pixel coordinates
91
- *
92
- * @private
93
- * @param {Array} point - [x, y] normalized coordinates
94
- * @returns {Array} [x, y] pixel coordinates
95
- */
96
- _normalizedToPixel(t) {
97
- const [o, i] = t;
98
- return [
99
- o * this.viewport.width,
100
- i * this.viewport.height
101
- ];
102
- }
1
+ function S(b, t) {
2
+ const { id: u, start: a, end: C, from_x: i, from_y: r, to_x: n, to_y: o } = b;
3
+ if (typeof i != "number" || typeof r != "number" || typeof n != "number" || typeof o != "number")
4
+ return [];
5
+ const s = [], l = C - a, f = l * 0.7, D = l * 0.3, g = 20, m = [];
6
+ for (let p = 0; p <= g; p++) {
7
+ const M = p / g;
8
+ m.push([
9
+ i + (n - i) * M,
10
+ r + (o - r) * M
11
+ ]);
12
+ }
13
+ s.push({
14
+ id: `${u}-0`,
15
+ points: m,
16
+ start: a,
17
+ end: a + f,
18
+ color: t.color || "rgba(255, 0, 0, 0.8)",
19
+ width: t.width || 2,
20
+ lineCap: t.lineCap || "round"
21
+ });
22
+ const _ = Math.sqrt((n - i) ** 2 + (o - r) ** 2), e = Math.min(_ * 0.2, 0.03), c = Math.atan2(o - r, n - i), h = Math.PI / 6, x = [
23
+ [n, o],
24
+ [
25
+ n - e * Math.cos(c - h),
26
+ o - e * Math.sin(c - h)
27
+ ]
28
+ ], P = [
29
+ [n, o],
30
+ [
31
+ n - e * Math.cos(c + h),
32
+ o - e * Math.sin(c + h)
33
+ ]
34
+ ], d = a + f, w = D / 2;
35
+ return s.push({
36
+ id: `${u}-1`,
37
+ points: x,
38
+ start: d,
39
+ end: d + w,
40
+ color: t.color || "rgba(255, 0, 0, 0.8)",
41
+ width: t.width || 2,
42
+ lineCap: t.lineCap || "round"
43
+ }), s.push({
44
+ id: `${u}-2`,
45
+ points: P,
46
+ start: d,
47
+ end: d + w,
48
+ color: t.color || "rgba(255, 0, 0, 0.8)",
49
+ width: t.width || 2,
50
+ lineCap: t.lineCap || "round"
51
+ }), s;
103
52
  }
104
53
  export {
105
- w as default
54
+ S as arrowToStrokes,
55
+ S as default
106
56
  };
107
57
  //# sourceMappingURL=index16.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index16.js","sources":["../src/pen/StrokeDrawer.js"],"sourcesContent":["/**\n * StrokeDrawer - Low-level canvas stroke drawing utilities\n *\n * Handles the actual drawing of strokes on canvas with support for:\n * - Progressive stroke reveal (partial drawing based on progress)\n * - Normalized to pixel coordinate conversion\n * - Variable width based on pressure data\n * - Smooth line rendering with round caps/joins\n */\nclass StrokeDrawer {\n /**\n * Creates a new StrokeDrawer instance\n *\n * @param {CanvasRenderingContext2D} ctx - Canvas 2D rendering context\n * @param {Object} viewport - Viewport dimensions for coordinate conversion\n * @param {number} viewport.width - Viewport width in pixels\n * @param {number} viewport.height - Viewport height in pixels\n */\n constructor(ctx, viewport) {\n this.ctx = ctx;\n this.viewport = viewport;\n }\n\n /**\n * Updates the viewport dimensions\n *\n * @param {Object} viewport - New viewport dimensions\n */\n setViewport(viewport) {\n this.viewport = viewport;\n }\n\n /**\n * Draws a stroke with optional progress for progressive reveal\n *\n * @param {Object} stroke - Stroke command object\n * @param {Array} stroke.points - Array of [x, y] normalized coordinates\n * @param {string} stroke.color - Stroke color (CSS color string)\n * @param {number} stroke.width - Base stroke width in pixels\n * @param {Array} [stroke.pressures] - Optional pressure values for variable width\n * @param {number} [progress=1.0] - Progress from 0 to 1 (for progressive reveal)\n */\n drawStroke(stroke, progress = 1.0) {\n const { points, color, width, pressures } = stroke;\n\n if (!points || points.length < 2) return;\n\n // Calculate how many points to draw based on progress\n const pointCount = Math.max(2, Math.floor(points.length * progress));\n const visiblePoints = points.slice(0, pointCount);\n\n // Configure stroke style\n this.ctx.strokeStyle = color || 'rgba(0, 0, 0, 0.5)';\n this.ctx.lineCap = 'round';\n this.ctx.lineJoin = 'round';\n\n // Draw with variable width if pressures provided\n if (pressures && pressures.length >= visiblePoints.length) {\n this._drawVariableWidthStroke(visiblePoints, width, pressures.slice(0, pointCount));\n } else {\n this._drawConstantWidthStroke(visiblePoints, width);\n }\n }\n\n /**\n * Draws a stroke with constant width\n *\n * @private\n * @param {Array} points - Array of [x, y] normalized coordinates\n * @param {number} width - Stroke width in pixels\n */\n _drawConstantWidthStroke(points, width) {\n this.ctx.lineWidth = width || 2;\n this.ctx.beginPath();\n\n for (let i = 0; i < points.length; i++) {\n const [px, py] = this._normalizedToPixel(points[i]);\n\n if (i === 0) {\n this.ctx.moveTo(px, py);\n } else {\n this.ctx.lineTo(px, py);\n }\n }\n\n this.ctx.stroke();\n }\n\n /**\n * Draws a stroke with variable width based on pressure\n *\n * Uses multiple line segments with varying widths for natural pen feel.\n *\n * @private\n * @param {Array} points - Array of [x, y] normalized coordinates\n * @param {number} baseWidth - Base stroke width in pixels\n * @param {Array} pressures - Pressure values (0-1) for each point\n */\n _drawVariableWidthStroke(points, baseWidth, pressures) {\n for (let i = 1; i < points.length; i++) {\n const [x1, y1] = this._normalizedToPixel(points[i - 1]);\n const [x2, y2] = this._normalizedToPixel(points[i]);\n\n // Average pressure between two points\n const p1 = pressures[i - 1] || 1;\n const p2 = pressures[i] || 1;\n const avgPressure = (p1 + p2) / 2;\n\n // Apply pressure to width (min 0.5, max 2x base width)\n const width = Math.max(0.5, baseWidth * avgPressure);\n\n this.ctx.lineWidth = width;\n this.ctx.beginPath();\n this.ctx.moveTo(x1, y1);\n this.ctx.lineTo(x2, y2);\n this.ctx.stroke();\n }\n }\n\n /**\n * Draws a single point (dot)\n *\n * Useful for single-point strokes or debugging.\n *\n * @param {number} x - Normalized x coordinate (0-1)\n * @param {number} y - Normalized y coordinate (0-1)\n * @param {number} radius - Dot radius in pixels\n * @param {string} color - Fill color\n */\n drawPoint(x, y, radius, color) {\n const [px, py] = this._normalizedToPixel([x, y]);\n\n this.ctx.fillStyle = color || 'rgba(0, 0, 0, 0.5)';\n this.ctx.beginPath();\n this.ctx.arc(px, py, radius, 0, Math.PI * 2);\n this.ctx.fill();\n }\n\n /**\n * Clears the entire canvas\n */\n clear() {\n const dpr = window.devicePixelRatio || 1;\n this.ctx.clearRect(0, 0, this.viewport.width * dpr, this.viewport.height * dpr);\n }\n\n /**\n * Converts normalized coordinates (0-1) to pixel coordinates\n *\n * @private\n * @param {Array} point - [x, y] normalized coordinates\n * @returns {Array} [x, y] pixel coordinates\n */\n _normalizedToPixel(point) {\n const [normX, normY] = point;\n return [\n normX * this.viewport.width,\n normY * this.viewport.height\n ];\n }\n}\n\nexport default StrokeDrawer;\n"],"names":["StrokeDrawer","ctx","viewport","stroke","progress","points","color","width","pressures","pointCount","visiblePoints","px","py","baseWidth","i","x1","y1","x2","y2","p1","p2","avgPressure","x","y","radius","dpr","point","normX","normY"],"mappings":"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"}
1
+ {"version":3,"file":"index16.js","sources":["../src/converters/arrow.js"],"sourcesContent":["/**\n * Arrow Converter - Converts arrow annotations to stroke commands\n *\n * Transforms arrow data into a line stroke with arrowhead strokes\n * that can be rendered progressively on canvas.\n *\n * @module converters/arrow\n */\n\n/**\n * Converts an arrow annotation to stroke commands\n *\n * Creates a main line stroke from source to target, followed by\n * two wing strokes forming the arrowhead. Line draws first (70%),\n * then arrowhead (30%).\n *\n * @param {Object} annotation - Arrow annotation object\n * @param {string} annotation.id - Unique identifier\n * @param {number} annotation.start - Start time in seconds\n * @param {number} annotation.end - End time in seconds\n * @param {number} annotation.from_x - Source x position (0-1 normalized)\n * @param {number} annotation.from_y - Source y position (0-1 normalized)\n * @param {number} annotation.to_x - Target x position (0-1 normalized)\n * @param {number} annotation.to_y - Target y position (0-1 normalized)\n * @param {Object} [annotation.style] - Optional style overrides\n * @param {Object} style - Resolved style configuration\n * @param {string} style.color - Stroke color\n * @param {number} style.width - Stroke width in pixels\n * @param {string} [style.lineCap='round'] - Line cap style\n * @returns {Array<Object>} Array of stroke commands\n */\nexport function arrowToStrokes(annotation, style) {\n const { id, start, end, from_x, from_y, to_x, to_y } = annotation;\n\n if (typeof from_x !== 'number' || typeof from_y !== 'number' ||\n typeof to_x !== 'number' || typeof to_y !== 'number') {\n return [];\n }\n\n const strokes = [];\n const totalDuration = end - start;\n const lineDuration = totalDuration * 0.7;\n const headDuration = totalDuration * 0.3;\n\n // Subdivide line for smooth progressive reveal\n const numPoints = 20;\n const linePoints = [];\n for (let i = 0; i <= numPoints; i++) {\n const t = i / numPoints;\n linePoints.push([\n from_x + (to_x - from_x) * t,\n from_y + (to_y - from_y) * t\n ]);\n }\n\n // Main line stroke\n strokes.push({\n id: `${id}-0`,\n points: linePoints,\n start: start,\n end: start + lineDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n // Arrow head calculation\n const lineLength = Math.sqrt((to_x - from_x) ** 2 + (to_y - from_y) ** 2);\n const headSize = Math.min(lineLength * 0.2, 0.03);\n const angle = Math.atan2(to_y - from_y, to_x - from_x);\n const headAngle = Math.PI / 6; // 30 degrees\n\n // Left wing\n const leftWing = [\n [to_x, to_y],\n [\n to_x - headSize * Math.cos(angle - headAngle),\n to_y - headSize * Math.sin(angle - headAngle)\n ]\n ];\n\n // Right wing\n const rightWing = [\n [to_x, to_y],\n [\n to_x - headSize * Math.cos(angle + headAngle),\n to_y - headSize * Math.sin(angle + headAngle)\n ]\n ];\n\n const headStart = start + lineDuration;\n const wingDuration = headDuration / 2;\n\n strokes.push({\n id: `${id}-1`,\n points: leftWing,\n start: headStart,\n end: headStart + wingDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n strokes.push({\n id: `${id}-2`,\n points: rightWing,\n start: headStart,\n end: headStart + wingDuration,\n color: style.color || 'rgba(255, 0, 0, 0.8)',\n width: style.width || 2,\n lineCap: style.lineCap || 'round'\n });\n\n return strokes;\n}\n\nexport default arrowToStrokes;\n"],"names":["arrowToStrokes","annotation","style","id","start","end","from_x","from_y","to_x","to_y","strokes","totalDuration","lineDuration","headDuration","numPoints","linePoints","i","t","lineLength","headSize","angle","headAngle","leftWing","rightWing","headStart","wingDuration"],"mappings":"AA+BO,SAASA,EAAeC,GAAYC,GAAO;AAChD,QAAM,EAAE,IAAAC,GAAI,OAAAC,GAAO,KAAAC,GAAK,QAAAC,GAAQ,QAAAC,GAAQ,MAAAC,GAAM,MAAAC,EAAI,IAAKR;AAEvD,MAAI,OAAOK,KAAW,YAAY,OAAOC,KAAW,YAChD,OAAOC,KAAS,YAAY,OAAOC,KAAS;AAC9C,WAAO,CAAA;AAGT,QAAMC,IAAU,CAAA,GACVC,IAAgBN,IAAMD,GACtBQ,IAAeD,IAAgB,KAC/BE,IAAeF,IAAgB,KAG/BG,IAAY,IACZC,IAAa,CAAA;AACnB,WAASC,IAAI,GAAGA,KAAKF,GAAWE,KAAK;AACnC,UAAMC,IAAID,IAAIF;AACd,IAAAC,EAAW,KAAK;AAAA,MACdT,KAAUE,IAAOF,KAAUW;AAAA,MAC3BV,KAAUE,IAAOF,KAAUU;AAAA,IACjC,CAAK;AAAA,EACH;AAGA,EAAAP,EAAQ,KAAK;AAAA,IACX,IAAI,GAAGP,CAAE;AAAA,IACT,QAAQY;AAAA,IACR,OAAOX;AAAA,IACP,KAAKA,IAAQQ;AAAA,IACb,OAAOV,EAAM,SAAS;AAAA,IACtB,OAAOA,EAAM,SAAS;AAAA,IACtB,SAASA,EAAM,WAAW;AAAA,EAC9B,CAAG;AAGD,QAAMgB,IAAa,KAAK,MAAMV,IAAOF,MAAW,KAAKG,IAAOF,MAAW,CAAC,GAClEY,IAAW,KAAK,IAAID,IAAa,KAAK,IAAI,GAC1CE,IAAQ,KAAK,MAAMX,IAAOF,GAAQC,IAAOF,CAAM,GAC/Ce,IAAY,KAAK,KAAK,GAGtBC,IAAW;AAAA,IACf,CAACd,GAAMC,CAAI;AAAA,IACX;AAAA,MACED,IAAOW,IAAW,KAAK,IAAIC,IAAQC,CAAS;AAAA,MAC5CZ,IAAOU,IAAW,KAAK,IAAIC,IAAQC,CAAS;AAAA,IAClD;AAAA,EACA,GAGQE,IAAY;AAAA,IAChB,CAACf,GAAMC,CAAI;AAAA,IACX;AAAA,MACED,IAAOW,IAAW,KAAK,IAAIC,IAAQC,CAAS;AAAA,MAC5CZ,IAAOU,IAAW,KAAK,IAAIC,IAAQC,CAAS;AAAA,IAClD;AAAA,EACA,GAEQG,IAAYpB,IAAQQ,GACpBa,IAAeZ,IAAe;AAEpC,SAAAH,EAAQ,KAAK;AAAA,IACX,IAAI,GAAGP,CAAE;AAAA,IACT,QAAQmB;AAAA,IACR,OAAOE;AAAA,IACP,KAAKA,IAAYC;AAAA,IACjB,OAAOvB,EAAM,SAAS;AAAA,IACtB,OAAOA,EAAM,SAAS;AAAA,IACtB,SAASA,EAAM,WAAW;AAAA,EAC9B,CAAG,GAEDQ,EAAQ,KAAK;AAAA,IACX,IAAI,GAAGP,CAAE;AAAA,IACT,QAAQoB;AAAA,IACR,OAAOC;AAAA,IACP,KAAKA,IAAYC;AAAA,IACjB,OAAOvB,EAAM,SAAS;AAAA,IACtB,OAAOA,EAAM,SAAS;AAAA,IACtB,SAASA,EAAM,WAAW;AAAA,EAC9B,CAAG,GAEMQ;AACT;"}
package/dist/index17.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e={name:"default",highlight:{color:"rgba(255, 255, 0, 0.3)",width:24},handText:{color:"rgba(220, 20, 60, 1.0)",width:2},ink:{color:"rgba(31, 41, 55, 1.0)",width:3}},r={name:"blue",highlight:{color:"rgba(100, 149, 237, 0.35)",width:24},handText:{color:"rgba(30, 64, 175, 1.0)",width:2},ink:{color:"rgba(30, 64, 175, 1.0)",width:3}},o={name:"minimal",highlight:{color:"rgba(156, 163, 175, 0.25)",width:20},handText:{color:"rgba(75, 85, 99, 1.0)",width:1.5},ink:{color:"rgba(75, 85, 99, 1.0)",width:2}},t={default:e,blue:r,minimal:o};function a(i){return t[i]||t.default}function l(){return Object.keys(t)}exports.BLUE_PRESET=r;exports.DEFAULT_PRESET=e;exports.MINIMAL_PRESET=o;exports.default=t;exports.getPreset=a;exports.getPresetNames=l;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function a(l,e){const{id:d,start:f,end:p,cx:o,cy:r,rx:n,ry:i}=l;if(typeof o!="number"||typeof r!="number"||typeof n!="number"||typeof i!="number")return[];const u=36,c=[];for(let t=0;t<=u;t++){const s=t/u*Math.PI*2;c.push([o+n*Math.cos(s),r+i*Math.sin(s)])}return[{id:d,points:c,start:f,end:p,color:e.color||"rgba(255, 165, 0, 0.8)",width:e.width||3,lineCap:e.lineCap||"round"}]}exports.circleToStrokes=a;exports.default=a;
2
2
  //# sourceMappingURL=index17.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index17.cjs","sources":["../src/pen/presets.js"],"sourcesContent":["/**\n * Client-side style presets for Digital Pen\n *\n * These presets mirror the backend presets and are used for\n * client-side preview or when backend presets aren't available.\n */\n\n/**\n * Default preset - Yellow highlights, crimson handwriting\n */\nexport const DEFAULT_PRESET = {\n name: 'default',\n highlight: {\n color: 'rgba(255, 255, 0, 0.3)',\n width: 24\n },\n handText: {\n color: 'rgba(220, 20, 60, 1.0)',\n width: 2\n },\n ink: {\n color: 'rgba(31, 41, 55, 1.0)',\n width: 3\n }\n};\n\n/**\n * Blue preset - Blue highlights and handwriting\n */\nexport const BLUE_PRESET = {\n name: 'blue',\n highlight: {\n color: 'rgba(100, 149, 237, 0.35)',\n width: 24\n },\n handText: {\n color: 'rgba(30, 64, 175, 1.0)',\n width: 2\n },\n ink: {\n color: 'rgba(30, 64, 175, 1.0)',\n width: 3\n }\n};\n\n/**\n * Minimal preset - Subtle gray, less visible effects\n */\nexport const MINIMAL_PRESET = {\n name: 'minimal',\n highlight: {\n color: 'rgba(156, 163, 175, 0.25)',\n width: 20\n },\n handText: {\n color: 'rgba(75, 85, 99, 1.0)',\n width: 1.5\n },\n ink: {\n color: 'rgba(75, 85, 99, 1.0)',\n width: 2\n }\n};\n\n/**\n * Preset registry\n */\nconst PRESETS = {\n default: DEFAULT_PRESET,\n blue: BLUE_PRESET,\n minimal: MINIMAL_PRESET\n};\n\n/**\n * Get a preset by name\n *\n * @param {string} name - Preset name\n * @returns {Object} Preset configuration\n */\nexport function getPreset(name) {\n return PRESETS[name] || PRESETS.default;\n}\n\n/**\n * Get all available preset names\n *\n * @returns {string[]} Array of preset names\n */\nexport function getPresetNames() {\n return Object.keys(PRESETS);\n}\n\nexport default PRESETS;\n"],"names":["DEFAULT_PRESET","BLUE_PRESET","MINIMAL_PRESET","PRESETS","getPreset","name","getPresetNames"],"mappings":"4GAUY,MAACA,EAAiB,CAC5B,KAAM,UACN,UAAW,CACT,MAAO,yBACP,MAAO,EACX,EACE,SAAU,CACR,MAAO,yBACP,MAAO,CACX,EACE,IAAK,CACH,MAAO,wBACP,MAAO,CACX,CACA,EAKaC,EAAc,CACzB,KAAM,OACN,UAAW,CACT,MAAO,4BACP,MAAO,EACX,EACE,SAAU,CACR,MAAO,yBACP,MAAO,CACX,EACE,IAAK,CACH,MAAO,yBACP,MAAO,CACX,CACA,EAKaC,EAAiB,CAC5B,KAAM,UACN,UAAW,CACT,MAAO,4BACP,MAAO,EACX,EACE,SAAU,CACR,MAAO,wBACP,MAAO,GACX,EACE,IAAK,CACH,MAAO,wBACP,MAAO,CACX,CACA,EAKMC,EAAU,CACd,QAASH,EACT,KAAMC,EACN,QAASC,CACX,EAQO,SAASE,EAAUC,EAAM,CAC9B,OAAOF,EAAQE,CAAI,GAAKF,EAAQ,OAClC,CAOO,SAASG,GAAiB,CAC/B,OAAO,OAAO,KAAKH,CAAO,CAC5B"}
1
+ {"version":3,"file":"index17.cjs","sources":["../src/converters/circle.js"],"sourcesContent":["/**\n * Circle Converter - Converts circle annotations to stroke commands\n *\n * Transforms circle/ellipse data into stroke paths that can be\n * rendered progressively on canvas.\n *\n * @module converters/circle\n */\n\n/**\n * Converts a circle annotation to stroke commands\n *\n * Generates an ellipse path from 0° to 360° that renders\n * progressively around the perimeter.\n *\n * @param {Object} annotation - Circle annotation object\n * @param {string} annotation.id - Unique identifier\n * @param {number} annotation.start - Start time in seconds\n * @param {number} annotation.end - End time in seconds\n * @param {number} annotation.cx - Center x position (0-1 normalized)\n * @param {number} annotation.cy - Center y position (0-1 normalized)\n * @param {number} annotation.rx - Horizontal radius (0-1 normalized)\n * @param {number} annotation.ry - Vertical radius (0-1 normalized)\n * @param {Object} [annotation.style] - Optional style overrides\n * @param {Object} style - Resolved style configuration\n * @param {string} style.color - Stroke color\n * @param {number} style.width - Stroke width in pixels\n * @param {string} [style.lineCap='round'] - Line cap style\n * @returns {Array<Object>} Array of stroke commands\n */\nexport function circleToStrokes(annotation, style) {\n const { id, start, end, cx, cy, rx, ry } = annotation;\n\n if (typeof cx !== 'number' || typeof cy !== 'number' ||\n typeof rx !== 'number' || typeof ry !== 'number') {\n return [];\n }\n\n // Generate ellipse points (36 segments + closing point)\n const numPoints = 36;\n const points = [];\n\n for (let i = 0; i <= numPoints; i++) {\n const angle = (i / numPoints) * Math.PI * 2;\n points.push([\n cx + rx * Math.cos(angle),\n cy + ry * Math.sin(angle)\n ]);\n }\n\n return [{\n id,\n points,\n start,\n end,\n color: style.color || 'rgba(255, 165, 0, 0.8)',\n width: style.width || 3,\n lineCap: style.lineCap || 'round'\n }];\n}\n\nexport default circleToStrokes;\n"],"names":["circleToStrokes","annotation","style","id","start","end","cx","cy","rx","ry","numPoints","points","i","angle"],"mappings":"4GA8BO,SAASA,EAAgBC,EAAYC,EAAO,CACjD,KAAM,CAAE,GAAAC,EAAI,MAAAC,EAAO,IAAAC,EAAK,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,CAAE,EAAKR,EAE3C,GAAI,OAAOK,GAAO,UAAY,OAAOC,GAAO,UACxC,OAAOC,GAAO,UAAY,OAAOC,GAAO,SAC1C,MAAO,CAAA,EAIT,MAAMC,EAAY,GACZC,EAAS,CAAA,EAEf,QAASC,EAAI,EAAGA,GAAKF,EAAWE,IAAK,CACnC,MAAMC,EAASD,EAAIF,EAAa,KAAK,GAAK,EAC1CC,EAAO,KAAK,CACVL,EAAKE,EAAK,KAAK,IAAIK,CAAK,EACxBN,EAAKE,EAAK,KAAK,IAAII,CAAK,CAC9B,CAAK,CACH,CAEA,MAAO,CAAC,CACN,GAAAV,EACA,OAAAQ,EACA,MAAAP,EACA,IAAAC,EACA,MAAOH,EAAM,OAAS,yBACtB,MAAOA,EAAM,OAAS,EACtB,QAASA,EAAM,SAAW,OAC9B,CAAG,CACH"}