@operato/image-marker 8.0.0-alpha.17 → 8.0.0-alpha.22
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 +16 -4
- package/dist/src/base-image-marker.js +96 -15
- package/dist/src/base-image-marker.js.map +1 -1
- package/dist/src/ox-image-marker-mode.js +2 -2
- package/dist/src/ox-image-marker-mode.js.map +1 -1
- package/dist/src/ox-image-marker-view.js +2 -2
- package/dist/src/ox-image-marker-view.js.map +1 -1
- package/dist/src/ox-image-marker.d.ts +9 -4
- package/dist/src/ox-image-marker.js +162 -92
- package/dist/src/ox-image-marker.js.map +1 -1
- package/dist/stories/ox-image-marker.stories.js +16 -0
- package/dist/stories/ox-image-marker.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/base-image-marker.ts +114 -19
- package/src/ox-image-marker-mode.ts +2 -2
- package/src/ox-image-marker-view.ts +2 -2
- package/src/ox-image-marker.ts +181 -100
- package/stories/ox-image-marker.stories.ts +16 -0
package/src/base-image-marker.ts
CHANGED
|
@@ -36,6 +36,8 @@ export class BaseImageMarker extends LitElement {
|
|
|
36
36
|
protected isPanning = false
|
|
37
37
|
protected panStart = { x: 0, y: 0 }
|
|
38
38
|
protected initialViewBox = '0 0 800 600'
|
|
39
|
+
private initialPinchDistance: number | null = null
|
|
40
|
+
private initialZoomLevel: number = 1
|
|
39
41
|
|
|
40
42
|
@query('svg') protected svg!: SVGSVGElement
|
|
41
43
|
|
|
@@ -50,7 +52,7 @@ export class BaseImageMarker extends LitElement {
|
|
|
50
52
|
img.src = this.imageUrl
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
protected
|
|
55
|
+
protected onSvgWheel(event: WheelEvent) {
|
|
54
56
|
event.preventDefault()
|
|
55
57
|
|
|
56
58
|
const { offsetX, offsetY, deltaY } = event
|
|
@@ -71,21 +73,99 @@ export class BaseImageMarker extends LitElement {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
protected onSvgMouseDown(event: MouseEvent) {
|
|
74
|
-
|
|
76
|
+
this.startPanning(event)
|
|
75
77
|
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
|
|
78
|
+
this.svg.addEventListener('mousemove', this.onPanMouseMove)
|
|
79
|
+
this.svg.addEventListener('mouseup', this.onPanMouseUp)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected onSvgTouchStart = (event: TouchEvent) => {
|
|
83
|
+
if (event.touches.length === 1) {
|
|
84
|
+
this.startPanning(event)
|
|
85
|
+
} else if (event.touches.length === 2) {
|
|
86
|
+
this.startPinchZooming(event)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
protected startPinchZooming(event: TouchEvent) {
|
|
91
|
+
const touch1 = event.touches[0]
|
|
92
|
+
const touch2 = event.touches[1]
|
|
93
|
+
|
|
94
|
+
const dx = touch2.clientX - touch1.clientX
|
|
95
|
+
const dy = touch2.clientY - touch1.clientY
|
|
96
|
+
|
|
97
|
+
this.initialPinchDistance = Math.sqrt(dx * dx + dy * dy)
|
|
98
|
+
this.initialZoomLevel = this.zoomLevel
|
|
99
|
+
|
|
100
|
+
this.svg.addEventListener('touchmove', this.onZoomTouchMove)
|
|
101
|
+
this.svg.addEventListener('touchend', this.onZoomTouchEnd)
|
|
102
|
+
}
|
|
79
103
|
|
|
80
|
-
|
|
81
|
-
|
|
104
|
+
protected onZoomTouchMove = (event: TouchEvent) => {
|
|
105
|
+
if (event.touches.length === 2 && this.initialPinchDistance) {
|
|
106
|
+
const touch1 = event.touches[0]
|
|
107
|
+
const touch2 = event.touches[1]
|
|
108
|
+
const dx = touch2.clientX - touch1.clientX
|
|
109
|
+
const dy = touch2.clientY - touch1.clientY
|
|
110
|
+
const currentPinchDistance = Math.sqrt(dx * dx + dy * dy)
|
|
111
|
+
|
|
112
|
+
const scaleFactor = currentPinchDistance / this.initialPinchDistance
|
|
113
|
+
this.zoomLevel = this.initialZoomLevel * scaleFactor
|
|
114
|
+
|
|
115
|
+
this.applyZoom()
|
|
116
|
+
}
|
|
82
117
|
}
|
|
83
118
|
|
|
84
|
-
protected
|
|
85
|
-
if (
|
|
119
|
+
protected onZoomTouchEnd = (event: TouchEvent) => {
|
|
120
|
+
if (event.touches.length < 2) {
|
|
121
|
+
this.initialPinchDistance = null
|
|
122
|
+
}
|
|
86
123
|
|
|
87
|
-
|
|
88
|
-
|
|
124
|
+
this.svg.removeEventListener('touchmove', this.onZoomTouchMove)
|
|
125
|
+
this.svg.removeEventListener('touchend', this.onZoomTouchEnd)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
protected applyZoom() {
|
|
129
|
+
const [vbX, vbY, vbWidth, vbHeight] = this.viewBox.split(' ').map(Number)
|
|
130
|
+
const initialViewBoxNumbers = this.initialViewBox.split(' ').map(Number)
|
|
131
|
+
const newVbWidth = initialViewBoxNumbers[2] / this.zoomLevel
|
|
132
|
+
const newVbHeight = initialViewBoxNumbers[3] / this.zoomLevel
|
|
133
|
+
const newVbX = vbX + (vbWidth - newVbWidth) / 2
|
|
134
|
+
const newVbY = vbY + (vbHeight - newVbHeight) / 2
|
|
135
|
+
|
|
136
|
+
this.viewBox = `${newVbX} ${newVbY} ${newVbWidth} ${newVbHeight}`
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
protected onSvgDoubleClick() {
|
|
140
|
+
this.viewBox = this.initialViewBox
|
|
141
|
+
this.zoomLevel = 1
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
protected startPanning(event: MouseEvent | TouchEvent) {
|
|
145
|
+
const { x, y } = this.getPointFromEvent(event)
|
|
146
|
+
|
|
147
|
+
this.isPanning = true
|
|
148
|
+
this.panStart = { x, y }
|
|
149
|
+
this.svg.classList.add('dragging')
|
|
150
|
+
|
|
151
|
+
if ('touches' in event) {
|
|
152
|
+
this.svg.addEventListener('touchmove', this.onPanMouseMove)
|
|
153
|
+
this.svg.addEventListener('touchend', this.onPanMouseUp)
|
|
154
|
+
} else {
|
|
155
|
+
this.svg.addEventListener('mousemove', this.onPanMouseMove)
|
|
156
|
+
this.svg.addEventListener('mouseup', this.onPanMouseUp)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
protected onPanMouseMove = (event: MouseEvent | TouchEvent) => {
|
|
161
|
+
if (!this.isPanning) {
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const { x, y } = this.getPointFromEvent(event)
|
|
166
|
+
|
|
167
|
+
const dx = x - this.panStart.x
|
|
168
|
+
const dy = y - this.panStart.y
|
|
89
169
|
|
|
90
170
|
const [vbX, vbY, vbWidth, vbHeight] = this.viewBox.split(' ').map(Number)
|
|
91
171
|
const scaleX = vbWidth / this.svg.clientWidth
|
|
@@ -96,21 +176,22 @@ export class BaseImageMarker extends LitElement {
|
|
|
96
176
|
const newVbY = vbY - dy * scale
|
|
97
177
|
|
|
98
178
|
this.viewBox = `${newVbX} ${newVbY} ${vbWidth} ${vbHeight}`
|
|
99
|
-
this.panStart = { x
|
|
179
|
+
this.panStart = { x, y }
|
|
100
180
|
}
|
|
101
181
|
|
|
102
|
-
protected onPanMouseUp = () => {
|
|
182
|
+
protected onPanMouseUp = (event: MouseEvent | TouchEvent) => {
|
|
103
183
|
const svg = this.svg
|
|
104
184
|
|
|
105
185
|
this.isPanning = false
|
|
106
186
|
svg.classList.remove('dragging')
|
|
107
|
-
svg.removeEventListener('mousemove', this.onPanMouseMove)
|
|
108
|
-
svg.removeEventListener('mouseup', this.onPanMouseUp)
|
|
109
|
-
}
|
|
110
187
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
188
|
+
if ('touches' in event) {
|
|
189
|
+
svg.removeEventListener('touchmove', this.onPanMouseMove)
|
|
190
|
+
svg.removeEventListener('touchend', this.onPanMouseUp)
|
|
191
|
+
} else {
|
|
192
|
+
svg.removeEventListener('mousemove', this.onPanMouseMove)
|
|
193
|
+
svg.removeEventListener('mouseup', this.onPanMouseUp)
|
|
194
|
+
}
|
|
114
195
|
}
|
|
115
196
|
|
|
116
197
|
protected renderShape(shape: Shape) {
|
|
@@ -141,4 +222,18 @@ export class BaseImageMarker extends LitElement {
|
|
|
141
222
|
return nothing
|
|
142
223
|
}
|
|
143
224
|
}
|
|
225
|
+
|
|
226
|
+
protected getPointFromEvent(event: MouseEvent | TouchEvent) {
|
|
227
|
+
if ('touches' in event) {
|
|
228
|
+
return {
|
|
229
|
+
x: event.touches[0].clientX,
|
|
230
|
+
y: event.touches[0].clientY
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
return {
|
|
234
|
+
x: event.clientX,
|
|
235
|
+
y: event.clientY
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
144
239
|
}
|
|
@@ -127,7 +127,7 @@ export class OxImageMarkerMode extends LitElement {
|
|
|
127
127
|
|
|
128
128
|
private onClickDelete() {
|
|
129
129
|
this.dispatchEvent(
|
|
130
|
-
new CustomEvent('
|
|
130
|
+
new CustomEvent('tap-delete', {
|
|
131
131
|
bubbles: true,
|
|
132
132
|
composed: true
|
|
133
133
|
})
|
|
@@ -136,7 +136,7 @@ export class OxImageMarkerMode extends LitElement {
|
|
|
136
136
|
|
|
137
137
|
private onClickSave() {
|
|
138
138
|
this.dispatchEvent(
|
|
139
|
-
new CustomEvent('
|
|
139
|
+
new CustomEvent('tap-save', {
|
|
140
140
|
bubbles: true,
|
|
141
141
|
composed: true
|
|
142
142
|
})
|
|
@@ -9,9 +9,9 @@ export class OxImageMarkerView extends BaseImageMarker {
|
|
|
9
9
|
return html`
|
|
10
10
|
<div class="container">
|
|
11
11
|
<svg
|
|
12
|
-
@wheel=${this.
|
|
12
|
+
@wheel=${this.onSvgWheel}
|
|
13
13
|
@mousedown=${this.onSvgMouseDown}
|
|
14
|
-
@dblclick=${this.
|
|
14
|
+
@dblclick=${this.onSvgDoubleClick}
|
|
15
15
|
viewBox=${this.viewBox}
|
|
16
16
|
>
|
|
17
17
|
<image href=${this.imageUrl} @load=${this.onImageLoad}></image>
|