kviewer 0.3.1 → 0.3.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 (55) hide show
  1. package/dist/module.d.mts +1 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +19 -15
  4. package/dist/runtime/annotation/engine/editor/editor.js +10 -12
  5. package/dist/runtime/annotation/engine/editor/selector.js +3 -1
  6. package/dist/runtime/annotation/engine/tools/arrow.js +24 -14
  7. package/dist/runtime/annotation/engine/tools/circle.js +24 -13
  8. package/dist/runtime/annotation/engine/tools/cloud.js +27 -18
  9. package/dist/runtime/annotation/engine/tools/free-highlight.js +24 -15
  10. package/dist/runtime/annotation/engine/tools/freehand.js +21 -12
  11. package/dist/runtime/annotation/engine/tools/highlight.d.ts +2 -0
  12. package/dist/runtime/annotation/engine/tools/highlight.js +20 -10
  13. package/dist/runtime/annotation/engine/tools/note.js +3 -1
  14. package/dist/runtime/annotation/engine/tools/rectangle.js +19 -8
  15. package/dist/runtime/annotation/engine/tools/signature.js +2 -1
  16. package/dist/runtime/annotation/engine/tools/stamp.js +2 -1
  17. package/dist/runtime/annotation/engine/utils.js +2 -1
  18. package/dist/runtime/annotation/pdf-export/download.js +1 -1
  19. package/dist/runtime/annotation/pdf-export/export-form-fields.js +20 -12
  20. package/dist/runtime/annotation/pdf-export/export.js +1 -1
  21. package/dist/runtime/annotation/pdf-export/parse_polyline.js +5 -1
  22. package/dist/runtime/annotation/pdf-export/parse_stamp.js +4 -4
  23. package/dist/runtime/annotation/pdf-export/print.d.ts +12 -0
  24. package/dist/runtime/annotation/pdf-export/print.js +63 -0
  25. package/dist/runtime/annotation/pdf-export/unicode-font.js +1 -4
  26. package/dist/runtime/annotation/pdf-import/decode_stamp.js +3 -2
  27. package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.js +1 -1
  28. package/dist/runtime/annotation/pdf-import/utils.js +1 -1
  29. package/dist/runtime/components/FormFieldLayer.d.vue.ts +1 -1
  30. package/dist/runtime/components/FormFieldLayer.vue.d.ts +1 -1
  31. package/dist/runtime/components/PdfPage.vue +3 -3
  32. package/dist/runtime/components/Viewer.d.vue.ts +10 -1
  33. package/dist/runtime/components/Viewer.vue +24 -2
  34. package/dist/runtime/components/Viewer.vue.d.ts +10 -1
  35. package/dist/runtime/components/ViewerTabs.vue +1 -1
  36. package/dist/runtime/components/panels/SignaturePicker.vue +8 -2
  37. package/dist/runtime/components/tools/ToolbarMenu.vue +17 -0
  38. package/dist/runtime/composables/useScriptingManager.d.ts +5 -0
  39. package/dist/runtime/composables/useScriptingManager.js +6 -0
  40. package/dist/runtime/composables/useSearchIndex.js +1 -1
  41. package/dist/runtime/composables/useViewerState.d.ts +2 -0
  42. package/dist/runtime/composables/useViewerState.js +8 -0
  43. package/dist/runtime/embed/bridge-client.d.ts +4 -0
  44. package/dist/runtime/embed/bridge-client.js +6 -0
  45. package/dist/runtime/embed/bridge-host.d.ts +11 -2
  46. package/dist/runtime/embed/bridge-host.js +104 -30
  47. package/dist/runtime/embed/protocol.d.ts +17 -0
  48. package/dist/runtime/embed/protocol.js +1 -0
  49. package/dist/runtime/i18n/messages.d.ts +2 -0
  50. package/dist/runtime/i18n/messages.js +2 -0
  51. package/dist/runtime/imports.d.ts +19 -0
  52. package/dist/runtime/public-types.d.ts +2 -2
  53. package/dist/runtime/public-types.js +4 -1
  54. package/dist/types.d.mts +1 -1
  55. package/package.json +2 -2
