lost-sia 0.5.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
 
8
+ ## [0.9.0] - 2021-12-23
9
+ ### Added
10
+ - Delete annotation in creation mode when hitting *Escape*-Key
11
+ - Show img description in ImgBar if available
12
+ - Max canvas size mode. Where canvas takes the maximum container size and is not
13
+ image oriented as before. Add prop *maxCanvas={true}* to canvas in order to enable.
14
+ ### Changed
15
+ - Be able to deal with mixed color possible labels -> where a part of labels
16
+ will have a specified color and the other part has no provided color
17
+
18
+ ## [0.8.0] - 2021-10-14
19
+ ### Added
20
+ - Added lockedAnnos prop for Canvas in order to lock annos by id. Locked annos
21
+ can not be edited
22
+
23
+ ## [0.7.0] - 2021-10-13
24
+ ### Added
25
+ - Update annotations on **annos**-prob change
26
+
27
+ ## [0.6.0] - 2021-09-28
28
+ ### Added
29
+ - Edit mode for Polygons -> Edit polygons again that already have been created
30
+
8
31
  ## [0.5.2] - 2021-07-22
9
32
  ### Changed
10
33
  - do not spam logs with toSia function
package/dist/index.css CHANGED
@@ -2,10 +2,10 @@
2
2
  position: fixed;
3
3
  top: 0;
4
4
  left: 0;
5
- z-index: 1021;
5
+ z-index: 9999;
6
6
  width: 100%;
7
7
  height: 100%;
8
- background-color: #eee8d5; }
8
+ background-color: #FFFF; }
9
9
 
10
10
  .sel-area-off {
11
11
  fill: none; }
package/dist/index.es.js CHANGED
@@ -4,13 +4,13 @@ import _ from 'lodash';
4
4
 
5
5
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
6
6
 
