@annotorious/annotorious 3.0.0-rc.16 → 3.0.0-rc.18
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/dist/Annotorious.d.ts.map +1 -1
- package/dist/annotation/SVGAnnotationLayerPointerEvent.d.ts.map +1 -1
- package/dist/annotation/editors/Handle.svelte.d.ts +1 -0
- package/dist/annotation/editors/editorsRegistry.d.ts +1 -1
- package/dist/annotation/editors/editorsRegistry.d.ts.map +1 -1
- package/dist/annotation/editors/index.d.ts +1 -1
- package/dist/annotation/editors/index.d.ts.map +1 -1
- package/dist/annotation/tools/drawingToolsRegistry.d.ts +4 -4
- package/dist/annotation/tools/drawingToolsRegistry.d.ts.map +1 -1
- package/dist/annotation/utils/responsive.d.ts +2 -1
- package/dist/annotation/utils/responsive.d.ts.map +1 -1
- package/dist/annotation/utils/styling.d.ts +1 -1
- package/dist/annotation/utils/styling.d.ts.map +1 -1
- package/dist/annotation/utils/touch.d.ts.map +1 -1
- package/dist/annotorious.css +1 -1
- package/dist/annotorious.es.js +2373 -2072
- package/dist/annotorious.es.js.map +1 -1
- package/dist/annotorious.js +1 -1
- package/dist/annotorious.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/keyboardCommands.d.ts.map +1 -1
- package/dist/model/w3c/W3CImageAnnotation.d.ts +11 -0
- package/dist/model/w3c/W3CImageAnnotation.d.ts.map +1 -0
- package/dist/model/w3c/W3CImageFormatAdapter.d.ts +3 -2
- package/dist/model/w3c/W3CImageFormatAdapter.d.ts.map +1 -1
- package/dist/model/w3c/fragment/FragmentSelector.d.ts +1 -2
- package/dist/model/w3c/fragment/FragmentSelector.d.ts.map +1 -1
- package/dist/model/w3c/index.d.ts +1 -0
- package/dist/model/w3c/index.d.ts.map +1 -1
- package/dist/model/w3c/svg/SVG.d.ts.map +1 -1
- package/dist/model/w3c/svg/SVGSelector.d.ts +1 -2
- package/dist/model/w3c/svg/SVGSelector.d.ts.map +1 -1
- package/dist/state/spatialTree.d.ts +1 -1
- package/dist/state/spatialTree.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/Annotorious.css +5 -5
- package/src/Annotorious.ts +7 -6
- package/src/annotation/SVGAnnotationLayer.svelte +18 -14
- package/src/annotation/SVGAnnotationLayerPointerEvent.ts +1 -2
- package/src/annotation/Transform.ts +1 -1
- package/src/annotation/editors/Editor.svelte +10 -11
- package/src/annotation/editors/EditorMount.svelte +2 -2
- package/src/annotation/editors/Handle.svelte +66 -0
- package/src/annotation/editors/index.ts +2 -2
- package/src/annotation/editors/polygon/PolygonEditor.svelte +16 -16
- package/src/annotation/editors/rectangle/RectangleEditor.svelte +46 -43
- package/src/annotation/shapes/Ellipse.svelte +2 -2
- package/src/annotation/shapes/Polygon.svelte +2 -2
- package/src/annotation/shapes/Rectangle.svelte +2 -2
- package/src/annotation/tools/ToolMount.svelte +3 -3
- package/src/annotation/tools/drawingToolsRegistry.ts +2 -1
- package/src/annotation/tools/polygon/RubberbandPolygon.svelte +34 -11
- package/src/annotation/tools/rectangle/RubberbandRectangle.svelte +16 -10
- package/src/annotation/utils/responsive.ts +1 -1
- package/src/annotation/utils/touch.ts +4 -1
- package/src/index.ts +1 -2
- package/src/keyboardCommands.ts +8 -4
- package/src/model/w3c/W3CImageAnnotation.ts +17 -0
- package/src/model/w3c/W3CImageFormatAdapter.ts +19 -15
- package/src/model/w3c/fragment/FragmentSelector.ts +5 -6
- package/src/model/w3c/index.ts +1 -0
- package/src/model/w3c/svg/SVG.ts +1 -2
- package/src/model/w3c/svg/SVGSelector.ts +11 -13
- package/src/state/ImageAnnotatorState.ts +3 -3
- package/src/state/spatialTree.ts +3 -2
- package/src/themes/dark/index.css +2 -2
- package/src/themes/light/index.css +2 -2
- package/src/themes/smart/setTheme.ts +2 -2
- package/dist/annotation/editors/Handle.d.ts +0 -14
- package/dist/annotation/editors/Handle.d.ts.map +0 -1
- package/src/annotation/editors/Handle.ts +0 -21
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Handle from '../Handle.svelte';
|
|
3
|
+
import type { Rectangle, Shape } from '../../../model';
|
|
3
4
|
import type { Transform } from '../../Transform';
|
|
4
|
-
import { Editor
|
|
5
|
+
import { Editor } from '..';
|
|
5
6
|
|
|
6
7
|
/** Props */
|
|
7
8
|
export let shape: Rectangle;
|
|
8
|
-
export let computedStyle: string
|
|
9
|
+
export let computedStyle: string | undefined;
|
|
9
10
|
export let transform: Transform;
|
|
10
11
|
export let viewportScale: number = 1;
|
|
11
12
|
|
|
12
13
|
$: geom = shape.geometry;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const editor = (rectangle: Rectangle, handle: Handle, delta: [number, number]) => {
|
|
15
|
+
const editor = (rectangle: Shape, handle: string, delta: [number, number]) => {
|
|
17
16
|
const initialBounds = rectangle.geometry.bounds;
|
|
18
17
|
|
|
19
18
|
let [x0, y0] = [initialBounds.minX, initialBounds.minY];
|
|
@@ -21,39 +20,39 @@
|
|
|
21
20
|
|
|
22
21
|
const [dx, dy] = delta;
|
|
23
22
|
|
|
24
|
-
if (handle ===
|
|
23
|
+
if (handle === 'SHAPE') {
|
|
25
24
|
x0 += dx;
|
|
26
25
|
x1 += dx;
|
|
27
26
|
y0 += dy;
|
|
28
27
|
y1 += dy;
|
|
29
28
|
} else {
|
|
30
29
|
switch (handle) {
|
|
31
|
-
case
|
|
32
|
-
case
|
|
33
|
-
case
|
|
30
|
+
case 'TOP':
|
|
31
|
+
case 'TOP_LEFT':
|
|
32
|
+
case 'TOP_RIGHT': {
|
|
34
33
|
y0 += dy;
|
|
35
34
|
break;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
case
|
|
39
|
-
case
|
|
40
|
-
case
|
|
37
|
+
case 'BOTTOM':
|
|
38
|
+
case 'BOTTOM_LEFT':
|
|
39
|
+
case 'BOTTOM_RIGHT': {
|
|
41
40
|
y1 += dy;
|
|
42
41
|
break;
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
switch (handle) {
|
|
47
|
-
case
|
|
48
|
-
case
|
|
49
|
-
case
|
|
46
|
+
case 'LEFT':
|
|
47
|
+
case 'TOP_LEFT':
|
|
48
|
+
case 'BOTTOM_LEFT': {
|
|
50
49
|
x0 += dx;
|
|
51
50
|
break;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
case
|
|
55
|
-
case
|
|
56
|
-
case
|
|
53
|
+
case 'RIGHT':
|
|
54
|
+
case 'TOP_RIGHT':
|
|
55
|
+
case 'BOTTOM_RIGHT': {
|
|
57
56
|
x1 += dx;
|
|
58
57
|
break;
|
|
59
58
|
}
|
|
@@ -92,52 +91,56 @@
|
|
|
92
91
|
<rect
|
|
93
92
|
class="a9s-outer"
|
|
94
93
|
style={computedStyle ? 'display:none;' : undefined}
|
|
95
|
-
on:pointerdown={grab(
|
|
94
|
+
on:pointerdown={grab('SHAPE')}
|
|
96
95
|
x={geom.x} y={geom.y} width={geom.w} height={geom.h} />
|
|
97
96
|
|
|
98
97
|
<rect
|
|
99
98
|
class="a9s-inner a9s-shape-handle"
|
|
100
99
|
style={computedStyle}
|
|
101
|
-
on:pointerdown={grab(
|
|
100
|
+
on:pointerdown={grab('SHAPE')}
|
|
102
101
|
x={geom.x} y={geom.y} width={geom.w} height={geom.h} />
|
|
103
102
|
|
|
104
103
|
<rect
|
|
105
104
|
class="a9s-edge-handle a9s-edge-handle-top"
|
|
106
|
-
on:pointerdown={grab(
|
|
105
|
+
on:pointerdown={grab('TOP')}
|
|
107
106
|
x={geom.x} y={geom.y} height={1} width={geom.w} />
|
|
108
107
|
|
|
109
108
|
<rect
|
|
110
109
|
class="a9s-edge-handle a9s-edge-handle-right"
|
|
111
|
-
on:pointerdown={grab(
|
|
110
|
+
on:pointerdown={grab('RIGHT')}
|
|
112
111
|
x={geom.x + geom.w} y={geom.y} height={geom.h} width={1}/>
|
|
113
112
|
|
|
114
113
|
<rect
|
|
115
114
|
class="a9s-edge-handle a9s-edge-handle-bottom"
|
|
116
|
-
on:pointerdown={grab(
|
|
115
|
+
on:pointerdown={grab('BOTTOM')}
|
|
117
116
|
x={geom.x} y={geom.y + geom.h} height={1} width={geom.w} />
|
|
118
117
|
|
|
119
118
|
<rect
|
|
120
119
|
class="a9s-edge-handle a9s-edge-handle-left"
|
|
121
|
-
on:pointerdown={grab(
|
|
120
|
+
on:pointerdown={grab('LEFT')}
|
|
122
121
|
x={geom.x} y={geom.y} height={geom.h} width={1} />
|
|
123
122
|
|
|
124
|
-
<
|
|
125
|
-
class="a9s-corner-handle
|
|
126
|
-
on:pointerdown={grab(
|
|
127
|
-
x={geom.x
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
<Handle
|
|
124
|
+
class="a9s-corner-handle-topleft"
|
|
125
|
+
on:pointerdown={grab('TOP_LEFT')}
|
|
126
|
+
x={geom.x} y={geom.y}
|
|
127
|
+
scale={viewportScale} />
|
|
128
|
+
|
|
129
|
+
<Handle
|
|
130
|
+
class="a9s-corner-handle-topright"
|
|
131
|
+
on:pointerdown={grab('TOP_RIGHT')}
|
|
132
|
+
x={geom.x + geom.w} y={geom.y}
|
|
133
|
+
scale={viewportScale} />
|
|
133
134
|
|
|
134
|
-
<
|
|
135
|
-
class="a9s-corner-handle
|
|
136
|
-
on:pointerdown={grab(
|
|
137
|
-
x={geom.x + geom.w
|
|
135
|
+
<Handle
|
|
136
|
+
class="a9s-corner-handle-bottomright"
|
|
137
|
+
on:pointerdown={grab('BOTTOM_RIGHT')}
|
|
138
|
+
x={geom.x + geom.w} y={geom.y + geom.h}
|
|
139
|
+
scale={viewportScale} />
|
|
138
140
|
|
|
139
|
-
<
|
|
140
|
-
class="a9s-corner-handle
|
|
141
|
-
on:pointerdown={grab(
|
|
142
|
-
x={geom.x
|
|
141
|
+
<Handle
|
|
142
|
+
class="a9s-corner-handle-bottomleft"
|
|
143
|
+
on:pointerdown={grab('BOTTOM_LEFT')}
|
|
144
|
+
x={geom.x} y={geom.y + geom.h}
|
|
145
|
+
scale={viewportScale} />
|
|
143
146
|
</Editor>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import type { DrawingStyle } from '@annotorious/core';
|
|
3
3
|
import type { Geometry, EllipseGeometry, ImageAnnotation } from '../../model';
|
|
4
4
|
import { computeStyle } from '../utils/styling';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/** Props */
|
|
7
7
|
export let annotation: ImageAnnotation;
|
|
8
8
|
export let geom: Geometry;
|
|
9
|
-
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle)
|
|
9
|
+
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
|
|
10
10
|
|
|
11
11
|
$: computedStyle = computeStyle(annotation, style);
|
|
12
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import type { DrawingStyle } from '@annotorious/core';
|
|
3
3
|
import type { Geometry, ImageAnnotation, PolygonGeometry } from '../../model';
|
|
4
4
|
import { computeStyle } from '../utils/styling';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/** Props **/
|
|
7
7
|
export let annotation: ImageAnnotation;
|
|
8
8
|
export let geom: Geometry;
|
|
9
|
-
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle)
|
|
9
|
+
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
|
|
10
10
|
|
|
11
11
|
$: computedStyle = computeStyle(annotation, style);
|
|
12
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import type { DrawingStyle } from '@annotorious/core';
|
|
3
3
|
import type { Geometry, ImageAnnotation, RectangleGeometry } from '../../model';
|
|
4
4
|
import { computeStyle } from '../utils/styling';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/** Props **/
|
|
7
7
|
export let annotation: ImageAnnotation;
|
|
8
8
|
export let geom: Geometry;
|
|
9
|
-
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle)
|
|
9
|
+
export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
|
|
10
10
|
|
|
11
11
|
$: computedStyle = computeStyle(annotation, style);
|
|
12
12
|
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
|
|
24
24
|
const cleanup: Function[] = [];
|
|
25
25
|
|
|
26
|
-
const addEventListener = (name:
|
|
27
|
-
svg
|
|
28
|
-
cleanup.push(() => svg
|
|
26
|
+
const addEventListener = (name: keyof SVGSVGElementEventMap, handler: EventListenerOrEventListenerObject, capture?: boolean) => {
|
|
27
|
+
svg?.addEventListener(name, handler, capture);
|
|
28
|
+
cleanup.push(() => svg?.removeEventListener(name, handler, capture));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
toolComponent = new tool({
|
|
@@ -9,10 +9,11 @@ export type DrawingToolOpts = {
|
|
|
9
9
|
|
|
10
10
|
drawingMode?: DrawingMode;
|
|
11
11
|
|
|
12
|
-
[key: string]:
|
|
12
|
+
[key: string]: any;
|
|
13
13
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
// @ts-ignore
|
|
16
17
|
const REGISTERED = new Map<DrawingTool, { tool: typeof SvelteComponent, opts?: DrawingToolOpts }>([
|
|
17
18
|
['rectangle', { tool: RubberbandRectangle }],
|
|
18
19
|
['polygon', { tool: RubberbandPolygon }]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import { onMount, createEventDispatcher } from 'svelte';
|
|
3
3
|
import type { DrawingMode } from '../../../AnnotoriousOpts';
|
|
4
4
|
import { boundsFromPoints, computeArea, ShapeType, type Polygon } from '../../../model';
|
|
@@ -17,15 +17,24 @@
|
|
|
17
17
|
|
|
18
18
|
let points: [number, number][] = [];
|
|
19
19
|
|
|
20
|
-
let cursor: [number, number]
|
|
20
|
+
let cursor: [number, number] | undefined;
|
|
21
|
+
|
|
22
|
+
// Keep track of the user keeping the finger
|
|
23
|
+
// in place. Long pauses will be interpreted like a
|
|
24
|
+
// double click and close the shape.
|
|
25
|
+
let touchPauseTimer: number | undefined;
|
|
21
26
|
|
|
22
27
|
let isClosable: boolean = false;
|
|
23
28
|
|
|
24
29
|
const CLOSE_DISTANCE = 20;
|
|
25
30
|
|
|
31
|
+
const TOUCH_PAUSE_LIMIT = 1500;
|
|
32
|
+
|
|
26
33
|
$: handleSize = 10 / viewportScale;
|
|
27
34
|
|
|
28
|
-
const onPointerDown = (
|
|
35
|
+
const onPointerDown = (event: Event) => {
|
|
36
|
+
const evt = event as PointerEvent;
|
|
37
|
+
|
|
29
38
|
// Note that the event itself is ephemeral!
|
|
30
39
|
const { timeStamp, offsetX, offsetY } = evt;
|
|
31
40
|
lastPointerDown = { timeStamp, offsetX, offsetY };
|
|
@@ -40,7 +49,11 @@
|
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
const onPointerMove = (
|
|
52
|
+
const onPointerMove = (event: Event) => {
|
|
53
|
+
const evt = event as PointerEvent;
|
|
54
|
+
|
|
55
|
+
if (touchPauseTimer) clearTimeout(touchPauseTimer);
|
|
56
|
+
|
|
44
57
|
if (points.length > 0) {
|
|
45
58
|
cursor = transform.elementToImage(evt.offsetX, evt.offsetY);
|
|
46
59
|
|
|
@@ -48,10 +61,18 @@
|
|
|
48
61
|
const d = distance(cursor, points[0]) * viewportScale;
|
|
49
62
|
isClosable = d < CLOSE_DISTANCE;
|
|
50
63
|
}
|
|
64
|
+
|
|
65
|
+
if (evt.pointerType === 'touch') {
|
|
66
|
+
touchPauseTimer = setTimeout(() => {
|
|
67
|
+
onDblClick();
|
|
68
|
+
}, TOUCH_PAUSE_LIMIT);
|
|
69
|
+
}
|
|
51
70
|
}
|
|
52
71
|
}
|
|
53
72
|
|
|
54
|
-
const onPointerUp = (
|
|
73
|
+
const onPointerUp = (event: Event) => {
|
|
74
|
+
const evt = event as PointerEvent;
|
|
75
|
+
|
|
55
76
|
if (drawingMode === 'click') {
|
|
56
77
|
const timeDifference = evt.timeStamp - lastPointerDown.timeStamp;
|
|
57
78
|
|
|
@@ -71,17 +92,17 @@
|
|
|
71
92
|
|
|
72
93
|
cursor = point;
|
|
73
94
|
} else {
|
|
74
|
-
points.push(cursor);
|
|
95
|
+
points.push(cursor!);
|
|
75
96
|
}
|
|
76
97
|
} else {
|
|
77
98
|
// Require minimum drag of 4px
|
|
78
99
|
if (points.length === 1) {
|
|
79
|
-
const dist = distance(points[0], cursor);
|
|
100
|
+
const dist = distance(points[0], cursor!);
|
|
80
101
|
|
|
81
102
|
if (dist <= 4) {
|
|
82
103
|
// Cancel
|
|
83
104
|
points = [];
|
|
84
|
-
cursor =
|
|
105
|
+
cursor = undefined;
|
|
85
106
|
|
|
86
107
|
return;
|
|
87
108
|
}
|
|
@@ -93,12 +114,14 @@
|
|
|
93
114
|
if (isClosable) {
|
|
94
115
|
stopDrawing();
|
|
95
116
|
} else {
|
|
96
|
-
points.push(cursor);
|
|
117
|
+
points.push(cursor!);
|
|
97
118
|
}
|
|
98
119
|
}
|
|
99
120
|
}
|
|
100
121
|
|
|
101
122
|
const onDblClick = () => {
|
|
123
|
+
if (!cursor) return;
|
|
124
|
+
|
|
102
125
|
// Require min 3 points (incl. cursor) and minimum
|
|
103
126
|
// polygon area
|
|
104
127
|
const p = [...points, cursor];
|
|
@@ -114,7 +137,7 @@
|
|
|
114
137
|
const area = computeArea(shape);
|
|
115
138
|
if (area > 4) {
|
|
116
139
|
points = [];
|
|
117
|
-
cursor =
|
|
140
|
+
cursor = undefined;
|
|
118
141
|
|
|
119
142
|
dispatch('create', shape);
|
|
120
143
|
}
|
|
@@ -130,7 +153,7 @@
|
|
|
130
153
|
}
|
|
131
154
|
|
|
132
155
|
points = [];
|
|
133
|
-
cursor =
|
|
156
|
+
cursor = undefined;
|
|
134
157
|
|
|
135
158
|
dispatch('create', shape);
|
|
136
159
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script lang="ts">
|
|
2
2
|
import { createEventDispatcher, onMount } from 'svelte';
|
|
3
3
|
import type { DrawingMode } from '../../../AnnotoriousOpts';
|
|
4
4
|
import { ShapeType, type Rectangle } from '../../../model';
|
|
@@ -13,13 +13,15 @@
|
|
|
13
13
|
|
|
14
14
|
let lastPointerDown: number;
|
|
15
15
|
|
|
16
|
-
let origin: [x: number, y: number];
|
|
16
|
+
let origin: [x: number, y: number] | undefined;
|
|
17
17
|
|
|
18
|
-
let anchor: [number, number];
|
|
18
|
+
let anchor: [number, number] | undefined;
|
|
19
19
|
|
|
20
20
|
let x: number, y: number, w: number, h: number;
|
|
21
21
|
|
|
22
|
-
const onPointerDown = (
|
|
22
|
+
const onPointerDown = (event: Event) => {
|
|
23
|
+
const evt = event as PointerEvent;
|
|
24
|
+
|
|
23
25
|
lastPointerDown = performance.now();
|
|
24
26
|
|
|
25
27
|
if (drawingMode === 'drag') {
|
|
@@ -33,7 +35,9 @@
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
const onPointerMove = (
|
|
38
|
+
const onPointerMove = (event: Event) => {
|
|
39
|
+
const evt = event as PointerEvent;
|
|
40
|
+
|
|
37
41
|
if (origin) {
|
|
38
42
|
anchor = transform.elementToImage(evt.offsetX, evt.offsetY);
|
|
39
43
|
|
|
@@ -44,7 +48,9 @@
|
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
const onPointerUp = (
|
|
51
|
+
const onPointerUp = (event: Event) => {
|
|
52
|
+
const evt = event as PointerEvent;
|
|
53
|
+
|
|
48
54
|
const timeDifference = performance.now() - lastPointerDown;
|
|
49
55
|
|
|
50
56
|
if (drawingMode === 'click') {
|
|
@@ -71,8 +77,8 @@
|
|
|
71
77
|
evt.stopPropagation();
|
|
72
78
|
stopDrawing();
|
|
73
79
|
} else {
|
|
74
|
-
origin =
|
|
75
|
-
anchor =
|
|
80
|
+
origin = undefined;
|
|
81
|
+
anchor = undefined;
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
}
|
|
@@ -96,8 +102,8 @@
|
|
|
96
102
|
dispatch('create', shape);
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
origin =
|
|
100
|
-
anchor =
|
|
105
|
+
origin = undefined;
|
|
106
|
+
anchor = undefined;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
onMount(() => {
|
package/src/index.ts
CHANGED
package/src/keyboardCommands.ts
CHANGED
|
@@ -9,15 +9,19 @@ export const initKeyboardCommands = <T extends Annotation>(
|
|
|
9
9
|
|
|
10
10
|
const el = container || document;
|
|
11
11
|
|
|
12
|
-
const onWinKeyDown = (
|
|
13
|
-
|
|
12
|
+
const onWinKeyDown = (evt: Event) => {
|
|
13
|
+
const event = evt as KeyboardEvent;
|
|
14
|
+
|
|
15
|
+
if (event.key === 'z' && event.ctrlKey) {
|
|
14
16
|
undoStack.undo();
|
|
15
|
-
} else if (event.key === '
|
|
17
|
+
} else if (event.key === 'y' && event.ctrlKey) {
|
|
16
18
|
undoStack.redo()
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
|
|
20
|
-
const onMacKeyDown = (
|
|
22
|
+
const onMacKeyDown = (evt: Event) => {
|
|
23
|
+
const event = evt as KeyboardEvent;
|
|
24
|
+
|
|
21
25
|
if (event.key === 'z' && event.metaKey) {
|
|
22
26
|
if (event.shiftKey) {
|
|
23
27
|
undoStack.redo()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { W3CAnnotation, W3CAnnotationTarget } from '@annotorious/core';
|
|
2
|
+
import type { FragmentSelector } from './fragment';
|
|
3
|
+
import type { SVGSelector } from './svg';
|
|
4
|
+
|
|
5
|
+
export interface W3CImageAnnotation extends W3CAnnotation {
|
|
6
|
+
|
|
7
|
+
target: W3CImageAnnotationTarget | W3CImageAnnotationTarget[];
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface W3CImageAnnotationTarget extends W3CAnnotationTarget {
|
|
12
|
+
|
|
13
|
+
selector: W3CImageSelector | W3CImageSelector[];
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type W3CImageSelector = FragmentSelector | SVGSelector;
|
|
@@ -3,12 +3,13 @@ import { parseW3CUser, parseW3CBodies, serializeW3CBodies } from '@annotorious/c
|
|
|
3
3
|
import type { FormatAdapter, ParseResult, W3CAnnotation } from '@annotorious/core';
|
|
4
4
|
import { ShapeType } from '../core';
|
|
5
5
|
import type { ImageAnnotation, RectangleGeometry } from '../core';
|
|
6
|
-
import type {
|
|
6
|
+
import type {FragmentSelector } from './fragment';
|
|
7
7
|
import { parseFragmentSelector, serializeFragmentSelector } from './fragment';
|
|
8
8
|
import type { SVGSelector } from './svg';
|
|
9
9
|
import { parseSVGSelector, serializeSVGSelector } from './svg';
|
|
10
|
+
import type { W3CImageAnnotation } from './W3CImageAnnotation';
|
|
10
11
|
|
|
11
|
-
export type W3CImageFormatAdapter = FormatAdapter<ImageAnnotation,
|
|
12
|
+
export type W3CImageFormatAdapter = FormatAdapter<ImageAnnotation, W3CImageAnnotation>;
|
|
12
13
|
|
|
13
14
|
export const W3CImageFormat = (
|
|
14
15
|
source: string,
|
|
@@ -33,22 +34,23 @@ export const parseW3CImageAnnotation = (
|
|
|
33
34
|
const {
|
|
34
35
|
creator,
|
|
35
36
|
created,
|
|
36
|
-
|
|
37
|
-
updated,
|
|
37
|
+
modified,
|
|
38
38
|
body,
|
|
39
39
|
...rest
|
|
40
40
|
} = annotation;
|
|
41
41
|
|
|
42
42
|
const bodies = parseW3CBodies(body, annotationId);
|
|
43
43
|
|
|
44
|
-
const
|
|
44
|
+
const w3cTarget = Array.isArray(annotation.target)
|
|
45
|
+
? annotation.target[0] : annotation.target;
|
|
45
46
|
|
|
46
|
-
const w3cSelector = Array.isArray(
|
|
47
|
+
const w3cSelector = Array.isArray(w3cTarget.selector)
|
|
48
|
+
? w3cTarget.selector[0] : w3cTarget.selector;
|
|
47
49
|
|
|
48
50
|
const selector =
|
|
49
|
-
w3cSelector
|
|
51
|
+
w3cSelector?.type === 'FragmentSelector' ?
|
|
50
52
|
parseFragmentSelector(w3cSelector as FragmentSelector, invertY) :
|
|
51
|
-
w3cSelector
|
|
53
|
+
w3cSelector?.type === 'SvgSelector' ?
|
|
52
54
|
parseSVGSelector(w3cSelector as SVGSelector) : undefined;
|
|
53
55
|
|
|
54
56
|
return selector ? {
|
|
@@ -59,13 +61,14 @@ export const parseW3CImageAnnotation = (
|
|
|
59
61
|
target: {
|
|
60
62
|
created: created ? new Date(created) : undefined,
|
|
61
63
|
creator: parseW3CUser(creator),
|
|
64
|
+
updated: modified ? new Date(modified) : undefined,
|
|
62
65
|
...rest.target,
|
|
63
66
|
annotation: annotationId,
|
|
64
67
|
selector
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
} : {
|
|
68
|
-
error: Error(`
|
|
71
|
+
error: Error(`Invalid selector: ${JSON.stringify(w3cSelector)}`)
|
|
69
72
|
};
|
|
70
73
|
|
|
71
74
|
}
|
|
@@ -73,13 +76,13 @@ export const parseW3CImageAnnotation = (
|
|
|
73
76
|
export const serializeW3CImageAnnotation = (
|
|
74
77
|
annotation: ImageAnnotation,
|
|
75
78
|
source: string
|
|
76
|
-
):
|
|
79
|
+
): W3CImageAnnotation => {
|
|
77
80
|
const {
|
|
78
81
|
selector,
|
|
79
82
|
creator,
|
|
80
83
|
created,
|
|
81
|
-
updated,
|
|
82
|
-
updatedBy,
|
|
84
|
+
updated,
|
|
85
|
+
updatedBy, // Excluded from serialization
|
|
83
86
|
...rest
|
|
84
87
|
} = annotation.target;
|
|
85
88
|
|
|
@@ -94,12 +97,13 @@ export const serializeW3CImageAnnotation = (
|
|
|
94
97
|
id: annotation.id,
|
|
95
98
|
type: 'Annotation',
|
|
96
99
|
body: serializeW3CBodies(annotation.bodies),
|
|
97
|
-
creator,
|
|
98
100
|
created: created?.toISOString(),
|
|
101
|
+
creator,
|
|
102
|
+
modified: updated?.toISOString(),
|
|
99
103
|
target: {
|
|
100
104
|
...rest,
|
|
101
105
|
source,
|
|
102
106
|
selector: w3CSelector
|
|
103
107
|
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import type { W3CSelector } from '@annotorious/core';
|
|
2
|
-
import { ShapeType } from '../../core';
|
|
3
1
|
import type { Rectangle, RectangleGeometry } from '../../core';
|
|
2
|
+
import { ShapeType } from '../../core';
|
|
4
3
|
|
|
5
|
-
export interface FragmentSelector
|
|
4
|
+
export interface FragmentSelector {
|
|
6
5
|
|
|
7
6
|
type: 'FragmentSelector';
|
|
8
7
|
|
|
9
8
|
conformsTo: 'http://www.w3.org/TR/media-frags/',
|
|
10
9
|
|
|
11
10
|
value: string;
|
|
12
|
-
|
|
11
|
+
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export const parseFragmentSelector = (
|
|
@@ -46,7 +45,7 @@ export const parseFragmentSelector = (
|
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
|
-
}
|
|
48
|
+
}
|
|
50
49
|
|
|
51
50
|
export const serializeFragmentSelector = (geometry: RectangleGeometry): FragmentSelector => {
|
|
52
51
|
const { x, y, w, h } = geometry;
|
|
@@ -56,4 +55,4 @@ export const serializeFragmentSelector = (geometry: RectangleGeometry): Fragment
|
|
|
56
55
|
conformsTo: 'http://www.w3.org/TR/media-frags/',
|
|
57
56
|
value: `xywh=pixel:${x},${y},${w},${h}`
|
|
58
57
|
};
|
|
59
|
-
}
|
|
58
|
+
}
|
package/src/model/w3c/index.ts
CHANGED
package/src/model/w3c/svg/SVG.ts
CHANGED
|
@@ -13,8 +13,7 @@ export const sanitize = (doc: Element | Document) => {
|
|
|
13
13
|
// Remove script tags
|
|
14
14
|
const scripts = doc.getElementsByTagName('script');
|
|
15
15
|
|
|
16
|
-
Array.from(scripts).reverse().forEach(el =>
|
|
17
|
-
el.parentNode.removeChild(el));
|
|
16
|
+
Array.from(scripts).reverse().forEach(el => el.parentNode!.removeChild(el));
|
|
18
17
|
|
|
19
18
|
Array.from(doc.querySelectorAll('*')).forEach(cleanEl);
|
|
20
19
|
|