box-annotations 4.0.0-beta.8 → 4.0.1-beta.1
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/README.md +7 -57
- package/dist/annotations.css +1 -1
- package/dist/annotations.js +1 -1
- package/i18n/bn-IN.js +6 -0
- package/i18n/bn-IN.properties +12 -0
- package/i18n/da-DK.js +6 -0
- package/i18n/da-DK.properties +12 -0
- package/i18n/de-DE.js +6 -0
- package/i18n/de-DE.properties +12 -0
- package/i18n/en-AU.js +6 -0
- package/i18n/en-AU.properties +12 -0
- package/i18n/en-CA.js +6 -0
- package/i18n/en-CA.properties +12 -0
- package/i18n/en-GB.js +6 -0
- package/i18n/en-GB.properties +12 -0
- package/i18n/en-US.js +6 -0
- package/i18n/en-US.properties +12 -0
- package/i18n/en-x-pseudo.js +16 -9
- package/i18n/en-x-pseudo.properties +23 -9
- package/i18n/es-419.js +6 -0
- package/i18n/es-419.properties +12 -0
- package/i18n/es-ES.js +6 -0
- package/i18n/es-ES.properties +12 -0
- package/i18n/fi-FI.js +6 -0
- package/i18n/fi-FI.properties +12 -0
- package/i18n/fr-CA.js +6 -0
- package/i18n/fr-CA.properties +12 -0
- package/i18n/fr-FR.js +6 -0
- package/i18n/fr-FR.properties +12 -0
- package/i18n/hi-IN.js +6 -0
- package/i18n/hi-IN.properties +12 -0
- package/i18n/it-IT.js +6 -0
- package/i18n/it-IT.properties +12 -0
- package/i18n/ja-JP.js +6 -0
- package/i18n/ja-JP.properties +12 -0
- package/i18n/json/src/components/Popups/messages.json +1 -1
- package/i18n/ko-KR.js +6 -0
- package/i18n/ko-KR.properties +12 -0
- package/i18n/nb-NO.js +6 -0
- package/i18n/nb-NO.properties +12 -0
- package/i18n/nl-NL.js +6 -0
- package/i18n/nl-NL.properties +12 -0
- package/i18n/pl-PL.js +6 -0
- package/i18n/pl-PL.properties +12 -0
- package/i18n/pt-BR.js +6 -0
- package/i18n/pt-BR.properties +12 -0
- package/i18n/ru-RU.js +6 -0
- package/i18n/ru-RU.properties +12 -0
- package/i18n/sv-SE.js +6 -0
- package/i18n/sv-SE.properties +12 -0
- package/i18n/tr-TR.js +6 -0
- package/i18n/tr-TR.properties +12 -0
- package/i18n/zh-CN.js +6 -0
- package/i18n/zh-CN.properties +12 -0
- package/i18n/zh-TW.js +6 -0
- package/i18n/zh-TW.properties +12 -0
- package/package.json +29 -29
- package/src/@types/events.ts +8 -2
- package/src/@types/global.ts +1 -0
- package/src/@types/model.ts +20 -7
- package/src/BoxAnnotations.ts +16 -2
- package/src/common/BaseAnnotator.scss +0 -1
- package/src/common/BaseAnnotator.ts +125 -19
- package/src/common/BaseManager.ts +67 -4
- package/src/common/DeselectListener.tsx +21 -0
- package/src/common/DeselectManager.tsx +30 -0
- package/src/common/useIsListInteractive.ts +10 -0
- package/src/common/useMountId.ts +14 -0
- package/src/common/useOutsideEvent.ts +9 -4
- package/src/common/usePrevious.ts +13 -0
- package/src/components/ItemList/ItemList.scss +7 -2
- package/src/components/ItemList/ItemList.tsx +45 -26
- package/src/components/ItemList/ItemRow.scss +19 -7
- package/src/components/ItemList/ItemRow.tsx +33 -12
- package/src/components/PointerCapture/PointerCapture.tsx +116 -0
- package/src/components/PointerCapture/index.ts +2 -0
- package/src/components/Popups/Popper.ts +1 -0
- package/src/components/Popups/PopupArrow.scss +91 -0
- package/src/components/Popups/PopupBase.scss +12 -81
- package/src/components/Popups/PopupBase.tsx +0 -1
- package/src/components/Popups/PopupCursor.tsx +1 -1
- package/src/components/Popups/PopupDrawingToolbar.scss +76 -0
- package/src/components/Popups/PopupDrawingToolbar.tsx +109 -0
- package/src/components/Popups/PopupHighlight.scss +39 -0
- package/src/components/Popups/PopupHighlight.tsx +97 -0
- package/src/components/Popups/PopupHighlightError.scss +23 -0
- package/src/components/Popups/PopupHighlightError.tsx +74 -0
- package/src/components/Popups/PopupList.scss +1 -4
- package/src/components/Popups/PopupList.tsx +2 -2
- package/src/components/Popups/PopupReply.tsx +51 -6
- package/src/components/Popups/messages.ts +30 -0
- package/src/components/ReplyField/ReplyField.scss +6 -1
- package/src/components/ReplyField/ReplyField.tsx +43 -42
- package/src/components/ReplyField/ReplyFieldContainer.tsx +2 -1
- package/src/components/ReplyForm/ReplyButton.tsx +38 -0
- package/src/components/ReplyForm/ReplyForm.scss +3 -0
- package/src/components/ReplyForm/ReplyForm.tsx +49 -12
- package/src/components/ReplyForm/ReplyFormContainer.tsx +6 -4
- package/src/constants.js +1 -8
- package/src/document/DocumentAnnotator.scss +15 -0
- package/src/document/DocumentAnnotator.ts +110 -53
- package/src/document/docUtil.ts +61 -0
- package/src/drawing/DecoratedDrawingPath.scss +9 -0
- package/src/drawing/DecoratedDrawingPath.tsx +43 -0
- package/src/drawing/DrawingAnnotations.scss +39 -0
- package/src/drawing/DrawingAnnotations.tsx +157 -0
- package/src/drawing/DrawingAnnotationsContainer.tsx +66 -0
- package/src/drawing/DrawingCreator.scss +9 -0
- package/src/drawing/DrawingCreator.tsx +183 -0
- package/src/drawing/DrawingCursor.ts +23 -0
- package/src/drawing/DrawingList.tsx +60 -0
- package/src/drawing/DrawingManager.tsx +15 -0
- package/src/drawing/DrawingPath.tsx +17 -0
- package/src/drawing/DrawingPathGroup.tsx +52 -0
- package/src/drawing/DrawingSVG.tsx +34 -0
- package/src/drawing/DrawingSVGGroup.tsx +23 -0
- package/src/drawing/DrawingTarget.scss +11 -0
- package/src/drawing/DrawingTarget.tsx +100 -0
- package/src/drawing/SVGFilterContext.js +5 -0
- package/src/drawing/actions.ts +48 -0
- package/src/drawing/drawingUtil.ts +106 -0
- package/src/drawing/index.ts +2 -0
- package/src/highlight/HighlightAnnotations.scss +12 -0
- package/src/highlight/HighlightAnnotations.tsx +144 -0
- package/src/highlight/HighlightCanvas.scss +9 -0
- package/src/highlight/HighlightCanvas.tsx +109 -0
- package/src/highlight/HighlightContainer.tsx +64 -0
- package/src/highlight/HighlightCreator.scss +12 -0
- package/src/highlight/HighlightCreatorManager.ts +79 -0
- package/src/highlight/HighlightList.scss +13 -0
- package/src/highlight/HighlightList.tsx +92 -0
- package/src/highlight/HighlightListener.ts +37 -0
- package/src/highlight/HighlightManager.tsx +15 -0
- package/src/highlight/HighlightSvg.scss +7 -0
- package/src/highlight/HighlightSvg.tsx +18 -0
- package/src/highlight/HighlightTarget.scss +5 -0
- package/src/highlight/HighlightTarget.tsx +106 -0
- package/src/highlight/actions.ts +36 -0
- package/src/highlight/highlightUtil.ts +143 -0
- package/src/highlight/index.ts +4 -0
- package/src/image/ImageAnnotator.scss +20 -0
- package/src/image/ImageAnnotator.ts +137 -0
- package/src/polyfill.ts +19 -0
- package/src/popup/PopupContainer.tsx +50 -0
- package/src/popup/PopupLayer.scss +3 -0
- package/src/popup/PopupLayer.tsx +103 -0
- package/src/popup/PopupManager.tsx +15 -0
- package/src/region/RegionAnnotation.scss +4 -0
- package/src/region/RegionAnnotation.tsx +15 -16
- package/src/region/RegionAnnotations.scss +1 -15
- package/src/region/RegionAnnotations.tsx +14 -115
- package/src/region/RegionAnnotationsContainer.tsx +24 -0
- package/src/region/RegionCreation.scss +17 -0
- package/src/region/RegionCreation.tsx +79 -0
- package/src/region/RegionCreationContainer.tsx +43 -0
- package/src/region/RegionCreationManager.tsx +15 -0
- package/src/region/RegionCreator.scss +9 -2
- package/src/region/RegionCreator.tsx +50 -71
- package/src/region/RegionList.tsx +8 -12
- package/src/region/RegionManager.tsx +7 -39
- package/src/region/RegionRect.scss +41 -9
- package/src/region/RegionRect.tsx +9 -3
- package/src/region/index.ts +1 -0
- package/src/region/regionUtil.ts +1 -8
- package/src/region/transformUtil.ts +28 -0
- package/src/store/annotations/actions.ts +1 -0
- package/src/store/annotations/reducer.ts +9 -2
- package/src/store/annotations/selectors.ts +1 -0
- package/src/store/annotations/types.ts +1 -0
- package/src/store/common/actions.ts +1 -0
- package/src/store/common/reducer.ts +16 -10
- package/src/store/common/selectors.ts +1 -0
- package/src/store/common/types.ts +3 -0
- package/src/store/createRootReducer.ts +4 -0
- package/src/store/creator/actions.ts +2 -0
- package/src/store/creator/reducer.ts +22 -3
- package/src/store/creator/selectors.ts +9 -1
- package/src/store/creator/types.ts +18 -3
- package/src/store/drawing/actions.ts +10 -0
- package/src/store/drawing/index.ts +4 -0
- package/src/store/drawing/reducer.ts +50 -0
- package/src/store/drawing/selectors.ts +9 -0
- package/src/store/drawing/types.ts +7 -0
- package/src/store/eventing/active.ts +4 -2
- package/src/store/eventing/fetch.ts +8 -0
- package/src/store/eventing/init.ts +14 -0
- package/src/store/eventing/middleware.ts +21 -3
- package/src/store/eventing/mode.ts +7 -0
- package/src/store/eventing/staged.ts +56 -0
- package/src/store/eventing/status.ts +19 -0
- package/src/store/highlight/actions.ts +106 -0
- package/src/store/highlight/index.ts +4 -0
- package/src/store/highlight/reducer.ts +37 -0
- package/src/store/highlight/selectors.ts +12 -0
- package/src/store/highlight/types.ts +14 -0
- package/src/store/index.ts +2 -0
- package/src/store/options/actions.ts +2 -0
- package/src/store/options/reducer.ts +17 -1
- package/src/store/options/selectors.ts +8 -0
- package/src/store/options/types.ts +5 -0
- package/src/store/types.ts +5 -1
- package/src/store/users/actions.ts +3 -2
- package/src/utils/resin.ts +22 -0
- package/src/utils/rotate.ts +131 -0
- package/src/utils/scroll.ts +45 -0
- package/src/utils/util.ts +3 -0
- package/src/region/RegionContainer.tsx +0 -49
- package/src/utils/polyfill.js +0 -161
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { createReducer } from '@reduxjs/toolkit';
|
|
2
2
|
import { OptionsState } from './types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
setFileIdAction,
|
|
5
|
+
setFileVersionIdAction,
|
|
6
|
+
setPermissionsAction,
|
|
7
|
+
setRotationAction,
|
|
8
|
+
setScaleAction,
|
|
9
|
+
} from './actions';
|
|
4
10
|
|
|
5
11
|
export const initialState = {
|
|
12
|
+
features: {},
|
|
6
13
|
fileId: null,
|
|
7
14
|
fileVersionId: null,
|
|
15
|
+
isCurrentFileVersion: true,
|
|
8
16
|
permissions: {},
|
|
17
|
+
rotation: 0,
|
|
18
|
+
scale: 1,
|
|
9
19
|
};
|
|
10
20
|
|
|
11
21
|
export default createReducer<OptionsState>(initialState, builder =>
|
|
@@ -18,5 +28,11 @@ export default createReducer<OptionsState>(initialState, builder =>
|
|
|
18
28
|
})
|
|
19
29
|
.addCase(setPermissionsAction, (state, { payload }) => {
|
|
20
30
|
state.permissions = payload;
|
|
31
|
+
})
|
|
32
|
+
.addCase(setRotationAction, (state, { payload }) => {
|
|
33
|
+
state.rotation = payload;
|
|
34
|
+
})
|
|
35
|
+
.addCase(setScaleAction, (state, { payload }) => {
|
|
36
|
+
state.scale = payload;
|
|
21
37
|
}),
|
|
22
38
|
);
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import getProp from 'lodash/get';
|
|
1
2
|
import { AppState } from '../types';
|
|
2
3
|
import { Permissions } from '../../@types';
|
|
4
|
+
import { Features } from '../../BoxAnnotations';
|
|
3
5
|
|
|
4
6
|
type State = Pick<AppState, 'options'>;
|
|
5
7
|
|
|
8
|
+
export const getFeatures = (state: State): Features => state.options.features;
|
|
6
9
|
export const getFileId = (state: State): string | null => state.options.fileId;
|
|
7
10
|
export const getFileVersionId = (state: State): string | null => state.options.fileVersionId;
|
|
11
|
+
export const getIsCurrentFileVersion = (state: State): boolean => state.options.isCurrentFileVersion;
|
|
8
12
|
export const getPermissions = (state: State): Permissions => state.options.permissions;
|
|
13
|
+
export const getRotation = (state: State): number => state.options.rotation;
|
|
14
|
+
export const getScale = (state: State): number => state.options.scale;
|
|
15
|
+
export const isFeatureEnabled = (state: State, featurename: string): boolean =>
|
|
16
|
+
getProp(getFeatures(state), featurename, false);
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { Features } from '../../BoxAnnotations';
|
|
1
2
|
import { Permissions } from '../../@types';
|
|
2
3
|
|
|
3
4
|
export type OptionsState = {
|
|
5
|
+
features: Features;
|
|
4
6
|
fileId: string | null;
|
|
5
7
|
fileVersionId: string | null;
|
|
8
|
+
isCurrentFileVersion: boolean;
|
|
6
9
|
permissions: Permissions;
|
|
10
|
+
rotation: number;
|
|
11
|
+
scale: number;
|
|
7
12
|
};
|
package/src/store/types.ts
CHANGED
|
@@ -4,13 +4,17 @@ import API from '../api';
|
|
|
4
4
|
import { AnnotationsState } from './annotations';
|
|
5
5
|
import { CommonState } from './common';
|
|
6
6
|
import { CreatorState } from './creator';
|
|
7
|
+
import { DrawingState } from './drawing';
|
|
8
|
+
import { HighlightState } from './highlight';
|
|
7
9
|
import { OptionsState } from './options';
|
|
8
10
|
import { UsersState } from './users';
|
|
9
11
|
|
|
10
12
|
export type AppState = {
|
|
11
13
|
annotations: AnnotationsState;
|
|
12
|
-
creator: CreatorState;
|
|
13
14
|
common: CommonState;
|
|
15
|
+
creator: CreatorState;
|
|
16
|
+
drawing: DrawingState;
|
|
17
|
+
highlight: HighlightState;
|
|
14
18
|
options: OptionsState;
|
|
15
19
|
users: UsersState;
|
|
16
20
|
};
|
|
@@ -4,9 +4,9 @@ import { AppThunkAPI } from '../types';
|
|
|
4
4
|
import { Collaborator } from '../../@types';
|
|
5
5
|
import { getFileId } from '../options';
|
|
6
6
|
|
|
7
|
-
export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collaborator>,
|
|
7
|
+
export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collaborator>, string, AppThunkAPI>(
|
|
8
8
|
'FETCH_COLLABORATORS',
|
|
9
|
-
async (
|
|
9
|
+
async (searchString = '', { extra, getState, signal }) => {
|
|
10
10
|
// Create a new client for each request
|
|
11
11
|
const client = extra.api.getCollaboratorsAPI();
|
|
12
12
|
const state = getState();
|
|
@@ -20,6 +20,7 @@ export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collabora
|
|
|
20
20
|
// Wrap the client request in a promise to allow it to be returned and cancelled
|
|
21
21
|
return new Promise<APICollection<Collaborator>>((resolve, reject) => {
|
|
22
22
|
client.getFileCollaborators(fileId, resolve, reject, {
|
|
23
|
+
filter_term: searchString, // eslint-disable-line @typescript-eslint/camelcase
|
|
23
24
|
include_groups: false, // eslint-disable-line @typescript-eslint/camelcase
|
|
24
25
|
include_uploader_collabs: false, // eslint-disable-line @typescript-eslint/camelcase
|
|
25
26
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function stringify(value: unknown): string {
|
|
2
|
+
if (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol') {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
return typeof value === 'string' ? value : String(value);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function applyResinTags(element: HTMLElement, attributes: Record<string, unknown>): void {
|
|
10
|
+
if (!element || !Object.values(attributes).length) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
15
|
+
const attribute = `data-resin-${key.toLowerCase()}`;
|
|
16
|
+
const stringValue = stringify(value);
|
|
17
|
+
|
|
18
|
+
if (stringValue) {
|
|
19
|
+
element.setAttribute(attribute, stringValue);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Dimensions, Position, Shape } from '../@types';
|
|
2
|
+
|
|
3
|
+
export type Translation = {
|
|
4
|
+
dx?: number;
|
|
5
|
+
dy?: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Possible rotation values as supplied by box-content-preview
|
|
9
|
+
const ROTATION_ONCE_DEG = -90;
|
|
10
|
+
const ROTATION_TWICE_DEG = -180;
|
|
11
|
+
const ROTATION_THRICE_DEG = -270;
|
|
12
|
+
|
|
13
|
+
// Annotation shapes are, by default, percentages, so a 100x100 space
|
|
14
|
+
const DEFAULT_DIMENSIONS = { height: 100, width: 100 };
|
|
15
|
+
|
|
16
|
+
export const invertYCoordinate = ({ x, y }: Position, height: number): Position => ({
|
|
17
|
+
x,
|
|
18
|
+
y: height > 0 ? height - y : y,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const rotatePoint = ({ x, y }: Position, rotationInDegrees: number): Position => {
|
|
22
|
+
const radians = (rotationInDegrees * Math.PI) / 180;
|
|
23
|
+
const cosine = Math.cos(radians);
|
|
24
|
+
const sine = Math.sin(radians);
|
|
25
|
+
|
|
26
|
+
// Formula to apply a rotation to a position is:
|
|
27
|
+
// x' = x * cos(θ) - y * sin(θ)
|
|
28
|
+
// y' = x * sin(θ) + y * cos(θ)
|
|
29
|
+
return {
|
|
30
|
+
x: x * cosine - y * sine,
|
|
31
|
+
y: x * sine + y * cosine,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const getPoints = (shape: Shape): [Position, Position, Position, Position] => {
|
|
36
|
+
const { height, width, x, y } = shape;
|
|
37
|
+
|
|
38
|
+
// Define the points from x,y and then in a clockwise fashion
|
|
39
|
+
// p1 p2
|
|
40
|
+
// +-------+
|
|
41
|
+
// | |
|
|
42
|
+
// +-------+
|
|
43
|
+
// p4 p3
|
|
44
|
+
const p1 = { x, y };
|
|
45
|
+
const p2 = { x: x + width, y };
|
|
46
|
+
const p3 = { x: x + width, y: y + height };
|
|
47
|
+
const p4 = { x, y: y + height };
|
|
48
|
+
|
|
49
|
+
return [p1, p2, p3, p4];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const translatePoint = ({ x, y }: Position, { dx = 0, dy = 0 }: { dx?: number; dy?: number }): Position => ({
|
|
53
|
+
x: x + dx,
|
|
54
|
+
y: y + dy,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export function selectTransformationPoint(shape: Shape, rotation: number): Position {
|
|
58
|
+
const [p1, p2, p3, p4] = getPoints(shape);
|
|
59
|
+
|
|
60
|
+
// Determine which position will be the new x,y (as defined as the top left position) after rotation
|
|
61
|
+
// If -90deg: use p2
|
|
62
|
+
// If -180deg: use p3
|
|
63
|
+
// If -270deg: use p4
|
|
64
|
+
// Otherwise: use p1
|
|
65
|
+
switch (rotation) {
|
|
66
|
+
case ROTATION_ONCE_DEG:
|
|
67
|
+
return p2;
|
|
68
|
+
case ROTATION_TWICE_DEG:
|
|
69
|
+
return p3;
|
|
70
|
+
case ROTATION_THRICE_DEG:
|
|
71
|
+
return p4;
|
|
72
|
+
default:
|
|
73
|
+
return p1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Determines the translation needed to anchor the bottom left corner of the
|
|
78
|
+
// coordinate space at the (0, 0) origin after rotation.
|
|
79
|
+
export function selectTranslation(dimensions: Dimensions, rotation: number): Translation {
|
|
80
|
+
const { height, width } = dimensions;
|
|
81
|
+
|
|
82
|
+
switch (rotation) {
|
|
83
|
+
case ROTATION_ONCE_DEG:
|
|
84
|
+
return { dx: height };
|
|
85
|
+
case ROTATION_TWICE_DEG:
|
|
86
|
+
return { dx: width, dy: height };
|
|
87
|
+
case ROTATION_THRICE_DEG:
|
|
88
|
+
return { dy: width };
|
|
89
|
+
default:
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { dx: 0, dy: 0 };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function getRotatedShape(shape: Shape, rotation: number): Shape {
|
|
96
|
+
const { height: shapeHeight, width: shapeWidth } = shape;
|
|
97
|
+
const { height: spaceHeight, width: spaceWidth } = DEFAULT_DIMENSIONS;
|
|
98
|
+
const isInverted = rotation % 180 === 0;
|
|
99
|
+
const isNoRotation = rotation % 360 === 0;
|
|
100
|
+
const translation = selectTranslation(DEFAULT_DIMENSIONS, rotation);
|
|
101
|
+
const position = selectTransformationPoint(shape, rotation);
|
|
102
|
+
|
|
103
|
+
if (isNoRotation) {
|
|
104
|
+
return shape;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// To transform from shape with 0 rotation to provided rotation:
|
|
108
|
+
// 1. Invert y-axis to convert from web to mathematical coordinate system
|
|
109
|
+
// 2. Apply rotation transformation (with inverted rotation -- again mathematical coordinate system)
|
|
110
|
+
// 3. Translate to align coordinate space with mathematical origin
|
|
111
|
+
// 4. Invert y-axis to convert back to web coordinate system
|
|
112
|
+
const invertedPoint = invertYCoordinate(position, spaceHeight);
|
|
113
|
+
const rotatedPoint = rotatePoint(invertedPoint, -rotation);
|
|
114
|
+
const translatedPoint = translatePoint(rotatedPoint, translation);
|
|
115
|
+
const { x: transformedX, y: transformedY } = invertYCoordinate(
|
|
116
|
+
translatedPoint,
|
|
117
|
+
isInverted ? spaceHeight : spaceWidth,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
height: isInverted ? shapeHeight : shapeWidth,
|
|
122
|
+
width: isInverted ? shapeWidth : shapeHeight,
|
|
123
|
+
x: transformedX,
|
|
124
|
+
y: transformedY,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function getRotatedPosition({ x, y }: Position, rotation: number): Position {
|
|
129
|
+
const { x: rotatedX, y: rotatedY } = getRotatedShape({ height: 0, width: 0, x, y }, rotation);
|
|
130
|
+
return { x: rotatedX, y: rotatedY };
|
|
131
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Position } from '../@types';
|
|
2
|
+
|
|
3
|
+
export type ScrollOptions = {
|
|
4
|
+
offsets?: Position;
|
|
5
|
+
threshold?: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const DEFAULT_OFFSETS = { x: 0, y: 0 };
|
|
9
|
+
|
|
10
|
+
export function scrollToLocation(parentEl: HTMLElement, referenceEl: HTMLElement, options: ScrollOptions = {}): void {
|
|
11
|
+
const { offsets = DEFAULT_OFFSETS } = options;
|
|
12
|
+
const { x: offsetXPercentage, y: offsetYPercentage } = offsets;
|
|
13
|
+
// Get the bounding client rects so that the offsetLeft of the reference element can be calculated --
|
|
14
|
+
// even if it has been transformed via rotation
|
|
15
|
+
const { left: parentLeft, top: parentTop } = parentEl.getBoundingClientRect();
|
|
16
|
+
const {
|
|
17
|
+
height: referenceHeight,
|
|
18
|
+
left: referenceLeft,
|
|
19
|
+
top: referenceTop,
|
|
20
|
+
width: referenceWidth,
|
|
21
|
+
} = referenceEl.getBoundingClientRect();
|
|
22
|
+
|
|
23
|
+
// Get the midpoint of the scrollable area (parent element)
|
|
24
|
+
const parentCenterX = Math.round(parentEl.clientWidth / 2);
|
|
25
|
+
const parentCenterY = Math.round(parentEl.clientHeight / 2);
|
|
26
|
+
|
|
27
|
+
// Get any specified offset relative to the reference element
|
|
28
|
+
const offsetX = Math.round(referenceWidth * (offsetXPercentage / 100)); // offsetX is assumed to be a percentage
|
|
29
|
+
const offsetY = Math.round(referenceHeight * (offsetYPercentage / 100)); // offsetY is assumed to be a percentage
|
|
30
|
+
|
|
31
|
+
// Get the positioning of the reference element relative to the parent and the viewport
|
|
32
|
+
const referenceOffsetLeft = referenceLeft - parentLeft;
|
|
33
|
+
const referenceOffsetTop = referenceTop - parentTop;
|
|
34
|
+
|
|
35
|
+
// Get the scroll offsets to center the parent element on the top left corner of the reference element and then apply any provided offset
|
|
36
|
+
const offsetScrollLeft = referenceOffsetLeft - parentCenterX + offsetX;
|
|
37
|
+
const offsetScrollTop = referenceOffsetTop - parentCenterY + offsetY;
|
|
38
|
+
|
|
39
|
+
// Get the absolute scroll offsets by applying the delta to the current value
|
|
40
|
+
const scrollLeft = Math.max(0, Math.min(parentEl.scrollLeft + offsetScrollLeft, parentEl.scrollWidth));
|
|
41
|
+
const scrollTop = Math.max(0, Math.min(parentEl.scrollTop + offsetScrollTop, parentEl.scrollHeight));
|
|
42
|
+
|
|
43
|
+
parentEl.scrollLeft = scrollLeft;
|
|
44
|
+
parentEl.scrollTop = scrollTop;
|
|
45
|
+
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { connect } from 'react-redux';
|
|
2
|
-
import { AnnotationRegion } from '../@types';
|
|
3
|
-
import {
|
|
4
|
-
AppState,
|
|
5
|
-
CreatorItem,
|
|
6
|
-
CreatorStatus,
|
|
7
|
-
getActiveAnnotationId,
|
|
8
|
-
getAnnotationMode,
|
|
9
|
-
getAnnotationsForLocation,
|
|
10
|
-
getCreatorMessage,
|
|
11
|
-
getCreatorStagedForLocation,
|
|
12
|
-
getCreatorStatus,
|
|
13
|
-
setActiveAnnotationIdAction,
|
|
14
|
-
setMessageAction,
|
|
15
|
-
setStagedAction,
|
|
16
|
-
setStatusAction,
|
|
17
|
-
} from '../store';
|
|
18
|
-
import RegionAnnotations from './RegionAnnotations';
|
|
19
|
-
import withProviders from '../common/withProviders';
|
|
20
|
-
import { createRegionAction } from './actions';
|
|
21
|
-
import { isRegion } from './regionUtil';
|
|
22
|
-
|
|
23
|
-
export type Props = {
|
|
24
|
-
activeAnnotationId: string | null;
|
|
25
|
-
annotations: AnnotationRegion[];
|
|
26
|
-
isCreating: boolean;
|
|
27
|
-
message: string;
|
|
28
|
-
staged: CreatorItem | null;
|
|
29
|
-
status: CreatorStatus;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const mapStateToProps = (state: AppState, { page }: { page: number }): Props => ({
|
|
33
|
-
activeAnnotationId: getActiveAnnotationId(state),
|
|
34
|
-
annotations: getAnnotationsForLocation(state, page).filter(isRegion),
|
|
35
|
-
isCreating: getAnnotationMode(state) === 'region',
|
|
36
|
-
message: getCreatorMessage(state),
|
|
37
|
-
staged: getCreatorStagedForLocation(state, page),
|
|
38
|
-
status: getCreatorStatus(state),
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
export const mapDispatchToProps = {
|
|
42
|
-
createRegion: createRegionAction,
|
|
43
|
-
setActiveAnnotationId: setActiveAnnotationIdAction,
|
|
44
|
-
setMessage: setMessageAction,
|
|
45
|
-
setStaged: setStagedAction,
|
|
46
|
-
setStatus: setStatusAction,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export default connect(mapStateToProps, mapDispatchToProps)(withProviders(RegionAnnotations));
|
package/src/utils/polyfill.js
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
(function() {
|
|
3
|
-
var testObject = {};
|
|
4
|
-
|
|
5
|
-
if (!(Object.setPrototypeOf || testObject.__proto__)) {
|
|
6
|
-
var nativeGetPrototypeOf = Object.getPrototypeOf;
|
|
7
|
-
|
|
8
|
-
Object.getPrototypeOf = function(object) {
|
|
9
|
-
if (object.__proto__) {
|
|
10
|
-
return object.__proto__;
|
|
11
|
-
} else {
|
|
12
|
-
return nativeGetPrototypeOf.call(Object, object);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
})();
|
|
17
|
-
|
|
18
|
-
if (typeof Object.assign != 'function') {
|
|
19
|
-
(function() {
|
|
20
|
-
Object.assign = function(target) {
|
|
21
|
-
'use strict';
|
|
22
|
-
if (target === undefined || target === null) {
|
|
23
|
-
throw new TypeError('Cannot convert undefined or null to object');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
var output = Object(target);
|
|
27
|
-
for (var index = 1; index < arguments.length; index++) {
|
|
28
|
-
var source = arguments[index];
|
|
29
|
-
if (source !== undefined && source !== null) {
|
|
30
|
-
for (var nextKey in source) {
|
|
31
|
-
if (source.hasOwnProperty(nextKey)) {
|
|
32
|
-
output[nextKey] = source[nextKey];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return output;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// https://tc39.github.io/ecma262/#sec-array.prototype.find
|
|
43
|
-
if (!Array.prototype.find) {
|
|
44
|
-
Object.defineProperty(Array.prototype, 'find', {
|
|
45
|
-
configurable: true,
|
|
46
|
-
enumerable: false,
|
|
47
|
-
writable: true,
|
|
48
|
-
value: function(predicate) {
|
|
49
|
-
// 1. Let O be ? ToObject(this value).
|
|
50
|
-
if (this == null) {
|
|
51
|
-
throw new TypeError('"this" is null or not defined');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
var o = Object(this);
|
|
55
|
-
|
|
56
|
-
// 2. Let len be ? ToLength(? Get(O, "length")).
|
|
57
|
-
var len = o.length >>> 0;
|
|
58
|
-
|
|
59
|
-
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
|
60
|
-
if (typeof predicate !== 'function') {
|
|
61
|
-
throw new TypeError('predicate must be a function');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
65
|
-
var thisArg = arguments[1];
|
|
66
|
-
|
|
67
|
-
// 5. Let k be 0.
|
|
68
|
-
var k = 0;
|
|
69
|
-
|
|
70
|
-
// 6. Repeat, while k < len
|
|
71
|
-
while (k < len) {
|
|
72
|
-
// a. Let Pk be ! ToString(k).
|
|
73
|
-
// b. Let kValue be ? Get(O, Pk).
|
|
74
|
-
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
|
|
75
|
-
// d. If testResult is true, return kValue.
|
|
76
|
-
var kValue = o[k];
|
|
77
|
-
if (predicate.call(thisArg, kValue, k, o)) {
|
|
78
|
-
return kValue;
|
|
79
|
-
}
|
|
80
|
-
// e. Increase k by 1.
|
|
81
|
-
k++;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// 7. Return undefined.
|
|
85
|
-
return undefined;
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
|
|
91
|
-
if (!Array.prototype.includes) {
|
|
92
|
-
Object.defineProperty(Array.prototype, 'includes', {
|
|
93
|
-
configurable: true,
|
|
94
|
-
enumerable: false,
|
|
95
|
-
writable: true,
|
|
96
|
-
value: function(searchElement, fromIndex) {
|
|
97
|
-
// 1. Let O be ? ToObject(this value).
|
|
98
|
-
if (this == null) {
|
|
99
|
-
throw new TypeError('"this" is null or not defined');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
var o = Object(this);
|
|
103
|
-
|
|
104
|
-
// 2. Let len be ? ToLength(? Get(O, "length")).
|
|
105
|
-
var len = o.length >>> 0;
|
|
106
|
-
|
|
107
|
-
// 3. If len is 0, return false.
|
|
108
|
-
if (len === 0) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// 4. Let n be ? ToInteger(fromIndex).
|
|
113
|
-
// (If fromIndex is undefined, this step produces the value 0.)
|
|
114
|
-
var n = fromIndex | 0;
|
|
115
|
-
|
|
116
|
-
// 5. If n ≥ 0, then
|
|
117
|
-
// a. Let k be n.
|
|
118
|
-
// 6. Else n < 0,
|
|
119
|
-
// a. Let k be len + n.
|
|
120
|
-
// b. If k < 0, let k be 0.
|
|
121
|
-
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
|
122
|
-
|
|
123
|
-
function sameValueZero(x, y) {
|
|
124
|
-
return x === y || (typeof x === 'Number' && typeof y === 'Number' && isNaN(x) && isNaN(y));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 7. Repeat, while k < len
|
|
128
|
-
while (k < len) {
|
|
129
|
-
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
|
|
130
|
-
// b. If SameValueZero(searchElement, elementK) is true, return true.
|
|
131
|
-
// c. Increase k by 1.
|
|
132
|
-
if (sameValueZero(o[k], searchElement)) {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
k++;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 8. Return false
|
|
139
|
-
return false;
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Add support for SVGElement.contains in IE11
|
|
145
|
-
if (!SVGElement.prototype.contains) {
|
|
146
|
-
Object.defineProperty(SVGElement.prototype, 'contains', {
|
|
147
|
-
configurable: true,
|
|
148
|
-
enumerable: false,
|
|
149
|
-
writable: true,
|
|
150
|
-
value: function contains(node) {
|
|
151
|
-
do {
|
|
152
|
-
if (this === node) {
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
} while ((node = node && node.parentNode));
|
|
156
|
-
|
|
157
|
-
return false;
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
/* eslint-enable */
|