@operato/image-marker 8.0.0-alpha.22 → 8.0.0-alpha.24

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.
@@ -38,62 +38,66 @@ export class OxImageMarkerMode extends LitElement {
38
38
  }
39
39
  `
40
40
 
41
- @property({ type: String }) currentMode: ImageMarkerMode = 'select'
41
+ @property({ type: String }) currentMode: ImageMarkerMode = 'edit'
42
42
  @property({ type: String }) currentShapeType?: ShapeType
43
43
 
44
44
  render() {
45
45
  return html`
46
46
  <div class="palette">
47
47
  <md-icon
48
- title="Move or Select"
49
- ?selected=${this.currentMode !== 'draw'}
50
- @click=${() => this.setMode(this.currentMode !== 'select' ? 'select' : 'move')}
51
- >${this.currentMode !== 'move' ? 'select' : 'drag_pan'}</md-icon
48
+ title="Edit or View"
49
+ ?selected=${this.currentMode !== 'shape'}
50
+ @click=${() => this.setMode(this.currentMode !== 'edit' ? 'edit' : 'view')}
51
+ >${this.currentMode !== 'view' ? 'brush' : 'drag_pan'}</md-icon
52
52
  >
53
53
 
54
54
  <md-icon
55
55
  title="Text"
56
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'text'}
56
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'text'}
57
57
  @click=${() => this.setShape('text')}
58
58
  >match_case</md-icon
59
59
  >
60
60
 
61
61
  <md-icon
62
62
  title="Rectangle"
63
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'rectangle'}
63
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'rectangle'}
64
64
  @click=${() => this.setShape('rectangle')}
65
65
  >rectangle</md-icon
66
66
  >
67
67
 
68
68
  <md-icon
69
69
  title="Circle"
70
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'circle'}
70
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'circle'}
71
71
  @click=${() => this.setShape('circle')}
72
72
  >circle</md-icon
73
73
  >
74
74
 
75
75
  <md-icon
76
76
  title="Triangle"
77
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'triangle'}
77
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'triangle'}
78
78
  @click=${() => this.setShape('triangle')}
79
79
  >change_history</md-icon
80
80
  >
81
81
 
82
82
  <md-icon
83
83
  title="Line"
84
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'line'}
84
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'line'}
85
85
  @click=${() => this.setShape('line')}
86
86
  >shape_line</md-icon
87
87
  >
88
88
 
89
89
  <md-icon
90
90
  title="Arrow"
91
- ?selected=${this.currentMode === 'draw' && this.currentShapeType === 'arrow'}
91
+ ?selected=${this.currentMode === 'shape' && this.currentShapeType === 'arrow'}
92
92
  @click=${() => this.setShape('arrow')}
93
93
  >line_end_arrow</md-icon
94
94
  >
95
95
  </div>
96
96
 
97
+ <div class="palette">
98
+ <md-icon title="Fit size" @click=${() => this.onClickFitSize()}>recenter</md-icon>
99
+ </div>
100
+
97
101
  <div class="palette">
98
102
  <md-icon title="Delete" @click=${() => this.onClickDelete()}>delete</md-icon>
99
103
  <md-icon title="Save" @click=${() => this.onClickSave()}>save</md-icon>
