@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.
- package/CHANGELOG.md +18 -0
- package/dist/src/base-image-marker.d.ts +3 -0
- package/dist/src/base-image-marker.js +20 -0
- package/dist/src/base-image-marker.js.map +1 -1
- package/dist/src/ox-image-marker-mode.d.ts +3 -2
- package/dist/src/ox-image-marker-mode.js +23 -13
- package/dist/src/ox-image-marker-mode.js.map +1 -1
- package/dist/src/ox-image-marker-view.js +1 -0
- package/dist/src/ox-image-marker-view.js.map +1 -1
- package/dist/src/ox-image-marker.d.ts +11 -8
- package/dist/src/ox-image-marker.js +126 -81
- package/dist/src/ox-image-marker.js.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/base-image-marker.ts +30 -0
- package/src/ox-image-marker-mode.ts +28 -15
- package/src/ox-image-marker-view.ts +1 -0
- package/src/ox-image-marker.ts +140 -81
- package/src/types.ts +1 -1
|
@@ -38,62 +38,66 @@ export class OxImageMarkerMode extends LitElement {
|
|
|
38
38
|
}
|
|
39
39
|
`
|
|
40
40
|
|
|
41
|
-
@property({ type: String }) currentMode: ImageMarkerMode = '
|
|
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="
|
|
49
|
-
?selected=${this.currentMode !== '
|
|
50
|
-
@click=${() => this.setMode(this.currentMode !== '
|
|
51
|
-
>${this.currentMode !== '
|
|
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 === '
|
|
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 === '
|
|
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 === '
|
|
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 === '
|
|
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 === '
|
|
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 === '
|
|
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
|
-
|
|
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
|
-
|
|
117
|
-
this.currentMode = '
|
|
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: '
|
|
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
|
}
|
package/src/ox-image-marker.ts
CHANGED
|
@@ -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:
|
|
31
|
+
cursor: default;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
svg
|
|
34
|
-
cursor:
|
|
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 = '
|
|
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
|
-
|
|
104
|
-
this.shapes = this.shapes.map(s => {
|
|
105
|
-
return { ...s, selected: false }
|
|
106
|
-
})
|
|
108
|
+
event.preventDefault()
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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.
|
|
118
|
-
this.shapes = this.shapes.map(s => {
|
|
119
|
-
return { ...s, selected: false }
|
|
120
|
-
})
|
|
127
|
+
this.setSelectedShape(null)
|
|
121
128
|
|
|
122
|
-
if (this.currentMode === '
|
|
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.
|
|
155
|
-
this.svg.addEventListener('touchend', this.
|
|
161
|
+
this.svg.addEventListener('touchmove', this.onMouseMoveForDrawing)
|
|
162
|
+
this.svg.addEventListener('touchend', this.onMouseUpForDrawing)
|
|
156
163
|
} else {
|
|
157
|
-
this.svg.addEventListener('mousemove', this.
|
|
158
|
-
this.svg.addEventListener('mouseup', this.
|
|
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
|
|
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
|
|
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.
|
|
277
|
-
svg.removeEventListener('touchend', this.
|
|
291
|
+
svg.removeEventListener('touchmove', this.onMouseMoveForDrawing)
|
|
292
|
+
svg.removeEventListener('touchend', this.onMouseUpForDrawing)
|
|
278
293
|
} else {
|
|
279
|
-
svg.removeEventListener('mousemove', this.
|
|
280
|
-
svg.removeEventListener('mouseup', this.
|
|
294
|
+
svg.removeEventListener('mousemove', this.onMouseMoveForDrawing)
|
|
295
|
+
svg.removeEventListener('mouseup', this.onMouseUpForDrawing)
|
|
281
296
|
}
|
|
282
297
|
|
|
283
|
-
|
|
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.
|
|
319
|
-
@touchstart="${(e: TouchEvent) => this.
|
|
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.
|
|
336
|
-
@touchstart="${(e: TouchEvent) => this.
|
|
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.
|
|
352
|
-
@touchstart="${(e: TouchEvent) => this.
|
|
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.
|
|
366
|
-
@touchstart="${(e: TouchEvent) => this.
|
|
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
|
-
|
|
382
|
-
|
|
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
|
-
|
|
404
|
-
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
454
|
-
svg.addEventListener('touchend', this.
|
|
507
|
+
svg.addEventListener('touchmove', this.onMouseMoveOnShape)
|
|
508
|
+
svg.addEventListener('touchend', this.onMouseUpOnShape)
|
|
455
509
|
} else {
|
|
456
|
-
svg.addEventListener('mousemove', this.
|
|
457
|
-
svg.addEventListener('mouseup', this.
|
|
510
|
+
svg.addEventListener('mousemove', this.onMouseMoveOnShape)
|
|
511
|
+
svg.addEventListener('mouseup', this.onMouseUpOnShape)
|
|
458
512
|
}
|
|
459
513
|
}
|
|
460
514
|
|
|
461
|
-
private
|
|
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
|
|
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.
|
|
507
|
-
svg.removeEventListener('touchend', this.
|
|
564
|
+
svg.removeEventListener('touchmove', this.onMouseMoveOnShape)
|
|
565
|
+
svg.removeEventListener('touchend', this.onMouseUpOnShape)
|
|
508
566
|
} else {
|
|
509
|
-
svg.removeEventListener('mousemove', this.
|
|
510
|
-
svg.removeEventListener('mouseup', this.
|
|
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.
|
|
565
|
-
@touchstart="${(e: TouchEvent) => this.
|
|
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
|
|
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.
|
|
583
|
-
svg.addEventListener('touchend', this.
|
|
642
|
+
svg.addEventListener('touchmove', this.onResizeHandleMouseMove)
|
|
643
|
+
svg.addEventListener('touchend', this.onResizeHandleMouseUp)
|
|
584
644
|
} else {
|
|
585
|
-
svg.addEventListener('mousemove', this.
|
|
586
|
-
svg.addEventListener('mouseup', this.
|
|
645
|
+
svg.addEventListener('mousemove', this.onResizeHandleMouseMove)
|
|
646
|
+
svg.addEventListener('mouseup', this.onResizeHandleMouseUp)
|
|
587
647
|
}
|
|
588
648
|
}
|
|
589
649
|
|
|
590
|
-
private
|
|
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
|
|
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.
|
|
678
|
-
svg.removeEventListener('touchend', this.
|
|
735
|
+
svg.removeEventListener('touchmove', this.onResizeHandleMouseMove)
|
|
736
|
+
svg.removeEventListener('touchend', this.onResizeHandleMouseUp)
|
|
679
737
|
} else {
|
|
680
|
-
svg.removeEventListener('mousemove', this.
|
|
681
|
-
svg.removeEventListener('mouseup', this.
|
|
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
|
-
|
|
885
|
+
|
|
886
|
+
this.setSelectedShape(null)
|
|
887
|
+
|
|
829
888
|
this.requestUpdate()
|
|
830
889
|
}
|
|
831
890
|
}
|
package/src/types.ts
CHANGED