mirador-annotation-editor-video 1.0.81 → 1.0.94

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 (59) hide show
  1. package/demo/src/index.js +3 -4
  2. package/demo/src/manifestsCatalog.js +2 -10
  3. package/es/CanvasListItem.js +2 -3
  4. package/es/IIIFUtils.js +65 -14
  5. package/es/annotationForm/AnnotationForm.js +15 -1
  6. package/es/annotationForm/AnnotationFormBody.js +13 -15
  7. package/es/annotationForm/AnnotationFormOverlay/AnnotationDrawing.js +3 -2
  8. package/es/annotationForm/AnnotationFormOverlay/AnnotationFormOverlayTool.js +2 -2
  9. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/KonvaUtils.js +21 -3
  10. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/CircleNode.js +6 -1
  11. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/EllipseNode.js +6 -1
  12. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/ParentComponent.js +13 -4
  13. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/Polygon.js +6 -1
  14. package/es/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/Rectangle.js +2 -1
  15. package/es/annotationForm/AnnotationFormUtils.js +15 -3
  16. package/es/annotationForm/DrawingTemplate.js +4 -2
  17. package/es/annotationForm/HMSInput.js +3 -3
  18. package/es/annotationForm/ImageCommentTemplate.js +3 -2
  19. package/es/annotationForm/ManifestNetworkFormSection.js +4 -20
  20. package/es/annotationForm/MultiTagsInput.js +109 -0
  21. package/es/annotationForm/MultipleBodyTemplate.js +160 -0
  22. package/es/annotationForm/NetworkCommentTemplate.js +1 -1
  23. package/es/custom.css +129 -0
  24. package/es/locales/locales_en.js +2 -0
  25. package/es/locales/locales_fr.js +2 -0
  26. package/es/playerReferences.js +44 -9
  27. package/package.json +4 -3
  28. package/src/CanvasListItem.js +1 -2
  29. package/src/IIIFUtils.js +78 -18
  30. package/src/annotationForm/AnnotationForm.js +19 -2
  31. package/src/annotationForm/AnnotationFormBody.js +78 -83
  32. package/src/annotationForm/AnnotationFormOverlay/AnnotationDrawing.js +3 -2
  33. package/src/annotationForm/AnnotationFormOverlay/AnnotationFormOverlayTool.js +40 -43
  34. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/KonvaUtils.js +32 -3
  35. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/CircleNode.js +6 -1
  36. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/EllipseNode.js +6 -1
  37. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/ParentComponent.js +9 -0
  38. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/Polygon.js +6 -1
  39. package/src/annotationForm/AnnotationFormOverlay/KonvaDrawing/shapes/Rectangle.js +2 -1
  40. package/src/annotationForm/AnnotationFormUtils.js +14 -2
  41. package/src/annotationForm/DrawingTemplate.js +4 -0
  42. package/src/annotationForm/HMSInput.js +3 -3
  43. package/src/annotationForm/ImageCommentTemplate.js +2 -1
  44. package/src/annotationForm/ManifestNetworkFormSection.js +4 -18
  45. package/src/annotationForm/MultiTagsInput.js +111 -0
  46. package/src/annotationForm/MultipleBodyTemplate.js +175 -0
  47. package/src/annotationForm/NetworkCommentTemplate.js +1 -1
  48. package/src/custom.css +129 -0
  49. package/src/locales/locales_en.js +2 -0
  50. package/src/locales/locales_fr.js +2 -0
  51. package/src/playerReferences.js +50 -8
  52. package/src/plugins/annotationCreationCompanionWindow.js +19 -7
  53. package/dist/mirador-annotation-editor.css +0 -6
  54. package/dist/mirador-annotation-editor.es.js +0 -54434
  55. package/dist/mirador-annotation-editor.es.js.map +0 -1
  56. package/dist/mirador-annotation-editor.js +0 -466
  57. package/dist/mirador-annotation-editor.js.map +0 -1
  58. package/es/annotationForm/Debug.js +0 -143
  59. package/src/annotationForm/Debug.js +0 -202