package/dist/module.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- export { ActiveTool, AddFormFieldPayload, CheckboxStyle, ExportPdfOptions, FormFieldDefinition, FormFieldOrigin, FormFieldType, FormFieldValue, KVIEWER_EMBED_PROTOCOL_VERSION, KViewerApi, KViewerEmbedBridgeOptions, KViewerEmbedClient, KViewerEmbedClientOptions, KViewerEmbedEventName, KViewerEmbedEventPayloads, KViewerEmbedMethodName, SignatureData, SignatureHandlers, ViewMode, ViewerBottomToolId, ViewerLayoutToolId, ViewerMenuButtonItem, ViewerMenuCheckboxItem, ViewerMenuItem, ViewerMenuSeparatorItem, ViewerState, ViewerToolEntry, ViewerToolId, ViewerToolSlot, ViewerTopToolId, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
2
+ export { ActiveTool, AddFormFieldPayload, CheckboxStyle, ExportPdfOptions, FormFieldDefinition, FormFieldOrigin, FormFieldType, FormFieldValue, KVIEWER_EMBED_PROTOCOL_VERSION, KVIEWER_EMBED_UNSUPPORTED_METHOD_ERROR_NAME, KViewerApi, KViewerEmbedBridgeOptions, KViewerEmbedClient, KViewerEmbedClientOptions, KViewerEmbedEventName, KViewerEmbedEventPayloads, KViewerEmbedMethodName, KViewerHostApi, PlacedFieldDefaults, SignatureData, SignatureFieldStatus, SignatureHandlers, ViewMode, ViewerBottomToolId, ViewerLayoutToolId, ViewerMenuButtonItem, ViewerMenuCheckboxItem, ViewerMenuItem, ViewerMenuSeparatorItem, ViewerState, ViewerToolEntry, ViewerToolId, ViewerToolSlot, ViewerTopToolId, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
3
3
 
4
4
  interface ModuleOptions {
5
5
  /**
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kviewer",
3
3
  "configKey": "kviewer",
4
- "version": "0.3.1",
4
+ "version": "0.3.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { defineNuxtModule, createResolver, extendViteConfig, addPlugin, addComponentsDir, addImports } from '@nuxt/kit';
4
- export { KVIEWER_EMBED_PROTOCOL_VERSION, KViewerEmbedClient, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
4
+ export { KVIEWER_EMBED_PROTOCOL_VERSION, KVIEWER_EMBED_UNSUPPORTED_METHOD_ERROR_NAME, KViewerEmbedClient, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
5
5
 
6
6
  const module$1 = defineNuxtModule({
7
7
  meta: {
@@ -34,19 +34,14 @@ const module$1 = defineNuxtModule({
34
34
  config.optimizeDeps ||= {};
35
35
  config.optimizeDeps.include ||= [];
36
36
  config.optimizeDeps.include.push(
37
- "konva",
38
- "pdf-lib",
39
- "pdfjs-dist/legacy/build/pdf.mjs",
40
- "pdfjs-dist/web/pdf_viewer.mjs",
41
- // unicode-font.ts registers @pdf-lib/fontkit for Unicode font
42
- // embedding. Its ESM build does `import pako from 'pako'`, but pako 1.x
43
- // is CJS with no `default` export so unless fontkit is pre-bundled
44
- // (where esbuild applies CJS interop and synthesizes the default), the
45
- // browser receives the raw pako index.js and throws "does not provide
46
- // an export named 'default'". The `kviewer >` prefix anchors resolution
47
- // through this module, so it works even when pnpm leaves fontkit
48
- // un-hoisted in the consumer (a bare '@pdf-lib/fontkit' entry would not
49
- // resolve from the consumer root and Vite would silently skip it).
37
+ "kviewer > konva",
38
+ "kviewer > pdf-lib",
39
+ "kviewer > pdfjs-dist/legacy/build/pdf.mjs",
40
+ "kviewer > pdfjs-dist/web/pdf_viewer.mjs",
41
+ // fontkit's ESM build does `import pako from 'pako'`, but pako 1.x is
42
+ // CJS with no `default` export without pre-bundling (where esbuild
43
+ // synthesizes it) the browser throws "does not provide an export named
44
+ // 'default'".
50
45
  "kviewer > @pdf-lib/fontkit"
51
46
  );
52
47
  });
@@ -56,6 +51,10 @@ const module$1 = defineNuxtModule({
56
51
  locale: options.locale ?? "en"
57
52
  };
58
53
  nuxt.options.css.push("pdfjs-dist/web/pdf_viewer.css");
54
+ const cssnano = nuxt.options.postcss?.plugins?.cssnano;
55
+ if (cssnano && typeof cssnano === "object" && !cssnano.preset) {
56
+ cssnano.preset = ["default", { svgo: false }];
57
+ }
59
58
  nuxt.options.css.push(resolve("./runtime/assets/kviewer.css"));
60
59
  addPlugin(resolve("./runtime/plugin"));
61
60
  addComponentsDir({
@@ -67,7 +66,12 @@ const module$1 = defineNuxtModule({
67
66
  addImports([
68
67
  { name: "useKViewerEmbedBridge", from: resolve("./runtime/embed/bridge-host") },
69
68
  { name: "KViewerEmbedClient", from: resolve("./runtime/embed/bridge-client") },
70
- { name: "KVIEWER_EMBED_PROTOCOL_VERSION", from: resolve("./runtime/embed/protocol") }
69
+ { name: "KVIEWER_EMBED_PROTOCOL_VERSION", from: resolve("./runtime/embed/protocol") },
70
+ {
71
+ name: "UNSUPPORTED_METHOD_ERROR_NAME",
72
+ as: "KVIEWER_EMBED_UNSUPPORTED_METHOD_ERROR_NAME",
73
+ from: resolve("./runtime/embed/protocol")
74
+ }
71
75
  ]);
72
76
  const require_ = createRequire(import.meta.url);
73
77
  const pdfjsDir = dirname(require_.resolve("pdfjs-dist/package.json"));
@@ -57,18 +57,14 @@ export class Editor {
57
57
  id,
58
58
  pageNumber,
59
59
  konvaString: konvaGroup.toJSON(),
60
- // Do NOT use konvaGroup.getClientRect() directly here — it includes the
61
- // stage's zoom scale, which would inflate annotation coordinates in the
62
- // exported PDF. We divide by scale to get page-space coordinates.
60
+ // Do NOT use konvaGroup.getClientRect() without relativeTo here — it is
61
+ // in absolute stage coordinates, which bake in the stage's zoom scale
62
+ // AND the windowed stage position (setStageWindow shifts stage.position
63
+ // at high zoom). relativeTo undoes both, yielding page-space
64
+ // coordinates regardless of the zoom state at placement time.
63
65
  konvaClientRect: (() => {
64
- const scale = konvaGroup.getStage()?.scaleX() ?? 1;
65
- const raw = konvaGroup.getClientRect();
66
- return {
67
- x: raw.x / scale,
68
- y: raw.y / scale,
69
- width: raw.width / scale,
70
- height: raw.height / scale
71
- };
66
+ const stage = konvaGroup.getStage();
67
+ return stage ? konvaGroup.getClientRect({ relativeTo: stage }) : konvaGroup.getClientRect();
72
68
  })(),
73
69
  title: this.userName,
74
70
  type: annotation.type,
@@ -144,7 +140,9 @@ export class Editor {
144
140
  this.konvaStage.off("click mousedown mousemove mouseup touchstart touchmove touchend");
145
141
  }
146
142
  getBgLayer(konvaStage) {
147
- return konvaStage ? konvaStage.getLayers()[0] : this.konvaStage.getLayers()[0];
143
+ const layer = konvaStage ? konvaStage.getLayers()[0] : this.konvaStage.getLayers()[0];
144
+ if (!layer) throw new Error("Annotation stage has no background layer");
145
+ return layer;
148
146
  }
149
147
  delShapeGroup(id) {
150
148
  this.shapeGroupStore.delete(id);
@@ -99,7 +99,9 @@ export class Selector {
99
99
  });
100
100
  }
101
101
  getBackgroundLayer(konvaStage) {
102
- return konvaStage.getLayers()[0];
102
+ const layer = konvaStage.getLayers()[0];
103
+ if (!layer) throw new Error("Annotation stage has no background layer");
104
+ return layer;
103
105
  }
104
106
  getPageShapeGroups(konvaStage) {
105
107
  return this.getBackgroundLayer(konvaStage).getChildren(
@@ -13,17 +13,21 @@ export class EditorArrow extends Editor {
13
13
  }
14
14
  mouseDownHandler(e) {
15
15
  if (e.currentTarget !== this.konvaStage) return;
16
+ const pos = this.konvaStage.getRelativePointerPosition();
17
+ const annotation = this.currentAnnotation;
18
+ const style = annotation?.style;
19
+ if (!pos || !annotation || !style) return;
16
20
  this.arrow = null;
17
21
  this.isPainting = true;
18
- this.currentShapeGroup = this.createShapeGroup();
19
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
20
- const pos = this.konvaStage.getRelativePointerPosition();
22
+ const shapeGroup = this.createShapeGroup();
23
+ this.currentShapeGroup = shapeGroup;
24
+ this.getBgLayer().add(shapeGroup.konvaGroup);
21
25
  this.startPoint = { x: pos.x, y: pos.y };
22
26
  this.arrow = new Konva.Arrow({
23
27
  points: [pos.x, pos.y, pos.x, pos.y],
24
- stroke: this.currentAnnotation.style.color,
25
- strokeWidth: this.currentAnnotation.style.strokeWidth,
26
- fill: this.currentAnnotation.style.color,
28
+ stroke: style.color,
29
+ strokeWidth: style.strokeWidth,
30
+ fill: style.color,
27
31
  pointerLength: 10,
28
32
  pointerWidth: 10,
29
33
  hitStrokeWidth: 20,
@@ -31,15 +35,16 @@ export class EditorArrow extends Editor {
31
35
  lineCap: "round",
32
36
  lineJoin: "round",
33
37
  visible: false,
34
- opacity: this.currentAnnotation.style.opacity
38
+ opacity: style.opacity
35
39
  });
36
- this.currentShapeGroup.konvaGroup.add(this.arrow);
40
+ shapeGroup.konvaGroup.add(this.arrow);
37
41
  window.addEventListener("mouseup", this.globalPointerUpHandler);
38
42
  }
39
43
  mouseMoveHandler(e) {
40
44
  if (!this.isPainting) return;
41
45
  e.evt.preventDefault();
42
46
  const pos = this.konvaStage.getRelativePointerPosition();
47
+ if (!pos) return;
43
48
  const points = [this.startPoint.x, this.startPoint.y, pos.x, pos.y];
44
49
  this.arrow?.show();
45
50
  this.arrow?.setAttrs({ points });
@@ -47,20 +52,24 @@ export class EditorArrow extends Editor {
47
52
  mouseUpHandler() {
48
53
  if (!this.isPainting) return;
49
54
  this.isPainting = false;
50
- const group = this.arrow?.getParent();
51
- if (!this.arrow?.isVisible() && group?.getType() === "Group") {
55
+ const arrow = this.arrow;
56
+ const group = arrow?.getParent();
57
+ if (!arrow || !group) return;
58
+ if (!arrow.isVisible() && group.getType() === "Group") {
52
59
  this.delShapeGroup(group.id());
53
60
  return;
54
61
  }
55
62
  if (this.isTooShort()) {
56
- this.arrow?.destroy();
63
+ arrow.destroy();
57
64
  this.delShapeGroup(group.id());
58
65
  this.arrow = null;
59
66
  return;
60
67
  }
68
+ const style = this.currentAnnotation?.style;
69
+ if (!style) return;
61
70
  this.setShapeGroupDone({
62
71
  id: group.id(),
63
- color: this.currentAnnotation.style.color,
72
+ color: style.color,
64
73
  contentsObj: {
65
74
  text: ""
66
75
  }
@@ -76,8 +85,9 @@ export class EditorArrow extends Editor {
76
85
  if (!this.arrow) return true;
77
86
  const points = this.arrow.points();
78
87
  if (points.length !== 4) return true;
79
- const dx = points[2] - points[0];
80
- const dy = points[3] - points[1];
88
+ const [x1, y1, x2, y2] = points;
89
+ const dx = x2 - x1;
90
+ const dy = y2 - y1;
81
91
  return Math.hypot(dx, dy) < Editor.MinSize;
82
92
  }
83
93
  /**
@@ -23,11 +23,15 @@ export class EditorCircle extends Editor {
23
23
  if (e.currentTarget !== this.konvaStage) {
24
24
  return;
25
25
  }
26
+ const pos = this.konvaStage.getRelativePointerPosition();
27
+ const annotation = this.currentAnnotation;
28
+ const style = annotation?.style;
29
+ if (!pos || !annotation || !style) return;
26
30
  this.ellipse = null;
27
31
  this.isPainting = true;
28
- this.currentShapeGroup = this.createShapeGroup();
29
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
30
- const pos = this.konvaStage.getRelativePointerPosition();
32
+ const shapeGroup = this.createShapeGroup();
33
+ this.currentShapeGroup = shapeGroup;
34
+ this.getBgLayer().add(shapeGroup.konvaGroup);
31
35
  this.vertex = { x: pos.x, y: pos.y };
32
36
  this.ellipse = new Konva.Ellipse({
33
37
  radiusX: 0,
@@ -36,14 +40,14 @@ export class EditorCircle extends Editor {
36
40
  y: pos.y,
37
41
  visible: false,
38
42
  // Start hidden
39
- stroke: this.currentAnnotation.style.color,
43
+ stroke: style.color,
40
44
  // Set the ellipse stroke color
41
- strokeWidth: this.currentAnnotation.style.strokeWidth,
45
+ strokeWidth: style.strokeWidth,
42
46
  // Set the ellipse stroke width
43
- opacity: this.currentAnnotation.style.opacity
47
+ opacity: style.opacity
44
48
  // Set the ellipse opacity
45
49
  });
46
- this.currentShapeGroup.konvaGroup.add(this.ellipse);
50
+ shapeGroup.konvaGroup.add(this.ellipse);
47
51
  window.addEventListener("mouseup", this.globalPointerUpHandler);
48
52
  }
49
53
  /**
@@ -55,8 +59,10 @@ export class EditorCircle extends Editor {
55
59
  return;
56
60
  }
57
61
  e.evt.preventDefault();
58
- this.ellipse.show();
59
62
  const pos = this.konvaStage.getRelativePointerPosition();
63
+ const ellipse = this.ellipse;
64
+ if (!pos || !ellipse) return;
65
+ ellipse.show();
60
66
  const radiusX = Math.abs(pos.x - this.vertex.x) / 2;
61
67
  const radiusY = Math.abs(pos.y - this.vertex.y) / 2;
62
68
  const areaAttr = {
@@ -65,7 +71,7 @@ export class EditorCircle extends Editor {
65
71
  radiusX,
66
72
  radiusY
67
73
  };
68
- this.ellipse.setAttrs(areaAttr);
74
+ ellipse.setAttrs(areaAttr);
69
75
  }
70
76
  /**
71
77
  * Handles mouse or touch pointer-up events and finishes drawing the ellipse.
@@ -75,20 +81,24 @@ export class EditorCircle extends Editor {
75
81
  return;
76
82
  }
77
83
  this.isPainting = false;
78
- const group = this.ellipse.getParent();
79
- if (!this.ellipse.isVisible() && group.getType() === "Group") {
84
+ const ellipse = this.ellipse;
85
+ const group = ellipse?.getParent();
86
+ if (!ellipse || !group) return;
87
+ if (!ellipse.isVisible() && group.getType() === "Group") {
80
88
  this.delShapeGroup(group.id());
81
89
  return;
82
90
  }
83
91
  if (this.isTooSmall()) {
84
- this.ellipse.destroy();
92
+ ellipse.destroy();
85
93
  this.delShapeGroup(group.id());
86
94
  this.ellipse = null;
87
95
  return;
88
96
  }
97
+ const style = this.currentAnnotation?.style;
98
+ if (!style) return;
89
99
  this.setShapeGroupDone({
90
100
  id: group.id(),
91
- color: this.currentAnnotation.style.color,
101
+ color: style.color,
92
102
  contentsObj: {
93
103
  text: ""
94
104
  }
@@ -109,6 +119,7 @@ export class EditorCircle extends Editor {
109
119
  * @returns True if the ellipse width or height is smaller than the minimum size, otherwise false.
110
120
  */
111
121
  isTooSmall() {
122
+ if (!this.ellipse) return true;
112
123
  const { width, height } = this.ellipse.size();
113
124
  return Math.max(width, height) < Editor.MinSize;
114
125
  }
@@ -35,23 +35,27 @@ export class EditorCloud extends Editor {
35
35
  }
36
36
  mouseDownHandler(_e) {
37
37
  const pos = this.konvaStage.getRelativePointerPosition();
38
+ const annotation = this.currentAnnotation;
39
+ const style = annotation?.style;
40
+ if (!pos || !annotation || !style) return;
38
41
  this.points.push(pos);
39
42
  if (!this.isPainting) {
40
43
  this.isPainting = true;
41
- this.currentShapeGroup = this.createShapeGroup();
42
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
44
+ const shapeGroup = this.createShapeGroup();
45
+ this.currentShapeGroup = shapeGroup;
46
+ this.getBgLayer().add(shapeGroup.konvaGroup);
43
47
  this.cloudPath = new Konva.Path({
44
48
  data: "",
45
- stroke: this.currentAnnotation.style.color,
46
- strokeWidth: this.currentAnnotation.style.strokeWidth,
49
+ stroke: style.color,
50
+ strokeWidth: style.strokeWidth,
47
51
  fillEnabled: false,
48
52
  lineJoin: "round",
49
53
  lineCap: "round",
50
54
  hitStrokeWidth: 20,
51
55
  // Set the hit detection width
52
- opacity: this.currentAnnotation.style.opacity
56
+ opacity: style.opacity
53
57
  });
54
- this.currentShapeGroup.konvaGroup.add(this.cloudPath);
58
+ shapeGroup.konvaGroup.add(this.cloudPath);
55
59
  this.drawStartRect(pos);
56
60
  }
57
61
  this.updateCloudPreview();
@@ -59,6 +63,7 @@ export class EditorCloud extends Editor {
59
63
  mouseMoveHandler(_e) {
60
64
  if (!this.isPainting || !this.cloudPath) return;
61
65
  const pos = this.konvaStage.getRelativePointerPosition();
66
+ if (!pos) return;
62
67
  this.updateCloudPreview(pos);
63
68
  }
64
69
  mouseUpHandler(_e) {
@@ -73,9 +78,12 @@ export class EditorCloud extends Editor {
73
78
  const closedPoints = [...this.points, this.points[0]];
74
79
  const pathData = this.generateCloudPathData(closedPoints);
75
80
  this.cloudPath.data(pathData);
81
+ const shapeGroup = this.currentShapeGroup;
82
+ const style = this.currentAnnotation?.style;
83
+ if (!shapeGroup || !style) return;
76
84
  this.setShapeGroupDone({
77
- id: this.currentShapeGroup.konvaGroup.id(),
78
- color: this.currentAnnotation.style.color,
85
+ id: shapeGroup.konvaGroup.id(),
86
+ color: style.color,
79
87
  contentsObj: { text: "" }
80
88
  });
81
89
  this.cloudPath = null;
@@ -179,7 +187,7 @@ export class EditorCloud extends Editor {
179
187
  height: this.startRectSize,
180
188
  stroke: "#000",
181
189
  strokeWidth: 2,
182
- fill: null,
190
+ fillEnabled: false,
183
191
  cornerRadius: 2,
184
192
  hitStrokeWidth: 10,
185
193
  // Increase the hit detection area
@@ -187,26 +195,27 @@ export class EditorCloud extends Editor {
187
195
  dash: [4, 2],
188
196
  name: "startRect"
189
197
  });
190
- this.getBgLayer().add(this.startRect);
191
- this.startRect.moveToTop();
192
- this.startRect.on(
198
+ const startRect = this.startRect;
199
+ this.getBgLayer().add(startRect);
200
+ startRect.moveToTop();
201
+ startRect.on(
193
202
  "mouseup",
194
203
  (_e) => {
195
204
  this.handleDoubleClick();
196
205
  }
197
206
  );
198
- this.startRect.on(
207
+ startRect.on(
199
208
  "mousemove",
200
209
  (_e) => {
201
- this.startRect.stroke("#1677ff");
202
- this.startRect.getLayer()?.batchDraw();
210
+ startRect.stroke("#1677ff");
211
+ startRect.getLayer()?.batchDraw();
203
212
  }
204
213
  );
205
- this.startRect.on(
214
+ startRect.on(
206
215
  "mouseout",
207
216
  (_e) => {
208
- this.startRect.stroke("#000");
209
- this.startRect.getLayer()?.batchDraw();
217
+ startRect.stroke("#000");
218
+ startRect.getLayer()?.batchDraw();
210
219
  }
211
220
  );
212
221
  }
@@ -16,16 +16,20 @@ export class EditorFreeHighlight extends Editor {
16
16
  if (e.currentTarget !== this.konvaStage) {
17
17
  return;
18
18
  }
19
+ const pos = this.konvaStage.getRelativePointerPosition();
20
+ const annotation = this.currentAnnotation;
21
+ const style = annotation?.style;
22
+ if (!pos || !annotation || !style) return;
19
23
  this.line = null;
20
24
  this.isPainting = true;
21
- this.currentShapeGroup = this.createShapeGroup();
22
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
23
- const pos = this.konvaStage.getRelativePointerPosition();
25
+ const shapeGroup = this.createShapeGroup();
26
+ this.currentShapeGroup = shapeGroup;
27
+ this.getBgLayer().add(shapeGroup.konvaGroup);
24
28
  this.line = new Konva.Line({
25
- stroke: this.currentAnnotation.style.color,
26
- strokeWidth: this.currentAnnotation.style.strokeWidth,
27
- opacity: this.currentAnnotation.style.opacity,
28
- hitStrokeWidth: this.currentAnnotation.style.strokeWidth,
29
+ stroke: style.color,
30
+ strokeWidth: style.strokeWidth,
31
+ opacity: style.opacity,
32
+ hitStrokeWidth: style.strokeWidth,
29
33
  lineCap: "round",
30
34
  lineJoin: "round",
31
35
  visible: false,
@@ -33,7 +37,7 @@ export class EditorFreeHighlight extends Editor {
33
37
  points: [pos.x, pos.y]
34
38
  // Initialize the starting point
35
39
  });
36
- this.currentShapeGroup.konvaGroup.add(this.line);
40
+ shapeGroup.konvaGroup.add(this.line);
37
41
  window.addEventListener("mouseup", this.globalPointerUpHandler);
38
42
  }
39
43
  /**
@@ -45,10 +49,12 @@ export class EditorFreeHighlight extends Editor {
45
49
  return;
46
50
  }
47
51
  e.evt.preventDefault();
48
- this.line.show();
49
52
  const pos = this.konvaStage.getRelativePointerPosition();
50
- const newPoints = this.line.points().concat([pos.x, pos.y]);
51
- this.line.points(newPoints);
53
+ const line = this.line;
54
+ if (!pos || !line) return;
55
+ line.show();
56
+ const newPoints = line.points().concat([pos.x, pos.y]);
57
+ line.points(newPoints);
52
58
  }
53
59
  /**
54
60
  * Handles mouse or touch pointer-up events and finishes drawing the freeform curve.
@@ -58,8 +64,9 @@ export class EditorFreeHighlight extends Editor {
58
64
  return;
59
65
  }
60
66
  this.isPainting = false;
61
- const group = this.line?.getParent();
62
- if (group && !this.line.isVisible() && group.getType() === "Group") {
67
+ const line = this.line;
68
+ const group = line?.getParent();
69
+ if (group && line && !line.isVisible() && group.getType() === "Group") {
63
70
  this.delShapeGroup(group.id());
64
71
  return;
65
72
  }
@@ -71,13 +78,14 @@ export class EditorFreeHighlight extends Editor {
71
78
  this.line = null;
72
79
  return;
73
80
  }
74
- if (this.line) {
81
+ const style = this.currentAnnotation?.style;
82
+ if (this.line && group && style) {
75
83
  const originalPoints = this.line.points();
76
84
  const correctedPoints = this.correctLineIfStraight(originalPoints);
77
85
  this.line.points(correctedPoints);
78
86
  this.setShapeGroupDone({
79
87
  id: group.id(),
80
- color: this.currentAnnotation.style.color,
88
+ color: style.color,
81
89
  contentsObj: {
82
90
  text: ""
83
91
  }
@@ -100,6 +108,7 @@ export class EditorFreeHighlight extends Editor {
100
108
  * @returns The corrected points
101
109
  */
102
110
  correctLineIfStraight(points) {
111
+ if (points.length < 4) return points;
103
112
  const THRESHOLD_ANGLE_DEGREES = 2;
104
113
  const startX = points[0];
105
114
  const startY = points[1];
@@ -20,6 +20,10 @@ export class EditorFreeHand extends Editor {
20
20
  if (e.currentTarget !== this.konvaStage) {
21
21
  return;
22
22
  }
23
+ const pos = this.konvaStage.getRelativePointerPosition();
24
+ const annotation = this.currentAnnotation;
25
+ const style = annotation?.style;
26
+ if (!pos || !annotation || !style) return;
23
27
  Editor.TimerClear(this.pageNumber);
24
28
  this.line = null;
25
29
  this.isPainting = true;
@@ -27,13 +31,12 @@ export class EditorFreeHand extends Editor {
27
31
  this.currentShapeGroup = this.createShapeGroup();
28
32
  this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
29
33
  }
30
- const pos = this.konvaStage.getRelativePointerPosition();
31
34
  this.line = new Konva.Line({
32
- stroke: this.currentAnnotation.style.color,
35
+ stroke: style.color,
33
36
  // Set the line color
34
- strokeWidth: this.currentAnnotation.style.strokeWidth,
37
+ strokeWidth: style.strokeWidth,
35
38
  // Set the line width
36
- opacity: this.currentAnnotation.style.opacity,
39
+ opacity: style.opacity,
37
40
  // Set the line opacity
38
41
  lineCap: "round",
39
42
  // Set rounded line caps
@@ -59,10 +62,12 @@ export class EditorFreeHand extends Editor {
59
62
  return;
60
63
  }
61
64
  e.evt.preventDefault();
62
- this.line.show();
63
65
  const pos = this.konvaStage.getRelativePointerPosition();
64
- const newPoints = this.line.points().concat([pos.x, pos.y]);
65
- this.line.points(newPoints);
66
+ const line = this.line;
67
+ if (!pos || !line) return;
68
+ line.show();
69
+ const newPoints = line.points().concat([pos.x, pos.y]);
70
+ line.points(newPoints);
66
71
  }
67
72
  /**
68
73
  * Handles mouse or touch pointer-up events and finishes drawing the freeform curve.
@@ -72,13 +77,17 @@ export class EditorFreeHand extends Editor {
72
77
  return;
73
78
  }
74
79
  this.isPainting = false;
75
- const group = this.line.getParent();
80
+ const line = this.line;
81
+ const group = line?.getParent();
82
+ const style = this.currentAnnotation?.style;
83
+ if (!line || !group || !style) return;
84
+ const color = style.color;
76
85
  if (this.isTooSmall()) {
77
- this.line.destroy();
86
+ line.destroy();
78
87
  Editor.TimerStart(this.pageNumber, () => {
79
88
  this.setShapeGroupDone({
80
89
  id: group.id(),
81
- color: this.currentAnnotation.style.color,
90
+ color,
82
91
  contentsObj: {
83
92
  text: ""
84
93
  }
@@ -90,7 +99,7 @@ export class EditorFreeHand extends Editor {
90
99
  Editor.TimerStart(this.pageNumber, () => {
91
100
  this.setShapeGroupDone({
92
101
  id: group.id(),
93
- color: this.currentAnnotation.style.color,
102
+ color,
94
103
  contentsObj: {
95
104
  text: ""
96
105
  }
@@ -113,7 +122,7 @@ export class EditorFreeHand extends Editor {
113
122
  * @returns True if the line point count is less than 5, otherwise false
114
123
  */
115
124
  isTooSmall() {
116
- return this.line.points().length < Editor.MinSize;
125
+ return !this.line || this.line.points().length < Editor.MinSize;
117
126
  }
118
127
  /**
119
128
  * @description Update annotation styles
@@ -5,6 +5,8 @@ import { Editor, type IEditorOptions } from '../editor/editor.js';
5
5
  * EditorHighLight is a highlight editor class that extends Editor.
6
6
  */
7
7
  export declare class EditorHighLight extends Editor {
8
+ private get activeAnnotation();
9
+ private get activeStyle();
8
10
  /**
9
11
  * Creates an EditorHighLight instance.
10
12
  * @param EditorOptions Options used to initialize the editor