7
- function toSia(data, image, type) {
7
+ function toSia(data, image, type, imgOffset) {
8
8
  switch (type) {
9
9
  case 'bBox':
10
10
  var w = image.width * data.w;
11
11
  var h = image.height * data.h;
12
- var x0 = image.width * data.x - w / 2.0;
13
- var y0 = image.height * data.y - h / 2.0;
12
+ var x0 = imgOffset.x + image.width * data.x - w / 2.0;
13
+ var y0 = imgOffset.y + image.height * data.y - h / 2.0;
14
14
  return [{
15
15
  x: x0,
16
16
  y: y0
@@ -26,15 +26,15 @@ function toSia(data, image, type) {
26
26
  }];
27
27
  case 'point':
28
28
  return [{
29
- x: image.width * data.x,
30
- y: image.height * data.y
29
+ x: imgOffset.x + image.width * data.x,
30
+ y: imgOffset.y + image.height * data.y
31
31
  }];
32
32
  case 'line':
33
33
  case 'polygon':
34
34
  return data.map(function (e) {
35
35
  return {
36
- x: image.width * e.x,
37
- y: image.height * e.y
36
+ x: imgOffset.x + image.width * e.x,
37
+ y: imgOffset.y + image.height * e.y
38
38
  };
39
39
  });
40
40
  default:
@@ -46,17 +46,21 @@ function toSia(data, image, type) {
46
46
  * Transform a sia annotation to backend format.
47
47
  *
48
48
  * @param {Array} data Annotation data
49
- * @param {*} image Image object {width, height}
49
+ * @param {*} svg Image object {width, height}
50
50
  * @param {String} type Type of the annotation bBox, point, line, polygon
51
51
  * @returns Annotation data in backend style (relative, centered)
52
52
  */
53
- function toBackend(data, image, type) {
53
+ function toBackend(data, svg, type) {
54
+ var imgOffset = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : { x: 0, y: 0 };
55
+
56
+ var imgWidth = svg.width - 2 * imgOffset.x;
57
+ var imgHeight = svg.height - 2 * imgOffset.y;
54
58
  switch (type) {
55
59
  case 'bBox':
56
- // const w = image.width * data.w
57
- // const h = image.height * data.h
58
- // const x0 = image.width * data.x - w/2.0
59
- // const y0 = image.height * data.y - h/2.0
60
+ // const w = svg.width * data.w
61
+ // const h = svg.height * data.h
62
+ // const x0 = svg.width * data.x - w/2.0
63
+ // const y0 = svg.height * data.y - h/2.0
60
64
 
61
65
  // console.error('GO On Here! w = max_x - min_x; h = max_y - min_y')
62
66
  var xList = data.map(function (e) {
@@ -65,30 +69,30 @@ function toBackend(data, image, type) {
65
69
  var yList = data.map(function (e) {
66
70
  return e.y;
67
71
  });
68
- var minX = Math.min.apply(Math, _toConsumableArray(xList));
69
- var maxX = Math.max.apply(Math, _toConsumableArray(xList));
70
- var minY = Math.min.apply(Math, _toConsumableArray(yList));
71
- var maxY = Math.max.apply(Math, _toConsumableArray(yList));
72
+ var minX = Math.min.apply(Math, _toConsumableArray(xList)) - imgOffset.x;
73
+ var maxX = Math.max.apply(Math, _toConsumableArray(xList)) - imgOffset.x;
74
+ var minY = Math.min.apply(Math, _toConsumableArray(yList)) - imgOffset.y;
75
+ var maxY = Math.max.apply(Math, _toConsumableArray(yList)) - imgOffset.y;
72
76
  var w = maxX - minX;
73
77
  var h = maxY - minY;
74
78
  var x = minX + w / 2.0;
75
79
  var y = minY + h / 2.0;
76
80
  return {
77
- x: x / image.width,
78
- y: y / image.height,
79
- w: w / image.width,
80
- h: h / image.height };
81
+ x: x / imgWidth,
82
+ y: y / imgHeight,
83
+ w: w / imgWidth,
84
+ h: h / imgHeight };
81
85
  case 'point':
82
86
  return {
83
- x: data[0].x / image.width,
84
- y: data[0].y / image.height
87
+ x: (data[0].x - imgOffset.x) / imgWidth,
88
+ y: (data[0].y - imgOffset.y) / imgHeight
85
89
  };
86
90
  case 'line':
87
91
  case 'polygon':
88
92
  return data.map(function (e) {
89
93
  return {
90
- x: e.x / image.width,
91
- y: e.y / image.height
94
+ x: (e.x - imgOffset.x) / imgWidth,
95
+ y: (e.y - imgOffset.y) / imgHeight
92
96
  };
93
97
  });
94
98
  default:
@@ -2448,7 +2452,7 @@ var Annotation$1 = function (_Component) {
2448
2452
  }, {
2449
2453
  key: 'getColor',
2450
2454
  value: function getColor$$1() {
2451
- if (this.state.anno.labelIds.length > 0) {
2455
+ if (this.state.anno.labelIds && this.state.anno.labelIds.length > 0) {
2452
2456
  return this.getLabel(this.state.anno.labelIds[0]).color;
2453
2457
  } else {
2454
2458
  return getDefaultColor();
@@ -3153,6 +3157,19 @@ var ImgBar = function (_Component) {
3153
3157
  return null;
3154
3158
  }
3155
3159
  }
3160
+ }, {
3161
+ key: 'renderImgDescription',
3162
+ value: function renderImgDescription() {
3163
+ if (this.props.annos.image.description) {
3164
+ return React.createElement(
3165
+ Menu.Item,
3166
+ null,
3167
+ this.props.annos.image.description
3168
+ );
3169
+ } else {
3170
+ return null;
3171
+ }
3172
+ }
3156
3173
  }, {
3157
3174
  key: 'render',
3158
3175
  value: function render() {
@@ -3160,7 +3177,7 @@ var ImgBar = function (_Component) {
3160
3177
 
3161
3178
  if (!this.props.visible) return null;
3162
3179
  if (!this.props.annos.image) return null;
3163
- if (!this.props.annos.image.url) return null;
3180
+ // if (!this.props.annos.image.url) return null
3164
3181
  return React.createElement(
3165
3182
  'div',
3166
3183
  { style: {
@@ -3177,10 +3194,11 @@ var ImgBar = function (_Component) {
3177
3194
  React.createElement(
3178
3195
  Menu,
3179
3196
  { inverted: true, style: { opacity: 0.9, justifyContent: 'center', alignItems: 'center' } },
3197
+ this.renderImgDescription(),
3180
3198
  React.createElement(
3181
3199
  Menu.Item,
3182
3200
  null,
3183
- this.props.annos.image.url.split('/').pop() + " (ID: " + this.props.annos.image.id + ")"
3201
+ "ID: " + this.props.annos.image.id
3184
3202
  ),
3185
3203
  React.createElement(
3186
3204
  Menu.Item,
@@ -3403,7 +3421,36 @@ var _extends$8 = Object.assign || function (target) { for (var i = 1; i < argume
3403
3421
 
3404
3422
  function _toConsumableArray$3(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
3405
3423
 
3406
- function backendAnnosToCanvas(backendAnnos, imgSize) {
3424
+ function _fixBackendAnnoElement(element) {
3425
+ return _extends$8({}, element, {
3426
+ id: element.id ? element.id : _.uniqueId('new'),
3427
+ annoTime: element.annoTime ? element.annoTime : 0.0,
3428
+ mode: element.mode ? element.mode : VIEW,
3429
+ status: element.status ? element.status : DATABASE,
3430
+ labelIds: element.labelIds ? element.labelIds : []
3431
+ });
3432
+ }
3433
+
3434
+ function fixBackendAnnos(backendAnnos) {
3435
+ var annos = {
3436
+ bBoxes: [].concat(_toConsumableArray$3(backendAnnos.bBoxes.map(function (element) {
3437
+ return _fixBackendAnnoElement(element);
3438
+ }))),
3439
+ lines: [].concat(_toConsumableArray$3(backendAnnos.lines.map(function (element) {
3440
+ return _fixBackendAnnoElement(element);
3441
+ }))),
3442
+ polygons: [].concat(_toConsumableArray$3(backendAnnos.polygons.map(function (element) {
3443
+ return _fixBackendAnnoElement(element);
3444
+ }))),
3445
+ points: [].concat(_toConsumableArray$3(backendAnnos.points.map(function (element) {
3446
+ return _fixBackendAnnoElement(element);
3447
+ })))
3448
+ };
3449
+ console.log('fixBackendAnnos', annos);
3450
+ return annos;
3451
+ }
3452
+
3453
+ function backendAnnosToCanvas(backendAnnos, imgSize, imgOffset) {
3407
3454
  var annos = [].concat(_toConsumableArray$3(backendAnnos.bBoxes.map(function (element) {
3408
3455
  return _extends$8({}, element, { type: 'bBox',
3409
3456
  mode: element.mode ? element.mode : VIEW,
@@ -3424,7 +3471,7 @@ function backendAnnosToCanvas(backendAnnos, imgSize) {
3424
3471
  })));
3425
3472
  annos = annos.map(function (el) {
3426
3473
  return _extends$8({}, el, {
3427
- data: toSia(el.data, imgSize, el.type) });
3474
+ data: toSia(el.data, imgSize, el.type, imgOffset) });
3428
3475
  });
3429
3476
  // this.setState({annos: [...annos]})
3430
3477
  return annos;
@@ -3432,6 +3479,7 @@ function backendAnnosToCanvas(backendAnnos, imgSize) {
3432
3479
 
3433
3480
  function canvasToBackendAnnos(annos, imgSize) {
3434
3481
  var forBackendPost = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
3482
+ var imgOffset = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : { x: 0, y: 0 };
3435
3483
 
3436
3484
  var myAnnos = annos;
3437
3485
  var bAnnos = myAnnos.map(function (el) {
@@ -3447,7 +3495,7 @@ function canvasToBackendAnnos(annos, imgSize) {
3447
3495
  return _extends$8({}, el, {
3448
3496
  id: annoId,
3449
3497
  mode: VIEW,
3450
- data: toBackend(el.data, imgSize, el.type)
3498
+ data: toBackend(el.data, imgSize, el.type, imgOffset)
3451
3499
  });
3452
3500
  });
3453
3501
 
@@ -3486,6 +3534,8 @@ var CAM_MOVE_RIGHT = 'camMoveRight';
3486
3534
  var CAM_MOVE_STOP = 'camMoveStop';
3487
3535
  var COPY_ANNOTATION = 'copyAnnotation';
3488
3536
  var PASTE_ANNOTATION = 'pasteAnnotation';
3537
+ var RECREATE_ANNO = 'recreateAnnotation';
3538
+ var DELETE_ANNO_IN_CREATION = 'deleteAnnoInCreation';
3489
3539
 
3490
3540
  var KeyMapper = function () {
3491
3541
  function KeyMapper() {
@@ -3539,6 +3589,9 @@ var KeyMapper = function () {
3539
3589
  case 'd':
3540
3590
  this.triggerKeyAction(CAM_MOVE_RIGHT);
3541
3591
  break;
3592
+ case 'e':
3593
+ this.triggerKeyAction(RECREATE_ANNO);
3594
+ break;
3542
3595
  case 'c':
3543
3596
  if (this.controlDown) {
3544
3597
  this.triggerKeyAction(COPY_ANNOTATION);
@@ -3549,6 +3602,9 @@ var KeyMapper = function () {
3549
3602
  this.triggerKeyAction(PASTE_ANNOTATION);
3550
3603
  }
3551
3604
  break;
3605
+ case 'Escape':
3606
+ this.triggerKeyAction(DELETE_ANNO_IN_CREATION);
3607
+ break;
3552
3608
  default:
3553
3609
  break;
3554
3610
  }
@@ -3702,7 +3758,7 @@ function getZoomTranslation(w0, svg, s1) {
3702
3758
  return translation;
3703
3759
  }
3704
3760
 
3705
- var css$1 = ".SIA_sia-fullscreen__1P3FS {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1021;\n width: 100%;\n height: 100%;\n background-color: #eee8d5; }\n";
3761
+ var css$1 = ".SIA_sia-fullscreen__1P3FS {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 9999;\n width: 100%;\n height: 100%;\n background-color: #FFFF; }\n";
3706
3762
  styleInject(css$1);
3707
3763
 
3708
3764
  var _extends$9 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
@@ -3727,17 +3783,19 @@ function _inherits$e(subClass, superClass) { if (typeof superClass !== "function
3727
3783
  * {
3728
3784
  * image : {
3729
3785
  * id: int,
3730
- * url: string,
3731
3786
  * number: int,
3732
3787
  * amount: int,
3733
3788
  * isFirst: bool,
3734
- * isLast: bool
3789
+ * isLast: bool,
3790
+ * description: string, // -> optional
3735
3791
  * },
3736
3792
  * annotations: {
3737
3793
  * bBoxes: [{
3738
- * id: int,
3739
- * labelIds: list of int,
3740
- * data: {}
3794
+ * id: int, // -> Not required if status === annoStatus.NEW
3795
+ * data: {},
3796
+ * labelIds: list of int, // -> optional
3797
+ * status: see annoStatus, // -> optional
3798
+ * annoTime: float, // -> optional
3741
3799
  * },...],
3742
3800
  * points: []
3743
3801
  * lines: []
@@ -3791,10 +3849,13 @@ function _inherits$e(subClass, superClass) { if (typeof superClass !== "function
3791
3849
  * {left:int, top:int, right:int, bottom:int} values in pixels.
3792
3850
  * @param {bool} centerCanvasInContainer - Center the canvas in the
3793
3851
  * middle of the container.
3852
+ * @param {bool} maxCanvas - Maximize Canvas Size. Do not fit canvas to image size
3794
3853
  * @param {str or int} defaultLabel (optional) - Name or ID of the default label that is used
3795
3854
  * when no label was selected by the annotator. If not set "no label" will be used.
3796
3855
  * If ID is used, it needs to be one of the possible label ids.
3797
3856
  * @param {bool} blocked Block canvas view with loading dimmer.
3857
+ * @param {bool} lockedAnnos A list of AnnoIds of annos that should only be displayed.
3858
+ * Such annos can not be edited in any way.
3798
3859
  * @event onSVGUpdate - Fires when the svg in canvas changed.
3799
3860
  * args: {width: int, height: int, scale: float, translateX: float,
3800
3861
  * translateY:float}
@@ -3832,6 +3893,10 @@ var Canvas = function (_Component) {
3832
3893
  width: undefined,
3833
3894
  height: undefined
3834
3895
  },
3896
+ imageOffset: {
3897
+ x: 0,
3898
+ y: 0
3899
+ },
3835
3900
  annos: [],
3836
3901
  mode: VIEW,
3837
3902
  // selectedAnnoId: {id:undefined},
@@ -3886,6 +3951,9 @@ var Canvas = function (_Component) {
3886
3951
  imgLoadTimestamp: performance.now()
3887
3952
  // isJunk: this.props.annos.image.isJunk
3888
3953
  });
3954
+ if (this.state.imageData) {
3955
+ this.updateCanvasView(fixBackendAnnos(this.props.annos.annotations));
3956
+ }
3889
3957
  // this.setState({
3890
3958
  // imageLoaded: false,
3891
3959
  // // imageData: undefined
@@ -3932,7 +4000,7 @@ var Canvas = function (_Component) {
3932
4000
  // Selected annotation should be on top
3933
4001
  this.putSelectedOnTop(prevState);
3934
4002
  if (prevState.imgLoadCount !== this.state.imgLoadCount) {
3935
- this.updateCanvasView(this.props.annos.annotations);
4003
+ this.updateCanvasView(fixBackendAnnos(this.props.annos.annotations));
3936
4004
  this.setImageLabels(this.props.annos.image.labelIds);
3937
4005
  this.setState({
3938
4006
  performedImageInit: true
@@ -3941,7 +4009,8 @@ var Canvas = function (_Component) {
3941
4009
  if (prevProps.layoutUpdate !== this.props.layoutUpdate) {
3942
4010
  this.selectAnnotation(undefined);
3943
4011
  // this.updateCanvasView(this.getAnnoBackendFormat())
3944
- this.updateCanvasView(canvasToBackendAnnos(this.state.annos, this.state.svg));
4012
+ // const {imageOffset} = this.updateImageSize()
4013
+ this.updateCanvasView(canvasToBackendAnnos(this.state.annos, this.state.svg, false, this.state.imageOffset));
3945
4014
  }
3946
4015
  }
3947
4016
  }
@@ -4065,14 +4134,10 @@ var Canvas = function (_Component) {
4065
4134
  this.editAnnoLabel(myAnno);
4066
4135
  break;
4067
4136
  case DELETE_ANNO:
4068
- if (anno) {
4069
- if (anno.mode === CREATE) {
4070
- var _ar = this.findAnnoRef(this.state.selectedAnnoId);
4071
- if (_ar !== undefined) _ar.current.myAnno.current.removeLastNode();
4072
- } else {
4073
- this.onAnnoPerformedAction(anno, ANNO_DELETED);
4074
- }
4075
- }
4137
+ this.deleteAnnotation(anno);
4138
+ break;
4139
+ case DELETE_ANNO_IN_CREATION:
4140
+ this.deleteAnnoInCreationMode(anno);
4076
4141
  break;
4077
4142
  case ENTER_ANNO_ADD_MODE:
4078
4143
  if (anno) {
@@ -4117,6 +4182,10 @@ var Canvas = function (_Component) {
4117
4182
  case PASTE_ANNOTATION:
4118
4183
  this.pasteAnnotation(0);
4119
4184
  break;
4185
+ case RECREATE_ANNO:
4186
+ // recreate selected annotation using the anno id
4187
+ if (this.state.selectedAnnoId) this.recreateAnnotation(this.state.selectedAnnoId);
4188
+ break;
4120
4189
  default:
4121
4190
  console.warn('Unknown key action', action);
4122
4191
  }
@@ -4398,11 +4467,13 @@ var Canvas = function (_Component) {
4398
4467
  if (!this.props.possibleLabels) return;
4399
4468
  if (this.props.possibleLabels.length <= 0) return;
4400
4469
  var lbls = this.props.possibleLabels;
4401
- if (!('color' in lbls[0])) {
4402
- lbls = lbls.map(function (e) {
4470
+ lbls = lbls.map(function (e) {
4471
+ if (!('color' in e)) {
4403
4472
  return _extends$9({}, e, { color: getColor(e.id) });
4404
- });
4405
- }
4473
+ } else {
4474
+ return _extends$9({}, e);
4475
+ }
4476
+ });
4406
4477
  this.setState({
4407
4478
  possibleLabels: [].concat(_toConsumableArray$4(lbls))
4408
4479
  });
@@ -4481,6 +4552,29 @@ var Canvas = function (_Component) {
4481
4552
  this.setCanvasState(cState.entry.annotations, cState.entry.imgLabelIds, cState.entry.selectedAnnoId, cState.entry.showSingleAnno);
4482
4553
  }
4483
4554
  }
4555
+ }, {
4556
+ key: 'deleteAnnotation',
4557
+ value: function deleteAnnotation(anno) {
4558
+ if (anno) {
4559
+ if (anno.mode === CREATE) {
4560
+ var ar = this.findAnnoRef(this.state.selectedAnnoId);
4561
+ if (ar !== undefined) ar.current.myAnno.current.removeLastNode();
4562
+ } else {
4563
+ this.onAnnoPerformedAction(anno, ANNO_DELETED);
4564
+ }
4565
+ }
4566
+ }
4567
+ }, {
4568
+ key: 'deleteAnnoInCreationMode',
4569
+ value: function deleteAnnoInCreationMode(anno) {
4570
+ if (anno) {
4571
+ if (anno.mode === CREATE) {
4572
+ // const ar = this.findAnnoRef(this.state.selectedAnnoId)
4573
+ // if (ar !== undefined) ar.current.myAnno.current.removeLastNode()
4574
+ this.onAnnoPerformedAction(anno, ANNO_DELETED);
4575
+ }
4576
+ }
4577
+ }
4484
4578
  }, {
4485
4579
  key: 'deleteAllAnnos',
4486
4580
  value: function deleteAllAnnos() {
@@ -4514,9 +4608,27 @@ var Canvas = function (_Component) {
4514
4608
  this.selectAnnotation(selectedAnnoId);
4515
4609
  this.setState({ showSingleAnno: showSingleAnno });
4516
4610
  }
4611
+ }, {
4612
+ key: 'isLocked',
4613
+ value: function isLocked(annoId) {
4614
+ if (this.props.lockedAnnos) {
4615
+ if (this.props.lockedAnnos.includes(annoId)) {
4616
+ return true;
4617
+ }
4618
+ }
4619
+ return false;
4620
+ }
4517
4621
  }, {
4518
4622
  key: 'selectAnnotation',
4519
4623
  value: function selectAnnotation(annoId) {
4624
+ if (this.isLocked(annoId)) {
4625
+ this.handleNotification({
4626
+ title: "Annotation locked",
4627
+ message: 'Annotation with id ' + annoId + ' is locked and can not be edited',
4628
+ type: WARNING
4629
+ });
4630
+ return;
4631
+ }
4520
4632
  if (annoId) {
4521
4633
  var anno = this.findAnno(annoId);
4522
4634
  this.setState({
@@ -4555,7 +4667,7 @@ var Canvas = function (_Component) {
4555
4667
 
4556
4668
  if (this.state.annos.length > 0) {
4557
4669
  var myAnnos = this.state.annos.filter(function (e) {
4558
- return e.status !== DELETED$1;
4670
+ return e.status !== DELETED$1 && !_this2.isLocked(e.id);
4559
4671
  });
4560
4672
  if (myAnnos.length > 0) {
4561
4673
  if (!this.state.selectedAnnoId) {
@@ -4581,7 +4693,7 @@ var Canvas = function (_Component) {
4581
4693
 
4582
4694
  var myAnnos = annos ? annos : this.state.annos;
4583
4695
  // const backendFormat = this.getAnnoBackendFormat(removeFrontedIds, myAnnos)
4584
- var backendFormat = canvasToBackendAnnos(myAnnos, this.state.svg, removeFrontedIds);
4696
+ var backendFormat = canvasToBackendAnnos(myAnnos, this.state.svg, removeFrontedIds, this.state.imageOffset);
4585
4697
  var finalData = {
4586
4698
  imgId: this.props.annos.image.id,
4587
4699
  imgLabelIds: this.state.imgLabelIds,
@@ -4730,6 +4842,56 @@ var Canvas = function (_Component) {
4730
4842
  }
4731
4843
  }
4732
4844
  }
4845
+
4846
+ /**
4847
+ * recreate an existing annotation in case the creation process was not finished
4848
+ * @param {string} id of annotation
4849
+ */
4850
+
4851
+ }, {
4852
+ key: 'recreateAnnotation',
4853
+ value: function recreateAnnotation(annoID) {
4854
+
4855
+ var annos = this.state.annos;
4856
+
4857
+ // search for id of selected anno in all annos (should normally be last item in list, but to be sure)
4858
+ var annoIndex = void 0;
4859
+ var anno = void 0;
4860
+
4861
+ for (var k in annos) {
4862
+ if (annos[k].id == annoID) {
4863
+ annoIndex = k;
4864
+ anno = annos[k];
4865
+ break;
4866
+ }
4867
+ } // editing is only allowed on line and polygon
4868
+ if (!['line', 'polygon'].includes(anno.type)) return console.log("Cant recreate annotation: Type " + anno.type + " is forbidden");
4869
+
4870
+ // remove the old annotation
4871
+ this.state.annos.splice(annoIndex, 1);
4872
+
4873
+ // create a new annotation based on the datapoints of the old annotation
4874
+ var newAnno = {
4875
+ id: anno.id,
4876
+ type: anno.type,
4877
+ data: anno.data,
4878
+ mode: CREATE,
4879
+ status: anno.status == 'database' ? CHANGED : NEW,
4880
+ labelIds: anno.labelIds,
4881
+ selectedNode: anno.data.length - 1,
4882
+ annoTime: anno.annoTime
4883
+ };
4884
+
4885
+ newAnno = this.startAnnotimeMeasure(newAnno);
4886
+ this.setState({
4887
+ annos: [].concat(_toConsumableArray$4(this.state.annos), [newAnno]),
4888
+ selectedAnnoId: newAnno.id,
4889
+ showSingleAnno: newAnno.id,
4890
+ annoToolBarVisible: false
4891
+ });
4892
+
4893
+ console.log("Annotation recreated");
4894
+ }
4733
4895
  }, {
4734
4896
  key: 'putSelectedOnTop',
4735
4897
  value: function putSelectedOnTop(prevState) {
@@ -4882,28 +5044,40 @@ var Canvas = function (_Component) {
4882
5044
  imgWidth = maxImgHeight * ratio;
4883
5045
  imgHeight = maxImgHeight;
4884
5046
  }
4885
- if (this.props.centerCanvasInContainer) {
4886
- var resSpaceX = maxImgWidth - imgWidth;
4887
- if (resSpaceX > 2) {
4888
- canvasLeft = canvasLeft + resSpaceX / 2;
4889
- }
4890
- var resSpaceY = maxImgHeight - imgHeight;
4891
- if (resSpaceY > 2) {
4892
- canvasTop = canvasTop + resSpaceY / 2;
5047
+ var svg;
5048
+ var imgOffset = { x: 0, y: 0 };
5049
+ if (this.props.maxCanvas) {
5050
+ imgOffset.x = (maxImgWidth - imgWidth) / 2;
5051
+ imgOffset.y = (maxImgHeight - imgHeight) / 2;
5052
+ console.log('imgOffset: ', imgOffset);
5053
+ svg = _extends$9({}, this.state.svg, { width: maxImgWidth, height: maxImgHeight,
5054
+ left: canvasLeft, top: canvasTop
5055
+ });
5056
+ } else {
5057
+ if (this.props.centerCanvasInContainer) {
5058
+ var resSpaceX = maxImgWidth - imgWidth;
5059
+ if (resSpaceX > 2) {
5060
+ canvasLeft = canvasLeft + resSpaceX / 2;
5061
+ }
5062
+ var resSpaceY = maxImgHeight - imgHeight;
5063
+ if (resSpaceY > 2) {
5064
+ canvasTop = canvasTop + resSpaceY / 2;
5065
+ }
4893
5066
  }
5067
+ svg = _extends$9({}, this.state.svg, { width: imgWidth, height: imgHeight,
5068
+ left: canvasLeft, top: canvasTop
5069
+ });
4894
5070
  }
4895
- var svg = _extends$9({}, this.state.svg, { width: imgWidth, height: imgHeight,
4896
- left: canvasLeft, top: canvasTop
4897
- });
4898
5071
  this.setState({
4899
5072
  svg: svg,
4900
5073
  image: {
4901
5074
  width: this.img.current.naturalWidth,
4902
5075
  height: this.img.current.naturalHeight
4903
- }
5076
+ },
5077
+ imageOffset: imgOffset
4904
5078
  });
4905
5079
  this.svgUpdate(svg);
4906
- return { imgWidth: imgWidth, imgHeight: imgHeight };
5080
+ return { imgWidth: imgWidth, imgHeight: imgHeight, imgOffset: imgOffset };
4907
5081
  }
4908
5082
  }, {
4909
5083
  key: 'svgUpdate',
@@ -4928,7 +5102,7 @@ var Canvas = function (_Component) {
4928
5102
  //for svg should be calculated
4929
5103
  if (annotations) {
4930
5104
  var imgSize = this.updateImageSize();
4931
- this.setState({ annos: [].concat(_toConsumableArray$4(backendAnnosToCanvas(annotations, { width: imgSize.imgWidth, height: imgSize.imgHeight }))) });
5105
+ this.setState({ annos: [].concat(_toConsumableArray$4(backendAnnosToCanvas(annotations, { width: imgSize.imgWidth, height: imgSize.imgHeight }, imgSize.imgOffset))) });
4932
5106
  }
4933
5107
  }
4934
5108
  }, {