package/demo/src/index.js CHANGED
@@ -6,7 +6,9 @@ import { manifestsCatalog } from './manifestsCatalog';
6
6
  const config = {
7
7
  annotation: {
8
8
  adapter: (canvasId) => new LocalStorageAdapter(`localStorage://?canvasId=${canvasId}`, 'Anonymous User'),
9
+ commentTemplate: '<h4>Comment</h4><p>comment content</p>',
9
10
  exportLocalStorageAnnotations: false, // display annotation JSON export button
11
+ tagsSuggestions: ['Mirador', 'Awesome', 'Viewer', 'IIIF'],
10
12
  },
11
13
  annotations: {
12
14
  htmlSanitizationRuleSet: 'liberal',
@@ -57,10 +59,7 @@ const config = {
57
59
  defaultSideBarPanel: 'annotations',
58
60
  sideBarOpenByDefault: true,
59
61
  },
60
- windows: [
61
- { manifestId: 'https://files.tetras-libre.fr/dev/sun-400x400.json' },
62
- { manifestId: 'https://resource.arvest.app/6b665140d80c98444a02f142c1a8fcb42d201940/8000x6000-Pogacar.json' },
63
- ],
62
+ windows: [],
64
63
  };
65
64
 
66
65
  mirador.viewer(config, [...annotationPlugins]);
@@ -8,14 +8,6 @@ export const manifestsCatalog = [
8
8
  { manifestId: 'https://iiif.harvardartmuseums.org/manifests/object/299843' },
9
9
  { manifestId: 'https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json' },
10
10
  { manifestId: 'https://files.tetras-libre.fr/dev/vertical_video_with_annot.json' },
11
- { manifestId: 'https://purl.stanford.edu/sn904cj3429/iiif/manifest' },
12
- { manifestId: 'https://coeso.tetras-libre.fr/data/coeso-deliverable/Manual_Network_Configuration.json' },
13
- { manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json' },
14
- { manifestId: 'https://resource.arvest.app/6b665140d80c98444a02f142c1a8fcb42d201940/8000x6000-Pogacar.json' },
15
- { manifestId: 'https://files.tetras-libre.fr/dev/multicanva-video.json' },
16
- { manifestId: 'https://dzkimgs.l.u-tokyo.ac.jp/videos/iiif_in_japan_2017/manifest.json' },
17
- { manifestId: 'https://iiif.io/api/cookbook/recipe/0219-using-caption-file/manifest.json' },
18
- { manifestId: 'https://preview.iiif.io/cookbook/master/recipe/0003-mvm-video/manifest.json' },
19
- { manifestId: 'https://iiif.io/api/cookbook/recipe/0065-opera-multiple-canvases/manifest.json' },
20
- { manifestId: 'https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/manifest.json' },
11
+ { manifestId: 'https://files.tetras-libre.fr/dev/youtube.json' },
12
+ { manifestId: 'https://files.tetras-libre.fr/dev/peertube.json' },
21
13
  ];
@@ -130,14 +130,13 @@ const CanvasListItem = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
130
130
  right: 0,
131
131
  zIndex: 10000
132
132
  }
133
- }, context.config?.debug && /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
133
+ }, context?.config?.debug && /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
134
134
  title: t('debugAnnotation')
135
135
  }, /*#__PURE__*/_react.default.createElement(_ToggleButton.default, {
136
136
  "aria-label": "Debug",
137
137
  onClick: () => console.log(annotationData) // TODO Open IIIIF debug window
138
138
  ,
139
- value: "Debug in console",
140
- visible: context.config.debug
139
+ value: "Debug in console"
141
140
  }, /*#__PURE__*/_react.default.createElement(_Settings.default, null))), /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