@@ -101,7 +105,7 @@ export class OxImageMarkerMode extends LitElement {
101
105
  `
102
106
  }
103
107
 
104
- private setMode(mode: ImageMarkerMode) {
108
+ public setMode(mode: ImageMarkerMode) {
105
109
  this.currentMode = mode
106
110
 
107
111
  this.dispatchEvent(
@@ -113,12 +117,12 @@ export class OxImageMarkerMode extends LitElement {
113
117
  )
114
118
  }
115
119
 
116
- private setShape(shapeType: ShapeType) {
117
- this.currentMode = 'draw'
120
+ protected setShape(shapeType: ShapeType) {
121
+ this.currentMode = 'shape'
118
122
  this.currentShapeType = shapeType
119
123
  this.dispatchEvent(
120
124
  new CustomEvent('mode-changed', {
121
- detail: { mode: 'draw', shapeType: this.currentShapeType },
125
+ detail: { mode: 'shape', shapeType: this.currentShapeType },
122
126
  bubbles: true,
123
127
  composed: true
124
128
  })
@@ -142,4 +146,13 @@ export class OxImageMarkerMode extends LitElement {
142
146
  })
143
147
  )
144
148
  }
149
+
150
+ private onClickFitSize() {
151
+ this.dispatchEvent(
152
+ new CustomEvent('tap-fit-size', {
153
+ bubbles: true,
154
+ composed: true
155
+ })
156
+ )
157
+ }
145
158
  }
@@ -11,6 +11,7 @@ export class OxImageMarkerView extends BaseImageMarker {
11
11
  <svg
12
12
  @wheel=${this.onSvgWheel}
13
13
  @mousedown=${this.onSvgMouseDown}
14
+ @touchstart=${this.onSvgTouchStart}
14
15
  @dblclick=${this.onSvgDoubleClick}
15
16
  viewBox=${this.viewBox}
16
17
  >
@@ -1,12 +1,13 @@
1
1
  import './ox-image-marker-mode'
2
2
 
3
3
  import { html, css, svg, nothing } from 'lit'
4
- import { state, customElement } from 'lit/decorators.js'
4
+ import { query, state, customElement } from 'lit/decorators.js'
5
5
  import { ifDefined } from 'lit/directives/if-defined.js'
6
6
  import { keyed } from 'lit/directives/keyed.js'
7
7
 
8
8
  import { ImageMarkerMode, Shape, ShapeType } from './types'
9
9
  import { BaseImageMarker } from './base-image-marker'
10
+ import { OxImageMarkerMode } from './ox-image-marker-mode'
10
11
 
11
12
  @customElement('ox-image-marker')
12
13
  export class OxImageMarker extends BaseImageMarker {
@@ -27,11 +28,11 @@ export class OxImageMarker extends BaseImageMarker {
27
28
  }
28
29
 
29
30
  svg {
30
- cursor: crosshair;
31
+ cursor: default;
31
32
  }
32
33
 
33
- svg.dragging {
34
- cursor: move;
34
+ svg[drawing] {
35
+ cursor: crosshair;
35
36
  }
36
37
 
37
38
  .resize-handle {
@@ -41,9 +42,11 @@ export class OxImageMarker extends BaseImageMarker {
41
42
  ]
42
43
 
43
44
  @state() private currentShapeType?: ShapeType
44
- @state() private currentMode: ImageMarkerMode = 'select'
45
+ @state() private currentMode: ImageMarkerMode = 'edit'
45
46
  @state() private selectedShape: Shape | null = null
46
47
 
48
+ @query('ox-image-marker-mode') imageMarkerMode!: OxImageMarkerMode
49
+
47
50
  private drawing = false
48
51
  private startX = 0
49
52
  private startY = 0
@@ -72,6 +75,7 @@ export class OxImageMarker extends BaseImageMarker {
72
75
  @wheel=${this.onSvgWheel}
73
76
  @dblclick=${this.onSvgDoubleClick}
74
77
  viewBox=${this.viewBox}
78
+ ?drawing=${this.currentMode == 'shape'}
75
79
  >
76
80
  <image href=${this.imageUrl} @load=${this.onImageLoad}></image>
77
81
  ${this.shapes.map(shape => keyed(shape.id, this.renderShape(shape)))}
@@ -85,6 +89,7 @@ export class OxImageMarker extends BaseImageMarker {
85
89
  const { mode, shapeType } = e.detail
86
90
  this.setMode(mode, shapeType)
87
91
  }}
92
+ @tap-fit-size=${() => this.resetZoom()}
88
93
  @tap-delete=${() => this.deleteSelectedShape()}
89
94
  @tap-save=${() => {
90
95
  this.dispatchEvent(
@@ -100,29 +105,31 @@ export class OxImageMarker extends BaseImageMarker {
100
105
  }
101
106
 
102
107
  protected onSvgMouseDown(event: MouseEvent) {
103
- this.selectedShape = null
104
- this.shapes = this.shapes.map(s => {
105
- return { ...s, selected: false }
106
- })
108
+ event.preventDefault()
107
109
 
108
- if (this.currentMode === 'move') {
109
- this.startPanning(event)
110
- } else if (this.currentMode === 'draw') {
110
+ this.setSelectedShape(null)
111
+
112
+ if (this.currentMode === 'shape') {
111
113
  this.startDrawing(event)
114
+ } else {
115
+ this.startPanning(event)
112
116
  }
113
117
  }
114
118
 
115
119
  protected onSvgTouchStart = (event: TouchEvent) => {
120
+ event.preventDefault()
121
+
122
+ if (this.isDoubleTouch(event)) {
123
+ this.resetZoom()
124
+ }
125
+
116
126
  if (event.touches.length === 1) {
117
- this.selectedShape = null
118
- this.shapes = this.shapes.map(s => {
119
- return { ...s, selected: false }
120
- })
127
+ this.setSelectedShape(null)
121
128
 
122
- if (this.currentMode === 'move') {
123
- this.startPanning(event)
124
- } else if (this.currentMode === 'draw') {
129
+ if (this.currentMode === 'shape') {
125
130
  this.startDrawing(event)
131
+ } else {
132
+ this.startPanning(event)
126
133
  }
127
134
  } else if (event.touches.length === 2) {
128
135
  this.startPinchZooming(event)
@@ -151,24 +158,30 @@ export class OxImageMarker extends BaseImageMarker {
151
158
  }
152
159
 
153
160
  if ('touches' in event) {
154
- this.svg.addEventListener('touchmove', this.onDrawingMouseMove)
155
- this.svg.addEventListener('touchend', this.onDrawingMouseUp)
161
+ this.svg.addEventListener('touchmove', this.onMouseMoveForDrawing)
162
+ this.svg.addEventListener('touchend', this.onMouseUpForDrawing)
156
163
  } else {
157
- this.svg.addEventListener('mousemove', this.onDrawingMouseMove)
158
- this.svg.addEventListener('mouseup', this.onDrawingMouseUp)
164
+ this.svg.addEventListener('mousemove', this.onMouseMoveForDrawing)
165
+ this.svg.addEventListener('mouseup', this.onMouseUpForDrawing)
159
166
  }
160
167
  }
161
168
 
162
169
  private setMode(mode: ImageMarkerMode, shapeType: ShapeType) {
170
+ if (mode == 'view') {
171
+ this.setSelectedShape(null)
172
+ }
173
+
163
174
  this.currentMode = mode
164
175
  this.currentShapeType = shapeType
165
176
  }
166
177
 
167
- private onDrawingMouseMove = (event: MouseEvent | TouchEvent) => {
178
+ private onMouseMoveForDrawing = (event: MouseEvent | TouchEvent) => {
168
179
  if (!this.drawing) {
169
180
  return
170
181
  }
171
182
 
183
+ event.preventDefault()
184
+
172
185
  const { x, y } = this.getSvgPoint(event)
173
186
 
174
187
  const minDistance = 5
@@ -232,8 +245,8 @@ export class OxImageMarker extends BaseImageMarker {
232
245
  return
233
246
  }
234
247
 
235
- this.selectedShape = newShape
236
248
  this.shapes = [...this.shapes, newShape]
249
+ this.setSelectedShape(newShape)
237
250
  }
238
251
 
239
252
  if (this.selectedShape) {
@@ -267,26 +280,38 @@ export class OxImageMarker extends BaseImageMarker {
267
280
  }
268
281
  }
269
282
 
270
- private onDrawingMouseUp = (event: MouseEvent | TouchEvent) => {
283
+ private onMouseUpForDrawing = (event: MouseEvent | TouchEvent) => {
284
+ event.preventDefault()
285
+
271
286
  this.drawing = false
272
287
 
273
288
  const svg = this.svg as SVGSVGElement
274
289
 
275
290
  if ('touches' in event) {
276
- svg.removeEventListener('touchmove', this.onDrawingMouseMove)
277
- svg.removeEventListener('touchend', this.onDrawingMouseUp)
291
+ svg.removeEventListener('touchmove', this.onMouseMoveForDrawing)
292
+ svg.removeEventListener('touchend', this.onMouseUpForDrawing)
278
293
  } else {
279
- svg.removeEventListener('mousemove', this.onDrawingMouseMove)
280
- svg.removeEventListener('mouseup', this.onDrawingMouseUp)
294
+ svg.removeEventListener('mousemove', this.onMouseMoveForDrawing)
295
+ svg.removeEventListener('mouseup', this.onMouseUpForDrawing)
281
296
  }
282
297
 
283
- if (this.selectedShape) {
284
- this.selectedShape.selected = true
285
- }
298
+ this.imageMarkerMode.setMode('edit')
286
299
 
287
300
  this.requestUpdate()
288
301
  }
289
302
 
303
+ private setSelectedShape(shape: Shape | null) {
304
+ this.selectedShape = shape
305
+
306
+ if (!shape) {
307
+ this.shapes = this.shapes.map(s => {
308
+ return { ...s, selected: false }
309
+ })
310
+ } else {
311
+ this.selectedShape!.selected = true
312
+ }
313
+ }
314
+
290
315
  private getSvgPoint(event: MouseEvent | TouchEvent) {
291
316
  const { x, y } = this.getPointFromEvent(event)
292
317
 
@@ -315,8 +340,8 @@ export class OxImageMarker extends BaseImageMarker {
315
340
  y="${shape.y!}"
316
341
  fill="${commonAttrs.stroke}"
317
342
  style="cursor: ${commonAttrs.cursor}; font-size: 16px;"
318
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
319
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
343
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
344
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
320
345
  @dblclick="${(e: MouseEvent) => this.onTextDoubleClick(e, shape)}"
321
346
  >${shape.text}</text>
322
347
  `
@@ -332,8 +357,8 @@ export class OxImageMarker extends BaseImageMarker {
332
357
  stroke-width="${commonAttrs['stroke-width']}"
333
358
  fill="${commonAttrs.fill}"
334
359
  style="cursor: ${commonAttrs.cursor}"
335
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
336
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
360
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
361
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
337
362
  ></rect>
338
363
  ${shape.selected ? this.renderResizeHandles(shape) : ''}
339
364
  `
@@ -348,8 +373,8 @@ export class OxImageMarker extends BaseImageMarker {
348
373
  stroke-width="${commonAttrs['stroke-width']}"
349
374
  fill="${commonAttrs.fill}"
350
375
  style="cursor: ${commonAttrs.cursor}"
351
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
352
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
376
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
377
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
353
378
  ></circle>
354
379
  ${shape.selected ? this.renderResizeHandles(shape) : ''}
355
380
  `
@@ -362,8 +387,8 @@ export class OxImageMarker extends BaseImageMarker {
362
387
  stroke-width="${commonAttrs['stroke-width']}"
363
388
  fill="${commonAttrs.fill}"
364
389
  style="cursor: ${commonAttrs.cursor}"
365
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
366
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
390
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
391
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
367
392
  ></polygon>
368
393
  ${shape.selected ? this.renderResizeHandles(shape) : ''}
369
394
  `
@@ -378,8 +403,20 @@ export class OxImageMarker extends BaseImageMarker {
378
403
  stroke="${commonAttrs.stroke}"
379
404
  stroke-width="${commonAttrs['stroke-width']}"
380
405
  style="cursor: ${commonAttrs.cursor}"
381
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
382
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
406
+ ></line>
407
+ <line
408
+ x1="${shape.x1!}"
409
+ y1="${shape.y1!}"
410
+ x2="${shape.x2 ?? shape.x1}"
411
+ y2="${shape.y2 ?? shape.y1}"
412
+ stroke="${commonAttrs.stroke}"
413
+ stroke-width="25"
414
+ stroke-opacity="0"
415
+ pointer-events="stroke"
416
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
417
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
418
+ @mouseenter="${() => (this.svg.style.cursor = 'pointer')}"
419
+ @mouseleave="${() => (this.svg.style.cursor = 'default')}"
383
420
  ></line>
384
421
  ${shape.selected ? this.renderResizeHandles(shape) : ''}
385
422
  `
@@ -400,8 +437,20 @@ export class OxImageMarker extends BaseImageMarker {
400
437
  stroke-width="${commonAttrs['stroke-width']}"
401
438
  marker-end="url(#arrowhead-${shape.id})"
402
439
  style="cursor: ${commonAttrs.cursor}"
403
- @mousedown="${(e: MouseEvent) => this.onShapeMouseDown(e, shape)}"
404
- @touchstart="${(e: TouchEvent) => this.onShapeMouseDown(e, shape)}"
440
+ ></line>
441
+ <line
442
+ x1="${shape.x1!}"
443
+ y1="${shape.y1!}"
444
+ x2="${shape.x2 ?? shape.x1}"
445
+ y2="${shape.y2 ?? shape.y1}"
446
+ stroke="${commonAttrs.stroke}"
447
+ stroke-width="25"
448
+ stroke-opacity="0"
449
+ pointer-events="stroke"
450
+ @mousedown="${(e: MouseEvent) => this.onMouseDownOnShape(e, shape)}"
451
+ @touchstart="${(e: TouchEvent) => this.onMouseDownOnShape(e, shape)}"
452
+ @mouseenter="${() => (this.svg.style.cursor = 'pointer')}"
453
+ @mouseleave="${() => (this.svg.style.cursor = 'default')}"
405
454
  ></line>
406
455
  ${shape.selected ? this.renderResizeHandles(shape) : ''}
407
456
  `
@@ -411,15 +460,20 @@ export class OxImageMarker extends BaseImageMarker {
411
460
  }
412
461
  }
413
462
 
414
- private onShapeMouseDown(event: MouseEvent | TouchEvent, shape: Shape) {
463
+ private onMouseDownOnShape(event: MouseEvent | TouchEvent, shape: Shape) {
464
+ if (this.currentMode !== 'edit') {
465
+ return
466
+ }
467
+
415
468
  event.stopPropagation()
469
+ event.preventDefault()
416
470
 
417
471
  this.shapes = this.shapes.map(s => ({
418
472
  ...s,
419
473
  selected: s.id === shape.id
420
474
  }))
421
475
 
422
- this.selectedShape = this.shapes.find(s => s.id == shape.id)!
476
+ this.setSelectedShape(this.shapes.find(s => s.id == shape.id)!)
423
477
 
424
478
  const { x, y } = this.getSvgPoint(event)
425
479
 
@@ -432,7 +486,7 @@ export class OxImageMarker extends BaseImageMarker {
432
486
  break
433
487
 
434
488
  case 'triangle':
435
- const points = this.selectedShape.points!.split(' ').map(p => p.split(',').map(Number))
489
+ const points = this.selectedShape!.points!.split(' ').map(p => p.split(',').map(Number))
436
490
  const [px, py] = points[0] || [0, 0]
437
491
 
438
492
  this.offsetX = x - px
@@ -450,19 +504,21 @@ export class OxImageMarker extends BaseImageMarker {
450
504
  const svg = this.svg as SVGSVGElement
451
505
 
452
506
  if ('touches' in event) {
453
- svg.addEventListener('touchmove', this.onShapeMouseMove)
454
- svg.addEventListener('touchend', this.onShapeMouseUp)
507
+ svg.addEventListener('touchmove', this.onMouseMoveOnShape)
508
+ svg.addEventListener('touchend', this.onMouseUpOnShape)
455
509
  } else {
456
- svg.addEventListener('mousemove', this.onShapeMouseMove)
457
- svg.addEventListener('mouseup', this.onShapeMouseUp)
510
+ svg.addEventListener('mousemove', this.onMouseMoveOnShape)
511
+ svg.addEventListener('mouseup', this.onMouseUpOnShape)
458
512
  }
459
513
  }
460
514
 
461
- private onShapeMouseMove = (event: MouseEvent | TouchEvent) => {
515
+ private onMouseMoveOnShape = (event: MouseEvent | TouchEvent) => {
462
516
  if (!this.selectedShape) {
463
517
  return
464
518
  }
465
519
 
520
+ event.preventDefault()
521
+
466
522
  const { x, y } = this.getSvgPoint(event)
467
523
 
468
524
  switch (this.selectedShape.type) {
@@ -499,15 +555,17 @@ export class OxImageMarker extends BaseImageMarker {
499
555
  this.requestUpdate()
500
556
  }
501
557
 
502
- private onShapeMouseUp = (event: MouseEvent | TouchEvent) => {
558
+ private onMouseUpOnShape = (event: MouseEvent | TouchEvent) => {
559
+ event.preventDefault()
560
+
503
561
  const svg = this.svg as SVGSVGElement
504
562
 
505
563
  if ('touches' in event) {
506
- svg.removeEventListener('touchmove', this.onShapeMouseMove)
507
- svg.removeEventListener('touchend', this.onShapeMouseUp)
564
+ svg.removeEventListener('touchmove', this.onMouseMoveOnShape)
565
+ svg.removeEventListener('touchend', this.onMouseUpOnShape)
508
566
  } else {
509
- svg.removeEventListener('mousemove', this.onShapeMouseMove)
510
- svg.removeEventListener('mouseup', this.onShapeMouseUp)
567
+ svg.removeEventListener('mousemove', this.onMouseMoveOnShape)
568
+ svg.removeEventListener('mouseup', this.onMouseUpOnShape)
511
569
  }
512
570
  }
513
571
 
@@ -561,8 +619,8 @@ export class OxImageMarker extends BaseImageMarker {
561
619
  stroke="black"
562
620
  class="resize-handle"
563
621
  style="cursor: ${handle.cursor};"
564
- @mousedown="${(e: MouseEvent) => this.onHandleMouseDown(e, shape, handle)}"
565
- @touchstart="${(e: TouchEvent) => this.onHandleMouseDown(e, shape, handle)}"
622
+ @mousedown="${(e: MouseEvent) => this.onResizeHandleMouseDown(e, shape, handle)}"
623
+ @touchstart="${(e: TouchEvent) => this.onResizeHandleMouseDown(e, shape, handle)}"
566
624
  ></rect>
567
625
  </g>
568
626
  `
@@ -570,37 +628,35 @@ export class OxImageMarker extends BaseImageMarker {
570
628
  `
571
629
  }
572
630
 
573
- private onHandleMouseDown(event: MouseEvent | TouchEvent, shape: Shape, handle: any) {
631
+ private onResizeHandleMouseDown(event: MouseEvent | TouchEvent, shape: Shape, handle: any) {
574
632
  event.stopPropagation()
633
+ event.preventDefault()
634
+
635
+ this.setSelectedShape(shape)
575
636
 
576
- this.selectedShape = shape
577
637
  this.offsetX = handle.x
578
638
  this.offsetY = handle.y
579
639
  const svg = this.svg as SVGSVGElement
580
640
 
581
641
  if ('touches' in event) {
582
- svg.addEventListener('touchmove', this.onHandleMouseMove)
583
- svg.addEventListener('touchend', this.onHandleMouseUp)
642
+ svg.addEventListener('touchmove', this.onResizeHandleMouseMove)
643
+ svg.addEventListener('touchend', this.onResizeHandleMouseUp)
584
644
  } else {
585
- svg.addEventListener('mousemove', this.onHandleMouseMove)
586
- svg.addEventListener('mouseup', this.onHandleMouseUp)
645
+ svg.addEventListener('mousemove', this.onResizeHandleMouseMove)
646
+ svg.addEventListener('mouseup', this.onResizeHandleMouseUp)
587
647
  }
588
648
  }
589
649
 
590
- private onHandleMouseMove = (event: MouseEvent | TouchEvent) => {
650
+ private onResizeHandleMouseMove = (event: MouseEvent | TouchEvent) => {
591
651
  if (!this.selectedShape) {
592
652
  return
593
653
  }
594
654
 
655
+ event.preventDefault()
656
+
595
657
  const { x, y } = this.getSvgPoint(event)
596
658
 
597
659
  switch (this.selectedShape.type) {
598
- // case 'text':
599
- // this.selectedShape.width = Math.abs(x - this.selectedShape.x!)
600
- // this.selectedShape.height = Math.abs(y - this.selectedShape.y!)
601
- // if (x < this.selectedShape.x!) this.selectedShape.x = x
602
- // if (y < this.selectedShape.y!) this.selectedShape.y = y
603
- // break
604
660
  case 'rectangle':
605
661
  const startX = this.selectedShape.x!
606
662
  const startY = this.selectedShape.y!
@@ -670,22 +726,23 @@ export class OxImageMarker extends BaseImageMarker {
670
726
  this.requestUpdate()
671
727
  }
672
728
 
673
- private onHandleMouseUp = (event: MouseEvent | TouchEvent) => {
729
+ private onResizeHandleMouseUp = (event: MouseEvent | TouchEvent) => {
730
+ event.preventDefault()
731
+
674
732
  const svg = this.svg as SVGSVGElement
675
733
 
676
734
  if ('touches' in event) {
677
- svg.removeEventListener('touchmove', this.onHandleMouseMove)
678
- svg.removeEventListener('touchend', this.onHandleMouseUp)
735
+ svg.removeEventListener('touchmove', this.onResizeHandleMouseMove)
736
+ svg.removeEventListener('touchend', this.onResizeHandleMouseUp)
679
737
  } else {
680
- svg.removeEventListener('mousemove', this.onHandleMouseMove)
681
- svg.removeEventListener('mouseup', this.onHandleMouseUp)
738
+ svg.removeEventListener('mousemove', this.onResizeHandleMouseMove)
739
+ svg.removeEventListener('mouseup', this.onResizeHandleMouseUp)
682
740
  }
683
-
684
- this.selectedShape = null
685
741
  }
686
742
 
687
743
  private onTextDoubleClick(event: MouseEvent, shape: Shape) {
688
744
  event.stopPropagation()
745
+ event.preventDefault()
689
746
 
690
747
  const textElement = event.target as SVGTextElement
691
748
 
@@ -825,7 +882,9 @@ export class OxImageMarker extends BaseImageMarker {
825
882
  private deleteSelectedShape() {
826
883
  if (this.selectedShape) {
827
884
  this.shapes = this.shapes.filter(s => s.id !== this.selectedShape!.id)
828
- this.selectedShape = null
885
+
886
+ this.setSelectedShape(null)
887
+
829
888
  this.requestUpdate()
830
889
  }
831
890
  }
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type ShapeType = 'text' | 'rectangle' | 'circle' | 'triangle' | 'line' | 'arrow'
2
- export type ImageMarkerMode = 'move' | 'select' | 'draw'
2
+ export type ImageMarkerMode = 'edit' | 'view' | 'shape'
3
3
  export interface Shape {
4
4
  id: string
5
5
  type: ShapeType