142
141
  title: /*#__PURE__*/_react.default.createElement(_WhoAndWhenFormSection.default, {
143
142
  creator: annotationData.creator,
package/es/IIIFUtils.js CHANGED
@@ -36,6 +36,8 @@ const convertAnnotationStateToBeSaved = async (annotationState, canvas, windowId
36
36
  if (annotationState.maeData.templateType === _AnnotationFormUtils.TEMPLATE.IIIF_TYPE) {
37
37
  return annotationState;
38
38
  }
39
+ console.info('Annotation state to be saved', annotationState);
40
+ console.info('Annotation state target', annotationState.maeData.target);
39
41
 
40
42
  // TODO I dont know why this code is here? To clean the object ?
41
43
  annotationStateForSaving.maeData.target = {
@@ -46,12 +48,21 @@ const convertAnnotationStateToBeSaved = async (annotationState, canvas, windowId
46
48
  tstart: annotationStateForSaving.maeData.target.tstart
47
49
  };
48
50
  console.info('Annotation state target', annotationState.maeData.target);
49
- if (annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.TAGGING_TYPE || annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.TEXT_TYPE) {
51
+ if (annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.TAGGING_TYPE || annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.TEXT_TYPE || annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.MANIFEST_TYPE || annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.MULTIPLE_BODY_TYPE) {
50
52
  // Complex annotation
51
53
  if (annotationStateForSaving.maeData.target.drawingState.shapes.length > 0) {
52
54
  annotationStateForSaving.maeData.target.svg = await (0, _KonvaUtils.getSvg)(windowId);
53
55
  }
54
56
  }
57
+ if (annotationStateForSaving.maeData.templateType === _AnnotationFormUtils.TEMPLATE.MULTIPLE_BODY_TYPE) {
58
+ annotationStateForSaving.body = [annotationState.maeData.textBody];
59
+ annotationStateForSaving.body.push(...annotationState.maeData.tags.map(tag => ({
60
+ purpose: 'tagging',
61
+ type: 'TextualBody',
62
+ value: tag.text,
63
+ id: tag.id
64
+ })));
65
+ }
55
66
  if (isAnnotationExportableToImage(annotationStateForSaving.maeData)) {
56
67
  annotationStateForSaving.body.id = await (0, _KonvaUtils.getKonvaAsDataURL)(windowId);
57
68
  annotationStateForSaving.body.format = 'image/jpg';
@@ -64,8 +75,6 @@ const convertAnnotationStateToBeSaved = async (annotationState, canvas, windowId
64
75
  annotationStateForSaving.type = 'Annotation';
65
76
  }
66
77
  }
67
-
68
- // eslint-disable-next-line no-param-reassign
69
78
  annotationStateForSaving.maeData.target.scale = playerReferences.getMediaTrueHeight() / playerReferences.getDisplayedMediaHeight() * playerReferences.getZoom();
70
79
  annotationStateForSaving.target = getIIIFTargetFromMaeData(annotationStateForSaving.maeData, canvas.id, windowId, playerReferences.getScale());
71
80
  annotationStateForSaving.maeData.target.drawingState = JSON.stringify(annotationStateForSaving.maeData.target.drawingState);
@@ -88,19 +97,21 @@ const getIIIFTargetFromMaeData = (maeData, canvasId, windowId = null, playerScal
88
97
  switch (templateType) {
89
98
  case _AnnotationFormUtils.TEMPLATE.IIIF_TYPE:
90
99
  return maeTarget;
100
+ case _AnnotationFormUtils.TEMPLATE.KONVA_TYPE:
101
+ return getIIIFTargetFromKonvaType(maeData, canvasId);
102
+ case _AnnotationFormUtils.TEMPLATE.IMAGE_TYPE:
103
+ return getIIIFTargetFromImageType(maeData, canvasId, windowId, playerScale);
91
104
  case _AnnotationFormUtils.TEMPLATE.TAGGING_TYPE:
105
+ case _AnnotationFormUtils.TEMPLATE.MANIFEST_TYPE:
106
+ case _AnnotationFormUtils.TEMPLATE.MULTIPLE_BODY_TYPE:
92
107
  case _AnnotationFormUtils.TEMPLATE.TEXT_TYPE:
93
- // Note, tagging or Manifest network template
94
- if (templateType === _AnnotationFormUtils.TEMPLATE.TAGGING_TYPE || templateType === _AnnotationFormUtils.TEMPLATE.TEXT_TYPE) {
95
- // In some case the target can be simplified in a string
96
- if (maeTarget.drawingState.shapes.length === 1 && maeTarget.drawingState.shapes[0].type === _KonvaUtils.SHAPES_TOOL.RECTANGLE) {
97
- return getIIIFTargetFromRectangleShape(maeTarget, canvasId, maeTarget.drawingState.shapes[0]);
98
- }
99
- // On the other case, the target is a SVG
100
- console.info('Implement target as SVG/Fragment with shapes');
101
- return getIIIFTargetAsFragmentSVGSelector(maeTarget, canvasId);
108
+ // In some case the target can be simplified in a string
109
+ if (maeTarget.drawingState.shapes.length === 1 && maeTarget.drawingState.shapes[0].type === _KonvaUtils.SHAPES_TOOL.RECTANGLE) {
110
+ return getIIIFTargetFromRectangleShape(maeTarget, canvasId, maeTarget.drawingState.shapes[0]);
102
111
  }
103
- break;
112
+ // On the other case, the target is a SVG
113
+ console.info('Implement target as SVG/Fragment with shapes');
114
+ return getIIIFTargetAsFragmentSVGSelector(maeTarget, canvasId);
104
115
  default:
105
116
  return getIIIFTargetFullCanvas(maeData, canvasId);
106
117
  }
@@ -110,12 +121,52 @@ const getIIIFTargetFromMaeData = (maeData, canvasId, windowId = null, playerScal
110
121
  };
111
122
 
112
123
  /**
113
- * Get the IIIF target from the full canvas
124
+ * Get the IIIF target from a Konva annotation (Drawing template)
114
125
  * @param maeData
115
126
  * @param canvasId
116
127
  * @returns {`${string}#${string}`}
117
128
  */
118
129
  exports.getIIIFTargetFromMaeData = getIIIFTargetFromMaeData;
130
+ const getIIIFTargetFromKonvaType = (maeData, canvasId) => {
131
+ // Simplified target for Konva annotation
132
+ console.log('Implement target as string with Konva annotation');
133
+ return getIIIFTargetFullCanvas(maeData, canvasId);
134
+ };
135
+
136
+ /**
137
+ * Get the IIIF target from an annotation with image template
138
+ * @param maeData
139
+ * @param canvasId
140
+ * @param windowId
141
+ * @param playerScale
142
+ * @returns {string}
143
+ */
144
+ const getIIIFTargetFromImageType = (maeData, canvasId, windowId, playerScale) => {
145
+ const maeTarget = maeData.target;
146
+ if (maeTarget.drawingState.shapes.length === 1) {
147
+ if (maeTarget.drawingState.shapes[0].type === _KonvaUtils.OVERLAY_TOOL.IMAGE) {
148
+ const {
149
+ x,
150
+ y
151
+ } = maeTarget.drawingState.shapes[0];
152
+ const imageShape = (0, _KonvaUtils.getKonvaShape)(windowId, maeTarget.drawingState.shapes[0].id);
153
+ const widthImage = Math.round(imageShape.attrs.image.width * imageShape.attrs.scaleX);
154
+ const heightImage = Math.round(imageShape.attrs.image.height * imageShape.attrs.scaleY);
155
+ const xImage = Math.round(x);
156
+ const yImage = Math.round(y);
157
+ return `${canvasId}#${maeTarget.tend ? `xywh=${xImage},${yImage},${widthImage},${heightImage}&t=${maeTarget.tstart},${maeTarget.tend}` : `xywh=${xImage},${yImage},${widthImage},${heightImage}`}`;
158
+ }
159
+ }
160
+ // Default return. For example if no image is upload in the annotation
161
+ return getIIIFTargetFullCanvas(maeData, canvasId);
162
+ };
163
+
164
+ /**
165
+ * Get the IIIF target from the full canvas
166
+ * @param maeData
167
+ * @param canvasId
168
+ * @returns {`${string}#${string}`}
169
+ */
119
170
  const getIIIFTargetFullCanvas = (maeData, canvasId) => {
120
171
  console.info('Implement target as string on fullSizeCanvas.');
121
172
  const maeTarget = maeData.target;
@@ -38,6 +38,16 @@ function AnnotationForm({
38
38
  const [templateType, setTemplateType] = (0, _react.useState)(null);
39
39
  // eslint-disable-next-line no-underscore-dangle
40
40
  const [mediaType, setMediaType] = (0, _react.useState)(playerReferences.getMediaType());
41
+ const [containerWidth, setContainerWidth] = (0, _react.useState)(0);
42
+ const [retryCount, setRetryCount] = (0, _react.useState)(0);
43
+ const [, forceUpdate] = (0, _react.useReducer)(x => x + 1, 0);
44
+ if (!playerReferences.isInitializedCorrectly() && retryCount < 10) {
45
+ console.log('AnnotationForm.js: retryCount', retryCount);
46
+ setTimeout(() => {
47
+ setRetryCount(retryCount + 1);
48
+ forceUpdate();
49
+ }, 100);
50
+ }
41
51
 
42
52
  // Add a state to trigger redraw
43
53
  const [windowSize, setWindowSize] = (0, _react.useState)({
@@ -91,7 +101,10 @@ function AnnotationForm({
91
101
  window.removeEventListener('resize', handleResize);
92
102
  };
93
103
  }, []);
94
- if (!playerReferences?.isInitializedCorrectly()) {
104
+ if (!playerReferences.isInitCorrectly) {
105
+ playerReferences.isInitializedCorrectly();
106
+ }
107
+ if (!playerReferences.isInitCorrectly) {
95
108
  return /*#__PURE__*/_react.default.createElement(_CompanionWindow.default, {
96
109
  title: t('media_not_supported'),
97
110
  windowId: windowId,
@@ -165,6 +178,7 @@ function AnnotationForm({
165
178
  annotation: annotation,
166
179
  canvases: canvases,
167
180
  closeFormCompanionWindow: closeFormCompanionWindow,
181
+ config: config,
168
182
  debugMode: debugMode,
169
183
  playerReferences: playerReferences,
170
184
  saveAnnotation: saveAnnotation,
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = AnnotationFormBody;
7
- var _react = _interopRequireWildcard(require("react"));
7
+ var _react = _interopRequireDefault(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _styles = require("@mui/material/styles");
10
10
  var _material = require("@mui/material");
@@ -17,10 +17,8 @@ var _DrawingTemplate = _interopRequireDefault(require("./DrawingTemplate"));
17
17
  var _IIIFTemplate = _interopRequireDefault(require("./IIIFTemplate"));
18
18
  var _TaggingTemplate = _interopRequireDefault(require("./TaggingTemplate"));
19
19
  require("./debug.css");
20
- var _AdvancedAnnotationEditor = require("./AdvancedAnnotationEditor");
20
+ var _MultipleBodyTemplate = _interopRequireDefault(require("./MultipleBodyTemplate"));
21
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
23
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
24
22
  /**
25
23
  * This function contain the logic for loading annotation and render proper template type
26
24
  * * */
@@ -28,6 +26,7 @@ function AnnotationFormBody({
28
26
  annotation,
29
27
  canvases,
30
28
  closeFormCompanionWindow,
29
+ config,
31
30
  debugMode,
32
31
  playerReferences,
33
32
  saveAnnotation,
@@ -35,11 +34,10 @@ function AnnotationFormBody({
35
34
  templateType,
36
35
  windowId
37
36
  }) {
38
- const [showAdvanced, setShowAdvanced] = (0, _react.useState)(false);
39
37
  return /*#__PURE__*/_react.default.createElement(_material.Grid, {
40
38
  container: true,
41
39
  direction: "column"
42
- }, !showAdvanced && /*#__PURE__*/_react.default.createElement(TemplateContainer, {
40
+ }, /*#__PURE__*/_react.default.createElement(TemplateContainer, {
43
41
  item: true
44
42
  }, templateType.id === _AnnotationFormUtils.TEMPLATE.TEXT_TYPE && /*#__PURE__*/_react.default.createElement(_TextCommentTemplate.default, {
45
43
  annotation: annotation,
@@ -83,17 +81,15 @@ function AnnotationFormBody({
83
81
  saveAnnotation: saveAnnotation,
84
82
  t: t,
85
83
  windowId: windowId
86
- })), /*#__PURE__*/_react.default.createElement(_material.Grid, {
87
- item: true
88
- }, showAdvanced && /*#__PURE__*/_react.default.createElement(_AdvancedAnnotationEditor.AdvancedAnnotationEditor, {
89
- value: annotation,
90
- onChange: updatedAnnotation => {
91
- // eslint-disable-next-line no-param-reassign
92
- annotation = updatedAnnotation;
93
- },
84
+ }), templateType.id === _AnnotationFormUtils.TEMPLATE.MULTIPLE_BODY_TYPE && /*#__PURE__*/_react.default.createElement(_MultipleBodyTemplate.default, {
85
+ annotation: annotation,
94
86
  closeFormCompanionWindow: closeFormCompanionWindow,
87
+ playerReferences: playerReferences,
95
88
  saveAnnotation: saveAnnotation,
96
- t: t
89
+ t: t,
90
+ windowId: windowId,
91
+ commentTemplate: config?.annotation?.commentTemplate ?? '',
92
+ tagsSuggestions: config?.annotation?.tagsSuggestions ?? []
97
93
  })), debugMode && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Typography.default, null, playerReferences.getMediaType()), /*#__PURE__*/_react.default.createElement(_Typography.default, null, t('scale'), ":", playerReferences.getScale()), /*#__PURE__*/_react.default.createElement(_Typography.default, null, t('zoom'), ":", playerReferences.getZoom()), /*#__PURE__*/_react.default.createElement(_Typography.default, null, t('image_true_size'), ":", playerReferences.getMediaTrueWidth(), ' ', "x", playerReferences.getMediaTrueHeight()), /*#__PURE__*/_react.default.createElement(_Typography.default, null, t('container_size'), ":", playerReferences.getContainerWidth(), ' ', "x", playerReferences.getContainerHeight()), /*#__PURE__*/_react.default.createElement(_Typography.default, null, t('image_displayed'), ":", playerReferences.getDisplayedMediaWidth(), ' ', "x", playerReferences.getDisplayedMediaHeight())));
98
94
  }
99
95
  const TemplateContainer = (0, _styles.styled)(_material.Grid)({
@@ -113,6 +109,8 @@ AnnotationFormBody.propTypes = {
113
109
  // eslint-disable-next-line react/forbid-prop-types
114
110
  canvases: _propTypes.default.object.isRequired,
115
111
  closeFormCompanionWindow: _propTypes.default.func.isRequired,
112
+ // eslint-disable-next-line react/forbid-prop-types
113
+ config: _propTypes.default.object.isRequired,
116
114
  debugMode: _propTypes.default.bool.isRequired,
117
115
  // eslint-disable-next-line react/forbid-prop-types
118
116
  playerReferences: _propTypes.default.object.isRequired,
@@ -46,7 +46,7 @@ function AnnotationDrawing({
46
46
  rotation: 0,
47
47
  scaleX: 0.2,
48
48
  scaleY: 0.2,
49
- type: _KonvaUtils.SHAPES_TOOL.IMAGE,
49
+ type: _KonvaUtils.OVERLAY_TOOL.IMAGE,
50
50
  url: toolState.imageEvent.id,
51
51
  x: 60,
52
52
  y: 60
@@ -196,7 +196,7 @@ function AnnotationDrawing({
196
196
  const modifiedShape = evt.target.attrs;
197
197
  const shape = drawingState.shapes.find(s => s.id === modifiedShape.id);
198
198
  Object.assign(shape, modifiedShape);
199
- if (shape.type === _KonvaUtils.SHAPES_TOOL.IMAGE) {
199
+ if (shape.type === _KonvaUtils.OVERLAY_TOOL.IMAGE) {
200
200
  shape.width = modifiedShape.image.width * modifiedShape.scaleX;
201
201
  shape.height = modifiedShape.image.height * modifiedShape.scaleY;
202
202
  }
@@ -522,6 +522,7 @@ function AnnotationDrawing({
522
522
  id: windowId
523
523
  }, /*#__PURE__*/_react.default.createElement(_ParentComponent.default, {
524
524
  activeTool: toolState.activeTool,
525
+ baseStrokeWidth: playerReferences.getTargetStrokeWidth(),
525
526
  displayMode: displayMode,
526
527
  handleDragEnd: handleDragEnd,
527
528
  handleDragStart: handleDragStart,
@@ -88,7 +88,7 @@ function AnnotationFormOverlayTool({
88
88
  onChange: changeTool,
89
89
  "aria-label": t('tool_selection'),
90
90
  size: "small"
91
- }, /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
91
+ }, displayMode !== _KonvaUtils.KONVA_MODE.IMAGE && /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
92
92
  title: t('rectangle')
93
93
  }, /*#__PURE__*/_react.default.createElement(_ToggleButton.default, {
94
94
  value: _KonvaUtils.SHAPES_TOOL.RECTANGLE,
@@ -98,7 +98,7 @@ function AnnotationFormOverlayTool({
98
98
  }, /*#__PURE__*/_react.default.createElement(_ToggleButton.default, {
99
99
  value: _KonvaUtils.SHAPES_TOOL.CIRCLE,
100
100
  "aria-label": t('add_a_circle')
101
- }, /*#__PURE__*/_react.default.createElement(_RadioButtonUnchecked.default, null))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
101
+ }, /*#__PURE__*/_react.default.createElement(_RadioButtonUnchecked.default, null))), displayMode !== _KonvaUtils.KONVA_MODE.IMAGE && /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
102
102
  title: t('line')
103
103
  }, /*#__PURE__*/_react.default.createElement(_ToggleButton.default, {
104
104
  value: _KonvaUtils.SHAPES_TOOL.POLYGON,
@@ -32,7 +32,7 @@ function getKonvaStage(windowId) {
32
32
  * @param scale
33
33
  * @param hideAfterResize
34
34
  */
35
- function resizeKonvaStage(windowId, width, height, scale, hideAfterResize = true) {
35
+ function resizeKonvaStage(windowId, width, height, scale, hideAfterResize = true, scaleStrokeForPNGExport = false) {
36
36
  hideKonvaStage();
37
37
  const stage = getKonvaStage(windowId);
38
38
  stage.width(width);
@@ -41,6 +41,20 @@ function resizeKonvaStage(windowId, width, height, scale, hideAfterResize = true
41
41
  x: scale,
42
42
  y: scale
43
43
  });
44
+ if (scaleStrokeForPNGExport) {
45
+ stage.find('Rect').map(node => {
46
+ node.strokeWidth(node.strokeWidth() * scale);
47
+ });
48
+ stage.find('Line').map(node => {
49
+ node.strokeWidth(node.strokeWidth() * scale);
50
+ });
51
+ stage.find('Circle').map(node => {
52
+ node.strokeWidth(node.strokeWidth() * scale);
53
+ });
54
+ stage.find('Ellipse').map(node => {
55
+ node.strokeWidth(node.strokeWidth() * scale);
56
+ });
57
+ }
44
58
  if (!hideAfterResize) {
45
59
  showKonvaStage();
46
60
  }
@@ -69,7 +83,7 @@ function showKonvaStage() {
69
83
  */
70
84
  async function getSvg(windowId) {
71
85
  const stage = getKonvaStage(windowId);
72
- const exportStrokeWidth = 1;
86
+ const exportStrokeWidth = 3;
73
87
  stage.find('Transformer').forEach(node => node.destroy());
74
88
 
75
89
  /**
@@ -97,6 +111,9 @@ async function getSvg(windowId) {
97
111
  stage.find('Circle').map(node => {
98
112
  cleanNode(node);
99
113
  });
114
+ stage.find('Ellipse').map(node => {
115
+ cleanNode(node);
116
+ });
100
117
  let svg = await (0, _reactKonvaToSvg.exportStageSVG)(stage, false); // TODO clean
101
118
  svg = svg.replaceAll('"', '\'');
102
119
  return svg;
@@ -117,9 +134,10 @@ function getKonvaShape(windowId, shapeId) {
117
134
  /** Export the stage as a JPG image in a data url */
118
135
  async function getKonvaAsDataURL(windowId) {
119
136
  const stage = getKonvaStage(windowId);
137
+ stage.find('Transformer').forEach(node => node.visible(false));
120
138
  const dataURL = stage.toDataURL({
121
139
  mimeType: 'image/jpg',
122
- quality: 0.1
140
+ quality: 0.2
123
141
  });
124
142
  return dataURL;
125
143
  }
@@ -7,6 +7,7 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _reactKonva = require("react-konva");
10
+ var _KonvaUtils = require("../KonvaUtils");
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -16,6 +17,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
16
17
  */
17
18
  function CircleNode({
18
19
  activeTool,
20
+ baseStrokeWidth,
21
+ displayMode,
19
22
  handleDragEnd,
20
23
  handleDragStart,
21
24
  isSelected,
@@ -59,7 +62,7 @@ function CircleNode({
59
62
  // This line cause SVG export error
60
63
  ,
61
64
  strokeScaleEnabled: false,
62
- strokeWidth: shape.strokeWidth,
65
+ strokeWidth: displayMode === _KonvaUtils.KONVA_MODE.TARGET ? baseStrokeWidth : shape.strokeWidth,
63
66
  x: shape.x,
64
67
  y: shape.y
65
68
  }), /*#__PURE__*/_react.default.createElement(_reactKonva.Transformer, {
@@ -69,6 +72,8 @@ function CircleNode({
69
72
  }
70
73
  CircleNode.propTypes = {
71
74
  activeTool: _propTypes.default.string.isRequired,
75
+ baseStrokeWidth: _propTypes.default.number.isRequired,
76
+ displayMode: _propTypes.default.string.isRequired,
72
77
  handleDragEnd: _propTypes.default.func.isRequired,
73
78
  handleDragStart: _propTypes.default.func.isRequired,
74
79
  isSelected: _propTypes.default.bool.isRequired,
@@ -7,6 +7,7 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _reactKonva = require("react-konva");
10
+ var _KonvaUtils = require("../KonvaUtils");
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -16,6 +17,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
16
17
  */
17
18
  function EllipseNode({
18
19
  activeTool,
20
+ baseStrokeWidth,
21
+ displayMode,
19
22
  handleDragEnd,
20
23
  isSelected,
21
24
  onShapeClick,
@@ -58,7 +61,7 @@ function EllipseNode({
58
61
  scaleY: shape.scaleY,
59
62
  stroke: shape.stroke,
60
63
  strokeScaleEnabled: false,
61
- strokeWidth: shape.strokeWidth,
64
+ strokeWidth: displayMode === _KonvaUtils.KONVA_MODE.TARGET ? baseStrokeWidth : shape.strokeWidth,
62
65
  x: shape.x,
63
66
  y: shape.y
64
67
  }), /*#__PURE__*/_react.default.createElement(_reactKonva.Transformer, {
@@ -68,6 +71,8 @@ function EllipseNode({
68
71
  }
69
72
  EllipseNode.propTypes = {
70
73
  activeTool: _propTypes.default.string.isRequired,
74
+ baseStrokeWidth: _propTypes.default.number.isRequired,
75
+ displayMode: _propTypes.default.string.isRequired,
71
76
  handleDragEnd: _propTypes.default.func.isRequired,
72
77
  handleDragStart: _propTypes.default.func.isRequired,
73
78
  isSelected: _propTypes.default.bool.isRequired,
@@ -22,6 +22,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
22
22
  /** Loads Konva and display in function of their type */
23
23
  function ParentComponent({
24
24
  activeTool,
25
+ baseStrokeWidth,
25
26
  displayMode,
26
27
  handleDragEnd,
27
28
  handleDragStart,
@@ -62,7 +63,8 @@ function ParentComponent({
62
63
  onTransform,
63
64
  shape,
64
65
  key: shape.id,
65
- displayMode: displayMode
66
+ displayMode: displayMode,
67
+ baseStrokeWidth: baseStrokeWidth
66
68
  });
67
69
  case 'text':
68
70
  return /*#__PURE__*/_react.default.createElement(_TextNode.default, {
@@ -85,7 +87,9 @@ function ParentComponent({
85
87
  onShapeClick: handleShapeClick,
86
88
  onTransform,
87
89
  shape,
88
- key: shape.id
90
+ key: shape.id,
91
+ displayMode: displayMode,
92
+ baseStrokeWidth: baseStrokeWidth
89
93
  });
90
94
  case _KonvaUtils.SHAPES_TOOL.CIRCLE:
91
95
  return /*#__PURE__*/_react.default.createElement(_CircleNode.default, {
@@ -96,7 +100,9 @@ function ParentComponent({
96
100
  onShapeClick: handleShapeClick,
97
101
  onTransform,
98
102
  shape,
99
- key: shape.id
103
+ key: shape.id,
104
+ displayMode: displayMode,
105
+ baseStrokeWidth: baseStrokeWidth
100
106
  });
101
107
  case _KonvaUtils.SHAPES_TOOL.FREEHAND:
102
108
  return /*#__PURE__*/_react.default.createElement(_Freehand.default, {
@@ -118,7 +124,9 @@ function ParentComponent({
118
124
  onShapeClick: handleShapeClick,
119
125
  onTransform,
120
126
  shape,
121
- key: shape.id
127
+ key: shape.id,
128
+ displayMode: displayMode,
129
+ baseStrokeWidth: baseStrokeWidth
122
130
  });
123
131
  case _KonvaUtils.SHAPES_TOOL.ARROW:
124
132
  return /*#__PURE__*/_react.default.createElement(_ArrowNode.default, {
@@ -148,6 +156,7 @@ function ParentComponent({
148
156
  }
149
157
  ParentComponent.propTypes = {
150
158
  activeTool: _propTypes.default.string.isRequired,
159
+ baseStrokeWidth: _propTypes.default.number.isRequired,
151
160
  displayMode: _propTypes.default.string.isRequired,
152
161
  handleDragEnd: _propTypes.default.func.isRequired,
153
162
  handleDragStart: _propTypes.default.func.isRequired,
@@ -7,12 +7,15 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _reactKonva = require("react-konva");
10
+ var _KonvaUtils = require("../KonvaUtils");
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
14
  /** FreeHand shape displaying */
14
15
  function Polygon({
15
16
  activeTool,
17
+ baseStrokeWidth,
18
+ displayMode,
16
19
  handleDragEnd,
17
20
  handleDragStart,
18
21
  isSelected,
@@ -61,7 +64,7 @@ function Polygon({
61
64
  // This line cause SVG export error
62
65
  ,
63
66
  strokeScaleEnabled: false,
64
- strokeWidth: shape.strokeWidth,
67
+ strokeWidth: displayMode === _KonvaUtils.KONVA_MODE.TARGET ? baseStrokeWidth : shape.strokeWidth,
65
68
  x: shape.x,
66
69
  y: shape.y
67
70
  }), /*#__PURE__*/_react.default.createElement(_reactKonva.Transformer, {
@@ -71,6 +74,8 @@ function Polygon({
71
74
  }
72
75
  Polygon.propTypes = {
73
76
  activeTool: _propTypes.default.string.isRequired,
77
+ baseStrokeWidth: _propTypes.default.number.isRequired,
78
+ displayMode: _propTypes.default.string.isRequired,
74
79
  handleDragEnd: _propTypes.default.func.isRequired,
75
80
  handleDragStart: _propTypes.default.func.isRequired,
76
81
  isSelected: _propTypes.default.bool.isRequired,
@@ -17,6 +17,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
17
17
  */
18
18
  function Rectangle({
19
19
  activeTool,
20
+ baseStrokeWidth,
20
21
  displayMode,
21
22
  handleDragEnd,
22
23
  handleDragStart,
@@ -59,7 +60,7 @@ function Rectangle({
59
60
  scaleY: shape.scaleY,
60
61
  stroke: shape.stroke,
61
62
  strokeScaleEnabled: false,
62
- strokeWidth: shape.strokeWidth,
63
+ strokeWidth: displayMode === _KonvaUtils.KONVA_MODE.TARGET ? baseStrokeWidth : shape.strokeWidth,
63
64
  width: shape.width,
64
65
  x: shape.x || 0,
65
66
  y: shape.y || 0
@@ -26,7 +26,8 @@ const TEMPLATE = exports.TEMPLATE = {
26
26
  KONVA_TYPE: 'konva',
27
27
  MANIFEST_TYPE: 'manifest',
28
28
  TAGGING_TYPE: 'tagging',
29
- TEXT_TYPE: 'text'
29
+ TEXT_TYPE: 'text',
30
+ MULTIPLE_BODY_TYPE: 'multiple_body'
30
31
  };
31
32
  const MEDIA_TYPES = exports.MEDIA_TYPES = {
32
33
  AUDIO: 'Audio',
@@ -42,6 +43,18 @@ const getTemplateType = (t, templateType) => TEMPLATE_TYPES(t).find(type => type
42
43
  */
43
44
  exports.getTemplateType = getTemplateType;
44
45
  const TEMPLATE_TYPES = t => [{
46
+ description: t('MultiBodyTemplate'),
47
+ // TODO
48
+ icon: /*#__PURE__*/_react.default.createElement(_TextFields.default, null),
49
+ id: TEMPLATE.MULTIPLE_BODY_TYPE,
50
+ isCompatibleWithTemplate: mediaType => {
51
+ if (mediaType === MEDIA_TYPES.VIDEO) return true;
52
+ if (mediaType === MEDIA_TYPES.IMAGE) return true;
53
+ if (mediaType === MEDIA_TYPES.AUDIO) return false;
54
+ return false;
55
+ },
56
+ label: t('MultiBodyTemplate') // TODO
57
+ }, {
45
58
  description: t('textual_note_with_target'),
46
59
  icon: /*#__PURE__*/_react.default.createElement(_TextFields.default, null),
47
60
  id: TEMPLATE.TEXT_TYPE,
@@ -101,8 +114,7 @@ const TEMPLATE_TYPES = t => [{
101
114
  id: TEMPLATE.MANIFEST_TYPE,
102
115
  isCompatibleWithTemplate: mediaType => {
103
116
  if (mediaType === MEDIA_TYPES.VIDEO) return true;
104
- // Mirador doesn't support annotation from an image
105
- if (mediaType === MEDIA_TYPES.IMAGE) return false;
117
+ if (mediaType === MEDIA_TYPES.IMAGE) return true;
106
118
  if (mediaType === MEDIA_TYPES.AUDIO) return false;
107
119
  return false;
108
120
  },
@@ -66,7 +66,7 @@ function DrawingTemplate({
66
66
 
67
67
  /** save Function * */
68
68
  const saveFunction = () => {
69
- (0, _KonvaUtils.resizeKonvaStage)(windowId, playerReferences.getMediaTrueWidth(), playerReferences.getMediaTrueHeight(), 1 / playerReferences.getScale());
69
+ (0, _KonvaUtils.resizeKonvaStage)(windowId, playerReferences.getMediaTrueWidth(), playerReferences.getMediaTrueHeight(), 1 / playerReferences.getScale(), true, true);
70
70
  // Save drawing state in annotation
71
71
  annotationState.maeData.target.drawingState = drawingState;
72
72
  // Unselect current shape
@@ -191,12 +191,14 @@ function DrawingTemplate({
191
191
  playerReferences: playerReferences,
192
192
  scale: scale,
193
193
  setColorToolFromCurrentShape: setColorToolFromCurrentShape,
194
+ setToolState: setToolState,
194
195
  setDrawingState: setDrawingState,
195
196
  tabView: viewTool,
196
197
  toolState: toolState,
197
198
  updateCurrentShapeInShapes: updateCurrentShapeInShapes,
198
199
  updateScale: updateScale,
199
- windowId: windowId
200
+ windowId: windowId,
201
+ setToolState: setToolState
200
202
  })), /*#__PURE__*/_react.default.createElement(_material.Grid, {
201
203
  item: true
202
204
  }, /*#__PURE__*/_react.default.createElement(_AnnotationFormOverlay.default, {