dbf-mirador 4.3.0-testing1 → 4.3.0-testing3
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/AudioViewer-tRH73pbt.js +40 -0
- package/dist/AudioViewer-tRH73pbt.js.map +1 -0
- package/dist/CommentSharp-BJ6oQAe3.js +322 -0
- package/dist/CommentSharp-BJ6oQAe3.js.map +1 -0
- package/dist/FailedImageContext-BhA0TpVp.js +339 -0
- package/dist/FailedImageContext-BhA0TpVp.js.map +1 -0
- package/dist/GalleryView-rCx0Q4f3.js +176 -0
- package/dist/GalleryView-rCx0Q4f3.js.map +1 -0
- package/dist/OpenSeadragonViewer-B_KV5sbU.js +7889 -0
- package/dist/OpenSeadragonViewer-B_KV5sbU.js.map +1 -0
- package/dist/PluginHook-DWFCXIIp.js +54 -0
- package/dist/PluginHook-DWFCXIIp.js.map +1 -0
- package/dist/SelectCollection-BK9ZDkK3.js +67 -0
- package/dist/SelectCollection-BK9ZDkK3.js.map +1 -0
- package/dist/TextViewer-D_1qzQE4.js +38 -0
- package/dist/TextViewer-D_1qzQE4.js.map +1 -0
- package/dist/VideoViewer-DzNjgLWE.js +42 -0
- package/dist/VideoViewer-DzNjgLWE.js.map +1 -0
- package/dist/WindowCanvasNavigationControls-D2uLtL_A.js +242 -0
- package/dist/WindowCanvasNavigationControls-D2uLtL_A.js.map +1 -0
- package/dist/WindowViewer-DMNeTH1_.js +27 -0
- package/dist/WindowViewer-DMNeTH1_.js.map +1 -0
- package/dist/WorkspaceArea-CzKnpSim.js +22222 -0
- package/dist/WorkspaceArea-CzKnpSim.js.map +1 -0
- package/dist/action-types-DjIbTE-A.js +74 -0
- package/dist/action-types-DjIbTE-A.js.map +1 -0
- package/dist/canvas-2ACcnS9Y.js +41 -0
- package/dist/canvas-2ACcnS9Y.js.map +1 -0
- package/dist/canvases-DTR37lo-.js +3270 -0
- package/dist/canvases-DTR37lo-.js.map +1 -0
- package/dist/createSvgIcon-Cwt8YPfm.js +2 -0
- package/dist/getters-B4oepJRC.js +2043 -0
- package/dist/getters-B4oepJRC.js.map +1 -0
- package/dist/index.module-CgUBfaXx.js +403 -0
- package/dist/index.module-CgUBfaXx.js.map +1 -0
- package/dist/mirador.es.js +9222 -0
- package/dist/mirador.es.js.map +1 -0
- package/dist/mirador.min.js +335 -0
- package/dist/mirador.min.js.map +1 -0
- package/dist/react-error-boundary.esm-ByHqCaxk.js +67 -0
- package/dist/react-error-boundary.esm-ByHqCaxk.js.map +1 -0
- package/dist/visuallyHidden-C4mhQkB0.js +98 -0
- package/dist/visuallyHidden-C4mhQkB0.js.map +1 -0
- package/dist/window-COQOIAli.js +138 -0
- package/dist/window-COQOIAli.js.map +1 -0
- package/package.json +3 -2
- package/src/components/AnnotationsOverlay.jsx +21 -6
- package/src/lib/AnnotationItem.js +18 -0
- package/src/lib/AnnotationResource.js +14 -0
- package/src/lib/CanvasAnnotationDisplay.js +76 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Component as e, createContext as t, createElement as n } from "react";
|
|
2
|
+
//#region node_modules/react-error-boundary/dist/react-error-boundary.esm.js
|
|
3
|
+
var r = t(null), i = {
|
|
4
|
+
didCatch: !1,
|
|
5
|
+
error: null
|
|
6
|
+
}, a = class extends e {
|
|
7
|
+
constructor(e) {
|
|
8
|
+
super(e), this.resetErrorBoundary = this.resetErrorBoundary.bind(this), this.state = i;
|
|
9
|
+
}
|
|
10
|
+
static getDerivedStateFromError(e) {
|
|
11
|
+
return {
|
|
12
|
+
didCatch: !0,
|
|
13
|
+
error: e
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
resetErrorBoundary() {
|
|
17
|
+
let { error: e } = this.state;
|
|
18
|
+
if (e !== null) {
|
|
19
|
+
var t, n, r = [...arguments];
|
|
20
|
+
(t = (n = this.props).onReset) == null || t.call(n, {
|
|
21
|
+
args: r,
|
|
22
|
+
reason: "imperative-api"
|
|
23
|
+
}), this.setState(i);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
componentDidCatch(e, t) {
|
|
27
|
+
var n, r;
|
|
28
|
+
(n = (r = this.props).onError) == null || n.call(r, e, t);
|
|
29
|
+
}
|
|
30
|
+
componentDidUpdate(e, t) {
|
|
31
|
+
let { didCatch: n } = this.state, { resetKeys: r } = this.props;
|
|
32
|
+
if (n && t.error !== null && o(e.resetKeys, r)) {
|
|
33
|
+
var a, s;
|
|
34
|
+
(a = (s = this.props).onReset) == null || a.call(s, {
|
|
35
|
+
next: r,
|
|
36
|
+
prev: e.resetKeys,
|
|
37
|
+
reason: "keys"
|
|
38
|
+
}), this.setState(i);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
render() {
|
|
42
|
+
let { children: e, fallbackRender: t, FallbackComponent: i, fallback: a } = this.props, { didCatch: o, error: s } = this.state, c = e;
|
|
43
|
+
if (o) {
|
|
44
|
+
let e = {
|
|
45
|
+
error: s,
|
|
46
|
+
resetErrorBoundary: this.resetErrorBoundary
|
|
47
|
+
};
|
|
48
|
+
if (typeof t == "function") c = t(e);
|
|
49
|
+
else if (i) c = n(i, e);
|
|
50
|
+
else if (a !== void 0) c = a;
|
|
51
|
+
else throw s;
|
|
52
|
+
}
|
|
53
|
+
return n(r.Provider, { value: {
|
|
54
|
+
didCatch: o,
|
|
55
|
+
error: s,
|
|
56
|
+
resetErrorBoundary: this.resetErrorBoundary
|
|
57
|
+
} }, c);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function o() {
|
|
61
|
+
let e = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [], t = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [];
|
|
62
|
+
return e.length !== t.length || e.some((e, n) => !Object.is(e, t[n]));
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { a as t };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=react-error-boundary.esm-ByHqCaxk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-error-boundary.esm-ByHqCaxk.js","names":[],"sources":["../node_modules/react-error-boundary/dist/react-error-boundary.esm.js"],"sourcesContent":["'use client';\nimport { createContext, Component, createElement, useContext, useState, useMemo, forwardRef } from 'react';\n\nconst ErrorBoundaryContext = createContext(null);\n\nconst initialState = {\n didCatch: false,\n error: null\n};\nclass ErrorBoundary extends Component {\n constructor(props) {\n super(props);\n this.resetErrorBoundary = this.resetErrorBoundary.bind(this);\n this.state = initialState;\n }\n static getDerivedStateFromError(error) {\n return {\n didCatch: true,\n error\n };\n }\n resetErrorBoundary() {\n const {\n error\n } = this.state;\n if (error !== null) {\n var _this$props$onReset, _this$props;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n (_this$props$onReset = (_this$props = this.props).onReset) === null || _this$props$onReset === void 0 ? void 0 : _this$props$onReset.call(_this$props, {\n args,\n reason: \"imperative-api\"\n });\n this.setState(initialState);\n }\n }\n componentDidCatch(error, info) {\n var _this$props$onError, _this$props2;\n (_this$props$onError = (_this$props2 = this.props).onError) === null || _this$props$onError === void 0 ? void 0 : _this$props$onError.call(_this$props2, error, info);\n }\n componentDidUpdate(prevProps, prevState) {\n const {\n didCatch\n } = this.state;\n const {\n resetKeys\n } = this.props;\n\n // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,\n // we'd end up resetting the error boundary immediately.\n // This would likely trigger a second error to be thrown.\n // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.\n\n if (didCatch && prevState.error !== null && hasArrayChanged(prevProps.resetKeys, resetKeys)) {\n var _this$props$onReset2, _this$props3;\n (_this$props$onReset2 = (_this$props3 = this.props).onReset) === null || _this$props$onReset2 === void 0 ? void 0 : _this$props$onReset2.call(_this$props3, {\n next: resetKeys,\n prev: prevProps.resetKeys,\n reason: \"keys\"\n });\n this.setState(initialState);\n }\n }\n render() {\n const {\n children,\n fallbackRender,\n FallbackComponent,\n fallback\n } = this.props;\n const {\n didCatch,\n error\n } = this.state;\n let childToRender = children;\n if (didCatch) {\n const props = {\n error,\n resetErrorBoundary: this.resetErrorBoundary\n };\n if (typeof fallbackRender === \"function\") {\n childToRender = fallbackRender(props);\n } else if (FallbackComponent) {\n childToRender = createElement(FallbackComponent, props);\n } else if (fallback !== undefined) {\n childToRender = fallback;\n } else {\n throw error;\n }\n }\n return createElement(ErrorBoundaryContext.Provider, {\n value: {\n didCatch,\n error,\n resetErrorBoundary: this.resetErrorBoundary\n }\n }, childToRender);\n }\n}\nfunction hasArrayChanged() {\n let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n let b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));\n}\n\nfunction assertErrorBoundaryContext(value) {\n if (value == null || typeof value.didCatch !== \"boolean\" || typeof value.resetErrorBoundary !== \"function\") {\n throw new Error(\"ErrorBoundaryContext not found\");\n }\n}\n\nfunction useErrorBoundary() {\n const context = useContext(ErrorBoundaryContext);\n assertErrorBoundaryContext(context);\n const [state, setState] = useState({\n error: null,\n hasError: false\n });\n const memoized = useMemo(() => ({\n resetBoundary: () => {\n context.resetErrorBoundary();\n setState({\n error: null,\n hasError: false\n });\n },\n showBoundary: error => setState({\n error,\n hasError: true\n })\n }), [context.resetErrorBoundary]);\n if (state.hasError) {\n throw state.error;\n }\n return memoized;\n}\n\nfunction withErrorBoundary(component, errorBoundaryProps) {\n const Wrapped = forwardRef((props, ref) => createElement(ErrorBoundary, errorBoundaryProps, createElement(component, {\n ...props,\n ref\n })));\n\n // Format for display in DevTools\n const name = component.displayName || component.name || \"Unknown\";\n Wrapped.displayName = \"withErrorBoundary(\".concat(name, \")\");\n return Wrapped;\n}\n\nexport { ErrorBoundary, ErrorBoundaryContext, useErrorBoundary, withErrorBoundary };\n"],"x_google_ignoreList":[0],"mappings":";;AAGA,IAAM,IAAuB,EAAc,IAAI,GAEzC,IAAe;CACnB,UAAU;CACV,OAAO;AACT,GACM,IAAN,cAA4B,EAAU;CACpC,YAAY,GAAO;EAGjB,AAFA,MAAM,CAAK,GACX,KAAK,qBAAqB,KAAK,mBAAmB,KAAK,IAAI,GAC3D,KAAK,QAAQ;CACf;CACA,OAAO,yBAAyB,GAAO;EACrC,OAAO;GACL,UAAU;GACV;EACF;CACF;CACA,qBAAqB;EACnB,IAAM,EACJ,aACE,KAAK;EACT,IAAI,MAAU,MAAM;GAClB,IAAI,GAAqB,GACS,QACnB;GAMf,CAJC,KAAuB,IAAc,KAAK,MAAA,CAAO,YAAa,QAAkD,EAAoB,KAAK,GAAa;IACrJ;IACA,QAAQ;GACV,CAAC,GACD,KAAK,SAAS,CAAY;EAC5B;CACF;CACA,kBAAkB,GAAO,GAAM;EAC7B,IAAI,GAAqB;EACzB,CAAC,KAAuB,IAAe,KAAK,MAAA,CAAO,YAAa,QAAkD,EAAoB,KAAK,GAAc,GAAO,CAAI;CACtK;CACA,mBAAmB,GAAW,GAAW;EACvC,IAAM,EACJ,gBACE,KAAK,OACH,EACJ,iBACE,KAAK;EAOT,IAAI,KAAY,EAAU,UAAU,QAAQ,EAAgB,EAAU,WAAW,CAAS,GAAG;GAC3F,IAAI,GAAsB;GAM1B,CALC,KAAwB,IAAe,KAAK,MAAA,CAAO,YAAa,QAAmD,EAAqB,KAAK,GAAc;IAC1J,MAAM;IACN,MAAM,EAAU;IAChB,QAAQ;GACV,CAAC,GACD,KAAK,SAAS,CAAY;EAC5B;CACF;CACA,SAAS;EACP,IAAM,EACJ,aACA,mBACA,sBACA,gBACE,KAAK,OACH,EACJ,aACA,aACE,KAAK,OACL,IAAgB;EACpB,IAAI,GAAU;GACZ,IAAM,IAAQ;IACZ;IACA,oBAAoB,KAAK;GAC3B;GACA,IAAI,OAAO,KAAmB,YAC5B,IAAgB,EAAe,CAAK;QAC/B,IAAI,GACT,IAAgB,EAAc,GAAmB,CAAK;QACjD,IAAI,MAAa,KAAA,GACtB,IAAgB;QAEhB,MAAM;EAEV;EACA,OAAO,EAAc,EAAqB,UAAU,EAClD,OAAO;GACL;GACA;GACA,oBAAoB,KAAK;EAC3B,EACF,GAAG,CAAa;CAClB;AACF;AACA,SAAS,IAAkB;CACzB,IAAI,IAAI,UAAU,SAAS,KAAK,UAAU,OAAO,KAAA,IAAY,UAAU,KAAK,CAAC,GACzE,IAAI,UAAU,SAAS,KAAK,UAAU,OAAO,KAAA,IAAY,UAAU,KAAK,CAAC;CAC7E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAM,MAAU,CAAC,OAAO,GAAG,GAAM,EAAE,EAAM,CAAC;AACpF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { U as e, at as t, ft as n, g as r, lt as i, ut as a } from "./getters-B4oepJRC.js";
|
|
2
|
+
import { createContext as o, useContext as s } from "react";
|
|
3
|
+
import { jsx as c } from "react/jsx-runtime";
|
|
4
|
+
import { styled as l } from "@mui/material/styles";
|
|
5
|
+
import u from "@mui/material/Badge";
|
|
6
|
+
import d from "@mui/material/IconButton";
|
|
7
|
+
import f from "@mui/material/Tooltip";
|
|
8
|
+
//#region src/contexts/WorkspaceContext.js
|
|
9
|
+
var p = /* @__PURE__ */ n(t(), 1), m = o({ current: document.body }), h = l(d, {
|
|
10
|
+
name: "MiradorMenuButton",
|
|
11
|
+
slot: "root"
|
|
12
|
+
})(({ selected: e, theme: t }) => ({
|
|
13
|
+
fill: "currentcolor",
|
|
14
|
+
...e && { backgroundColor: t.palette.action.selected }
|
|
15
|
+
}));
|
|
16
|
+
function g({ "aria-label": e, badge: t = !1, children: n, dispatch: r = () => {}, selected: i = !1, BadgeProps: a = {}, TooltipProps: o = {}, sx: l = {}, ...d }) {
|
|
17
|
+
let p = s(m), g = /* @__PURE__ */ c(h, {
|
|
18
|
+
selected: i,
|
|
19
|
+
"aria-label": e,
|
|
20
|
+
...d,
|
|
21
|
+
sx: l,
|
|
22
|
+
size: "large",
|
|
23
|
+
children: t ? /* @__PURE__ */ c(u, {
|
|
24
|
+
overlap: "rectangular",
|
|
25
|
+
...a,
|
|
26
|
+
children: n
|
|
27
|
+
}) : n
|
|
28
|
+
});
|
|
29
|
+
return d.disabled ? g : /* @__PURE__ */ c(f, {
|
|
30
|
+
title: e,
|
|
31
|
+
...o,
|
|
32
|
+
slotProps: { popper: { container: p?.current } },
|
|
33
|
+
children: g
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
g.propTypes = {
|
|
37
|
+
"aria-label": p.default.string.isRequired,
|
|
38
|
+
badge: p.default.bool,
|
|
39
|
+
BadgeProps: p.default.object,
|
|
40
|
+
children: p.default.element.isRequired,
|
|
41
|
+
dispatch: p.default.func,
|
|
42
|
+
selected: p.default.bool,
|
|
43
|
+
sx: p.default.object,
|
|
44
|
+
TooltipProps: p.default.object
|
|
45
|
+
};
|
|
46
|
+
var _ = e(r("MiradorMenuButton"))(g), v = /* @__PURE__ */ a(((e) => {
|
|
47
|
+
Object.defineProperty(e, "__esModule", { value: !0 }), e.useElementSize = void 0;
|
|
48
|
+
var t = i();
|
|
49
|
+
function n() {
|
|
50
|
+
var e = (0, t.useState)(null), n = e[0], r = e[1], i = (0, t.useState)({
|
|
51
|
+
width: 0,
|
|
52
|
+
height: 0
|
|
53
|
+
}), a = i[0], o = i[1], s = (0, t.useCallback)(function() {
|
|
54
|
+
n && o({
|
|
55
|
+
width: n.offsetWidth,
|
|
56
|
+
height: n.offsetHeight
|
|
57
|
+
});
|
|
58
|
+
}, [n]);
|
|
59
|
+
return (typeof window < "u" ? t.useLayoutEffect : t.useEffect)(function() {
|
|
60
|
+
if (n) {
|
|
61
|
+
s();
|
|
62
|
+
var e = new ResizeObserver(s);
|
|
63
|
+
return e.observe(n), function() {
|
|
64
|
+
return e.disconnect();
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}, [n, s]), [r, a];
|
|
68
|
+
}
|
|
69
|
+
e.useElementSize = n;
|
|
70
|
+
}));
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region node_modules/merge-refs/dist/index.js
|
|
73
|
+
function y() {
|
|
74
|
+
var e = [...arguments].filter(Boolean);
|
|
75
|
+
return e.length <= 1 ? e[0] || null : function(t) {
|
|
76
|
+
for (var n = 0, r = e; n < r.length; n++) {
|
|
77
|
+
var i = r[n];
|
|
78
|
+
typeof i == "function" ? i(t) : i && (i.current = t);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region node_modules/@mui/utils/esm/visuallyHidden/visuallyHidden.js
|
|
84
|
+
var b = {
|
|
85
|
+
border: 0,
|
|
86
|
+
clip: "rect(0 0 0 0)",
|
|
87
|
+
height: "1px",
|
|
88
|
+
margin: "-1px",
|
|
89
|
+
overflow: "hidden",
|
|
90
|
+
padding: 0,
|
|
91
|
+
position: "absolute",
|
|
92
|
+
whiteSpace: "nowrap",
|
|
93
|
+
width: "1px"
|
|
94
|
+
};
|
|
95
|
+
//#endregion
|
|
96
|
+
export { g as a, _ as i, y as n, m as o, v as r, b as t };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=visuallyHidden-C4mhQkB0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visuallyHidden-C4mhQkB0.js","names":[],"sources":["../src/contexts/WorkspaceContext.js","../src/components/MiradorMenuButton.jsx","../src/containers/MiradorMenuButton.js","../node_modules/@custom-react-hooks/use-element-size/dist/index.js","../node_modules/merge-refs/dist/index.js","../node_modules/@mui/utils/esm/visuallyHidden/visuallyHidden.js"],"sourcesContent":["import { createContext } from 'react';\n\nconst WorkspaceContext = createContext({ current: document.body });\n\nexport default WorkspaceContext;\n","import { useContext } from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport Badge from '@mui/material/Badge';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport WorkspaceContext from '../contexts/WorkspaceContext';\n\nconst Root = styled(IconButton, { name: 'MiradorMenuButton', slot: 'root' })(({ selected, theme }) => ({\n fill: 'currentcolor',\n ...(selected && {\n backgroundColor: theme.palette.action.selected,\n }),\n}));\n\n/**\n * MiradorMenuButton ~ Wrap the given icon prop in an IconButton and a Tooltip.\n * This shares the passed in aria-label w/ the Tooltip (as title) and the IconButton\n * All props besides icon are spread to the IconButton component\n */\nexport function MiradorMenuButton({\n 'aria-label': ariaLabel,\n badge = false,\n children,\n dispatch = () => {},\n selected = false,\n BadgeProps = {},\n TooltipProps = {},\n sx = {},\n ...iconButtonProps\n}) {\n const container = useContext(WorkspaceContext);\n const button = (\n <Root selected={selected} aria-label={ariaLabel} {...iconButtonProps} sx={sx} size=\"large\">\n {badge ? (\n <Badge overlap=\"rectangular\" {...BadgeProps}>\n {children}\n </Badge>\n ) : (\n children\n )}\n </Root>\n );\n\n if (iconButtonProps.disabled) return button;\n\n return (\n <Tooltip\n title={ariaLabel}\n {...TooltipProps}\n slotProps={{\n popper: {\n container: container?.current,\n },\n }}\n >\n {button}\n </Tooltip>\n );\n}\n\nMiradorMenuButton.propTypes = {\n 'aria-label': PropTypes.string.isRequired,\n badge: PropTypes.bool,\n BadgeProps: PropTypes.object,\n children: PropTypes.element.isRequired,\n dispatch: PropTypes.func,\n selected: PropTypes.bool,\n sx: PropTypes.object,\n TooltipProps: PropTypes.object,\n};\n","import { compose } from 'redux';\nimport { withPlugins } from '../extend/withPlugins';\nimport { MiradorMenuButton } from '../components/MiradorMenuButton';\n\nconst enhance = compose(withPlugins('MiradorMenuButton'));\n\nexport default enhance(MiradorMenuButton);\n","\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.useElementSize = void 0;\r\nvar react_1 = require(\"react\");\r\nfunction useElementSize() {\r\n var _a = (0, react_1.useState)(null), ref = _a[0], setRef = _a[1];\r\n var _b = (0, react_1.useState)({ width: 0, height: 0 }), size = _b[0], setSize = _b[1];\r\n var handleSize = (0, react_1.useCallback)(function () {\r\n if (ref) {\r\n setSize({\r\n width: ref.offsetWidth,\r\n height: ref.offsetHeight,\r\n });\r\n }\r\n }, [ref]);\r\n var useEnviromentEffect = typeof window !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect;\r\n useEnviromentEffect(function () {\r\n if (!ref)\r\n return;\r\n handleSize();\r\n var resizeObserver = new ResizeObserver(handleSize);\r\n resizeObserver.observe(ref);\r\n return function () { return resizeObserver.disconnect(); };\r\n }, [ref, handleSize]);\r\n return [setRef, size];\r\n}\r\nexports.useElementSize = useElementSize;\r\n","/**\n * A function that merges React refs into one.\n * Supports both functions and ref objects created using createRef() and useRef().\n *\n * Usage:\n * ```tsx\n * <div ref={mergeRefs(ref1, ref2, ref3)} />\n * ```\n *\n * @param {(React.Ref<T> | undefined)[]} inputRefs Array of refs\n * @returns {React.Ref<T> | React.RefCallback<T>} Merged refs\n */\nexport default function mergeRefs() {\n var inputRefs = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n inputRefs[_i] = arguments[_i];\n }\n var filteredInputRefs = inputRefs.filter(Boolean);\n if (filteredInputRefs.length <= 1) {\n var firstRef = filteredInputRefs[0];\n return firstRef || null;\n }\n return function mergedRefs(ref) {\n for (var _i = 0, filteredInputRefs_1 = filteredInputRefs; _i < filteredInputRefs_1.length; _i++) {\n var inputRef = filteredInputRefs_1[_i];\n if (typeof inputRef === 'function') {\n inputRef(ref);\n }\n else if (inputRef) {\n inputRef.current = ref;\n }\n }\n };\n}\n","const visuallyHidden = {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1px'\n};\nexport default visuallyHidden;"],"x_google_ignoreList":[3,4,5],"mappings":";;;;;;;;mCAEM,IAAmB,EAAc,EAAE,SAAS,SAAS,KAAK,CAAC,GCM3D,IAAO,EAAO,GAAY;CAAE,MAAM;CAAqB,MAAM;AAAO,CAAC,CAAC,EAAE,EAAE,aAAU,gBAAa;CACrG,MAAM;CACN,GAAI,KAAY,EACd,iBAAiB,EAAM,QAAQ,OAAO,SACxC;AACF,EAAE;AAOF,SAAgB,EAAkB,EAChC,cAAc,GACd,WAAQ,IACR,aACA,oBAAiB,CAAC,GAClB,cAAW,IACX,gBAAa,CAAC,GACd,kBAAe,CAAC,GAChB,QAAK,CAAC,GACN,GAAG,KACF;CACD,IAAM,IAAY,EAAW,CAAgB,GACvC,IACJ,kBAAC,GAAD;EAAgB;EAAU,cAAY;EAAW,GAAI;EAAqB;EAAI,MAAK;EAChF,UAAA,IACC,kBAAC,GAAD;GAAO,SAAQ;GAAc,GAAI;GAC9B;EACI,CAAA,IAEP;CAEE,CAAA;CAKR,OAFI,EAAgB,WAAiB,IAGnC,kBAAC,GAAD;EACE,OAAO;EACP,GAAI;EACJ,WAAW,EACT,QAAQ,EACN,WAAW,GAAW,QACxB,EACF;EAEC,UAAA;CACM,CAAA;AAEb;AAEA,EAAkB,YAAY;CAC5B,cAAc,EAAA,QAAU,OAAO;CAC/B,OAAO,EAAA,QAAU;CACjB,YAAY,EAAA,QAAU;CACtB,UAAU,EAAA,QAAU,QAAQ;CAC5B,UAAU,EAAA,QAAU;CACpB,UAAU,EAAA,QAAU;CACpB,IAAI,EAAA,QAAU;CACd,cAAc,EAAA,QAAU;AAC1B;AChEA,IAAA,IAFgB,EAAQ,EAAY,mBAAmB,CAExC,CAAA,CAAQ,CAAiB;CCJxC,AADA,OAAO,eAAe,GAAS,cAAc,EAAE,OAAO,GAAK,CAAC,GAC5D,EAAQ,iBAAiB,KAAK;CAC9B,IAAI,IAAA,EAAA;CACJ,SAAS,IAAiB;EACtB,IAAI,KAAM,GAAG,EAAQ,SAAA,CAAU,IAAI,GAAG,IAAM,EAAG,IAAI,IAAS,EAAG,IAC3D,KAAM,GAAG,EAAQ,SAAA,CAAU;GAAE,OAAO;GAAG,QAAQ;EAAE,CAAC,GAAG,IAAO,EAAG,IAAI,IAAU,EAAG,IAChF,KAAc,GAAG,EAAQ,YAAA,CAAa,WAAY;GAClD,AAAI,KACA,EAAQ;IACJ,OAAO,EAAI;IACX,QAAQ,EAAI;GAChB,CAAC;EAET,GAAG,CAAC,CAAG,CAAC;EAUR,QAT0B,OAAO,SAAW,MAAc,EAAQ,kBAAkB,EAAQ,UAAA,CACxE,WAAY;GACvB,OAEL;MAAW;IACX,IAAI,IAAiB,IAAI,eAAe,CAAU;IAElD,OADA,EAAe,QAAQ,CAAG,GACnB,WAAY;KAAE,OAAO,EAAe,WAAW;IAAG;GAH9C;EAIf,GAAG,CAAC,GAAK,CAAU,CAAC,GACb,CAAC,GAAQ,CAAI;CACxB;CACA,EAAQ,iBAAiB;;;;ACdzB,SAAwB,IAAY;CAE3B,IAGD,IAAoB,IAFJ,SAEI,CAAA,CAAU,OAAO,OAAO;CAKhD,OAJI,EAAkB,UAAU,IACb,EAAkB,MACd,OAEhB,SAAoB,GAAK;EAC5B,KAAK,IAAI,IAAK,GAAG,IAAsB,GAAmB,IAAK,EAAoB,QAAQ,KAAM;GAC7F,IAAI,IAAW,EAAoB;GACnC,AAAI,OAAO,KAAa,aACpB,EAAS,CAAG,IAEP,MACL,EAAS,UAAU;EAE3B;CACJ;AACJ;;;ACjCA,IAAM,IAAiB;CACrB,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACT,UAAU;CACV,YAAY;CACZ,OAAO;AACT"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { f as e, h as t } from "./getters-B4oepJRC.js";
|
|
2
|
+
import { t as n } from "./action-types-DjIbTE-A.js";
|
|
3
|
+
//#region src/state/actions/window.js
|
|
4
|
+
function r(e, t = !1) {
|
|
5
|
+
return {
|
|
6
|
+
pan: t,
|
|
7
|
+
type: n.FOCUS_WINDOW,
|
|
8
|
+
windowId: e
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function i({ companionWindows: r, manifest: i, ...a }) {
|
|
12
|
+
return (o, s) => {
|
|
13
|
+
let { config: c, workspace: { windowIds: l = [] } } = e(s()), u = l.length, d = a.id || `window-${t()}`, f = `cw-${t()}`, p = [{
|
|
14
|
+
content: "thumbnailNavigation",
|
|
15
|
+
default: !0,
|
|
16
|
+
id: f,
|
|
17
|
+
position: a.thumbnailNavigationPosition || c.thumbnailNavigation.defaultPosition,
|
|
18
|
+
windowId: d
|
|
19
|
+
}, ...(r || []).map((e, n) => ({
|
|
20
|
+
...e,
|
|
21
|
+
id: `cw-${t()}`
|
|
22
|
+
}))];
|
|
23
|
+
(a.sideBarPanel || c.window.defaultSideBarPanel || c.window.sideBarPanel) && p.unshift({
|
|
24
|
+
content: a.sideBarPanel || a.defaultSearchQuery && "search" || c.window.defaultSideBarPanel || c.window.sideBarPanel,
|
|
25
|
+
default: !0,
|
|
26
|
+
id: `cw-${t()}`,
|
|
27
|
+
position: "left",
|
|
28
|
+
windowId: d
|
|
29
|
+
});
|
|
30
|
+
let m = {
|
|
31
|
+
canvasId: void 0,
|
|
32
|
+
collectionIndex: 0,
|
|
33
|
+
companionAreaOpen: !0,
|
|
34
|
+
companionWindowIds: p.map((e) => e.id),
|
|
35
|
+
draggingEnabled: !0,
|
|
36
|
+
highlightAllAnnotations: c.window.highlightAllAnnotations || !1,
|
|
37
|
+
id: d,
|
|
38
|
+
manifestId: null,
|
|
39
|
+
maximized: !1,
|
|
40
|
+
rangeId: null,
|
|
41
|
+
rotation: null,
|
|
42
|
+
selectedAnnotations: {},
|
|
43
|
+
sideBarOpen: c.window.sideBarOpenByDefault === void 0 ? c.window.sideBarOpen || !!a.defaultSearchQuery : c.window.sideBarOpenByDefault || !!a.defaultSearchQuery,
|
|
44
|
+
sideBarPanel: a.sideBarPanel || c.window.defaultSideBarPanel || c.window.sideBarPanel,
|
|
45
|
+
thumbnailNavigationId: f
|
|
46
|
+
};
|
|
47
|
+
o({
|
|
48
|
+
companionWindows: p,
|
|
49
|
+
elasticLayout: {
|
|
50
|
+
...c.window.elastic || {
|
|
51
|
+
height: 400,
|
|
52
|
+
width: 480
|
|
53
|
+
},
|
|
54
|
+
x: 200 + (Math.floor(u / 10) * 50 + u * 30 % 300),
|
|
55
|
+
y: 200 + u * 50 % 300
|
|
56
|
+
},
|
|
57
|
+
manifest: i,
|
|
58
|
+
type: n.ADD_WINDOW,
|
|
59
|
+
window: {
|
|
60
|
+
...m,
|
|
61
|
+
...a
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function a(e, t) {
|
|
67
|
+
return {
|
|
68
|
+
id: e,
|
|
69
|
+
payload: t,
|
|
70
|
+
type: n.UPDATE_WINDOW
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function o(e) {
|
|
74
|
+
return {
|
|
75
|
+
type: n.MAXIMIZE_WINDOW,
|
|
76
|
+
windowId: e
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function s(e) {
|
|
80
|
+
return {
|
|
81
|
+
type: n.MINIMIZE_WINDOW,
|
|
82
|
+
windowId: e
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function c(e, t) {
|
|
86
|
+
return {
|
|
87
|
+
id: e,
|
|
88
|
+
payload: { companionAreaOpen: t },
|
|
89
|
+
type: n.UPDATE_WINDOW
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function l(e) {
|
|
93
|
+
return {
|
|
94
|
+
type: n.REMOVE_WINDOW,
|
|
95
|
+
windowId: e
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function u(e) {
|
|
99
|
+
return {
|
|
100
|
+
type: n.TOGGLE_WINDOW_SIDE_BAR,
|
|
101
|
+
windowId: e
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function d(e, t) {
|
|
105
|
+
return (r, i) => {
|
|
106
|
+
let { windows: a } = i(), { thumbnailNavigationId: o } = a[e];
|
|
107
|
+
r({
|
|
108
|
+
id: o,
|
|
109
|
+
payload: { position: t },
|
|
110
|
+
type: n.UPDATE_COMPANION_WINDOW
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function f(e, t) {
|
|
115
|
+
return {
|
|
116
|
+
type: n.SET_WINDOW_VIEW_TYPE,
|
|
117
|
+
viewType: t,
|
|
118
|
+
windowId: e
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function p(e, t = [], r) {
|
|
122
|
+
return {
|
|
123
|
+
dialogCollectionPath: t,
|
|
124
|
+
manifestId: e,
|
|
125
|
+
type: n.SHOW_COLLECTION_DIALOG,
|
|
126
|
+
windowId: r
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function m(e) {
|
|
130
|
+
return {
|
|
131
|
+
type: n.HIDE_COLLECTION_DIALOG,
|
|
132
|
+
windowId: e
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { s as a, d as c, u as d, a as f, o as i, f as l, r as n, l as o, m as r, c as s, i as t, p as u };
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=window-COQOIAli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-COQOIAli.js","names":[],"sources":["../src/state/actions/window.js"],"sourcesContent":["import { v4 as uuid } from 'uuid';\nimport ActionTypes from './action-types';\nimport { miradorSlice } from '../selectors/utils';\n\n/**\n * focusWindow - action creator\n *\n * @param {String} windowId\n * @memberof ActionCreators\n */\nexport function focusWindow(windowId, pan = false) {\n return {\n pan,\n type: ActionTypes.FOCUS_WINDOW,\n windowId,\n };\n}\n\n/**\n * addWindow - action creator\n *\n * @param {Object} options\n * @memberof ActionCreators\n */\nexport function addWindow({ companionWindows, manifest, ...options }) {\n return (dispatch, getState) => {\n const {\n config,\n workspace: { windowIds = [] },\n } = miradorSlice(getState());\n const numWindows = windowIds.length;\n\n const windowId = options.id || `window-${uuid()}`;\n const cwThumbs = `cw-${uuid()}`;\n\n const defaultCompanionWindows = [\n {\n content: 'thumbnailNavigation',\n default: true,\n id: cwThumbs,\n position: options.thumbnailNavigationPosition || config.thumbnailNavigation.defaultPosition,\n windowId,\n },\n ...(companionWindows || []).map((cw, i) => ({ ...cw, id: `cw-${uuid()}` })),\n ];\n\n if (options.sideBarPanel || config.window.defaultSideBarPanel || config.window.sideBarPanel) {\n defaultCompanionWindows.unshift({\n content:\n options.sideBarPanel ||\n (options.defaultSearchQuery && 'search') ||\n config.window.defaultSideBarPanel ||\n config.window.sideBarPanel,\n\n default: true,\n id: `cw-${uuid()}`,\n position: 'left',\n windowId,\n });\n }\n\n const defaultOptions = {\n canvasId: undefined,\n collectionIndex: 0,\n companionAreaOpen: true,\n companionWindowIds: defaultCompanionWindows.map((cw) => cw.id),\n draggingEnabled: true,\n highlightAllAnnotations: config.window.highlightAllAnnotations || false,\n id: windowId,\n manifestId: null,\n maximized: false,\n rangeId: null,\n rotation: null,\n selectedAnnotations: {},\n sideBarOpen:\n config.window.sideBarOpenByDefault !== undefined\n ? config.window.sideBarOpenByDefault || !!options.defaultSearchQuery\n : config.window.sideBarOpen || !!options.defaultSearchQuery,\n sideBarPanel: options.sideBarPanel || config.window.defaultSideBarPanel || config.window.sideBarPanel,\n thumbnailNavigationId: cwThumbs,\n };\n\n const elasticLayout = {\n ...(config.window.elastic || { height: 400, width: 480 }),\n x: 200 + (Math.floor(numWindows / 10) * 50 + ((numWindows * 30) % 300)),\n y: 200 + ((numWindows * 50) % 300),\n };\n\n dispatch({\n companionWindows: defaultCompanionWindows,\n elasticLayout,\n manifest,\n type: ActionTypes.ADD_WINDOW,\n window: { ...defaultOptions, ...options },\n });\n };\n}\n\n/** */\nexport function updateWindow(id, payload) {\n return {\n id,\n payload,\n type: ActionTypes.UPDATE_WINDOW,\n };\n}\n\n/**\n * maximizeWindow\n * @param {String} windowId\n * @memberof ActionCreators\n */\nexport function maximizeWindow(windowId) {\n return { type: ActionTypes.MAXIMIZE_WINDOW, windowId };\n}\n\n/**\n * minimizeWindow\n * @param {String} windowId\n * @memberof ActionCreators\n */\nexport function minimizeWindow(windowId) {\n return { type: ActionTypes.MINIMIZE_WINDOW, windowId };\n}\n\n/** */\nexport function setCompanionAreaOpen(id, companionAreaOpen) {\n return {\n id,\n payload: { companionAreaOpen },\n type: ActionTypes.UPDATE_WINDOW,\n };\n}\n\n/**\n * removeWindow - action creator\n *\n * @param {String} windowId\n * @memberof ActionCreators\n */\nexport function removeWindow(windowId) {\n return {\n type: ActionTypes.REMOVE_WINDOW,\n windowId,\n };\n}\n\n/**\n * toggleWindowSideBar - action creator\n *\n * @param {String} windowId\n * @memberof ActionCreators\n */\nexport function toggleWindowSideBar(windowId) {\n return { type: ActionTypes.TOGGLE_WINDOW_SIDE_BAR, windowId };\n}\n\n/**\n * setWindowThumbnailPosition - action creator\n *\n * @param {String} windowId\n * @param {String} position\n * @memberof ActionCreators\n */\nexport function setWindowThumbnailPosition(windowId, position) {\n return (dispatch, getState) => {\n const { windows } = getState();\n const { thumbnailNavigationId } = windows[windowId];\n\n dispatch({\n id: thumbnailNavigationId,\n payload: { position },\n type: ActionTypes.UPDATE_COMPANION_WINDOW,\n });\n };\n}\n\n/**\n * setWindowViewType - action creator\n *\n * @param {String} windowId\n * @param {String} viewType\n * @memberof ActionCreators\n */\nexport function setWindowViewType(windowId, viewType) {\n return {\n type: ActionTypes.SET_WINDOW_VIEW_TYPE,\n viewType,\n windowId,\n };\n}\n\n/** */\nexport function showCollectionDialog(manifestId, dialogCollectionPath = [], windowId) {\n return {\n dialogCollectionPath,\n manifestId,\n type: ActionTypes.SHOW_COLLECTION_DIALOG,\n windowId,\n };\n}\n\n/** */\nexport function hideCollectionDialog(windowId) {\n return {\n type: ActionTypes.HIDE_COLLECTION_DIALOG,\n windowId,\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbf-mirador",
|
|
3
|
-
"version": "4.3.0-
|
|
3
|
+
"version": "4.3.0-testing3",
|
|
4
4
|
"description": "An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/mirador.min.js",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"lint:translations": "node ./scripts/i18n-lint.js",
|
|
30
30
|
"size": "size-limit",
|
|
31
31
|
"start": "vite",
|
|
32
|
-
"test": "npm run build && npm run lint && npm run size && vitest run"
|
|
32
|
+
"test": "npm run build && npm run lint && npm run size && vitest run",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
33
34
|
},
|
|
34
35
|
"license": "Apache-2.0",
|
|
35
36
|
"contributors": [
|
|
@@ -6,11 +6,11 @@ import sortBy from 'lodash/sortBy';
|
|
|
6
6
|
import xor from 'lodash/xor';
|
|
7
7
|
import OpenSeadragonCanvasOverlay from '../lib/OpenSeadragonCanvasOverlay';
|
|
8
8
|
import CanvasWorld from '../lib/CanvasWorld';
|
|
9
|
-
import CanvasAnnotationDisplay from '../lib/CanvasAnnotationDisplay';
|
|
9
|
+
import CanvasAnnotationDisplay, { POI_ICON_HEIGHT_PX } from '../lib/CanvasAnnotationDisplay';
|
|
10
10
|
import { buildPath2D } from '../lib/svgShapesToPath';
|
|
11
11
|
|
|
12
12
|
/** @private */
|
|
13
|
-
function isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, point) {
|
|
13
|
+
function isAnnotationAtPoint({ canvasWorld, osdCanvasOverlay, viewer }, resource, canvas, point) {
|
|
14
14
|
const [canvasX, canvasY] = canvasWorld.canvasToWorldCoordinates(canvas.id);
|
|
15
15
|
const relativeX = point.x - canvasX;
|
|
16
16
|
const relativeY = point.y - canvasY;
|
|
@@ -21,6 +21,21 @@ function isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, po
|
|
|
21
21
|
return [...svgPaths].some((path) => context.isPointInPath(buildPath2D(path), relativeX, relativeY));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
if (resource.pointSelector) {
|
|
25
|
+
const { x, y } = resource.pointSelector;
|
|
26
|
+
const osdCanvasIndex = canvasWorld.canvases.findIndex((c) => c.id === canvas.id);
|
|
27
|
+
const viewportCanvas = viewer.world.getItemAt(osdCanvasIndex);
|
|
28
|
+
if (!viewportCanvas) return false;
|
|
29
|
+
// The icon renders at a constant on-screen size regardless of zoom (see
|
|
30
|
+
// CanvasAnnotationDisplay#pointContext), so its clickable footprint must counter-scale the
|
|
31
|
+
// same way, or the hit region would shrink/grow with the image instead of the icon.
|
|
32
|
+
const zoomRatio = viewportCanvas.viewportToImageZoom(viewer.viewport.getZoom(true));
|
|
33
|
+
const hitRadius = POI_ICON_HEIGHT_PX / 2 / zoomRatio;
|
|
34
|
+
const dx = relativeX - x;
|
|
35
|
+
const dy = relativeY - y;
|
|
36
|
+
return dx * dx + dy * dy <= hitRadius * hitRadius;
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
if (resource.fragmentSelector) {
|
|
25
40
|
const [x, y, w, h] = resource.fragmentSelector;
|
|
26
41
|
return x <= relativeX && relativeX <= x + w && y <= relativeY && relativeY <= y + h;
|
|
@@ -137,12 +152,12 @@ export function AnnotationsOverlay({
|
|
|
137
152
|
.filter((resource) => {
|
|
138
153
|
if (canvas.id !== resource.targetId) return false;
|
|
139
154
|
|
|
140
|
-
return isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, resource, canvas, point);
|
|
155
|
+
return isAnnotationAtPoint({ canvasWorld, osdCanvasOverlay, viewer }, resource, canvas, point);
|
|
141
156
|
});
|
|
142
157
|
|
|
143
158
|
return annos;
|
|
144
159
|
},
|
|
145
|
-
[annotations, canvasWorld, osdCanvasOverlay, searchAnnotations],
|
|
160
|
+
[annotations, canvasWorld, osdCanvasOverlay, searchAnnotations, viewer],
|
|
146
161
|
);
|
|
147
162
|
|
|
148
163
|
const onCanvasClick = useCallback(
|
|
@@ -188,7 +203,7 @@ export function AnnotationsOverlay({
|
|
|
188
203
|
const x = Math.cos(degrees * degreesToRadians) * radius + point.x;
|
|
189
204
|
const y = Math.sin(degrees * degreesToRadians) * radius + point.y;
|
|
190
205
|
|
|
191
|
-
if (isAnnotationAtPoint(canvasWorld, osdCanvasOverlay, anno, canvas, { x, y })) score += 1;
|
|
206
|
+
if (isAnnotationAtPoint({ canvasWorld, osdCanvasOverlay, viewer }, anno, canvas, { x, y })) score += 1;
|
|
192
207
|
}
|
|
193
208
|
|
|
194
209
|
return { anno, score };
|
|
@@ -206,7 +221,7 @@ export function AnnotationsOverlay({
|
|
|
206
221
|
toggleAnnotation(annosWithScore[0].anno.id);
|
|
207
222
|
}
|
|
208
223
|
},
|
|
209
|
-
[annotationsAtPoint, canvasWorld, osdCanvasOverlay, toggleAnnotation],
|
|
224
|
+
[annotationsAtPoint, canvasWorld, osdCanvasOverlay, toggleAnnotation, viewer],
|
|
210
225
|
);
|
|
211
226
|
|
|
212
227
|
const onCanvasMouseMove = useDebouncedCallback(
|
|
@@ -120,4 +120,22 @@ export default class AnnotationItem {
|
|
|
120
120
|
|
|
121
121
|
return match && match[1].split(',').map((str) => parseInt(str, 10));
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
/** */
|
|
125
|
+
get pointSelector() {
|
|
126
|
+
const { selector } = this;
|
|
127
|
+
switch (typeof selector) {
|
|
128
|
+
case 'string':
|
|
129
|
+
return null;
|
|
130
|
+
case 'object':
|
|
131
|
+
return selector.find((s) => s.type && s.type === 'PointSelector');
|
|
132
|
+
default:
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** the POI's position within its journey (see mirador-annotation-editor's `dbf:journey`), or null when the POI is not part of a journey */
|
|
138
|
+
get journeyOrder() {
|
|
139
|
+
return this.resource['dbf:journey']?.order ?? null;
|
|
140
|
+
}
|
|
123
141
|
}
|
|
@@ -119,4 +119,18 @@ export default class AnnotationResource {
|
|
|
119
119
|
|
|
120
120
|
return match && match[1].split(',').map((str) => parseInt(str, 10));
|
|
121
121
|
}
|
|
122
|
+
|
|
123
|
+
/** */
|
|
124
|
+
get pointSelector() {
|
|
125
|
+
const { selector } = this;
|
|
126
|
+
if (selector && typeof selector === 'object' && selector['@type'] === 'oa:PointSelector') {
|
|
127
|
+
return { x: selector.x, y: selector.y };
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** the POI's position within its journey (see mirador-annotation-editor's `dbf:journey`), or null when the POI is not part of a journey */
|
|
133
|
+
get journeyOrder() {
|
|
134
|
+
return this.resource['dbf:journey']?.order ?? null;
|
|
135
|
+
}
|
|
122
136
|
}
|
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { buildPath2D } from '../lib/svgShapesToPath';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* The POI marker icon's path data and viewBox, copied from src/assets/icons/poi-marker.svg -
|
|
9
|
+
* inlined as a Path2D (rather than loaded as an image via drawImage) so it renders as a crisp
|
|
10
|
+
* vector at any zoom with no async image-load step to coordinate with the render loop. Update
|
|
11
|
+
* this constant (and the asset file, for reference) together if the icon changes.
|
|
12
|
+
*/
|
|
13
|
+
const POI_ICON_PATH_D =
|
|
14
|
+
'M50.002 0C30.763 0 15 15.718 15 34.902c0 7.432 2.374 14.34 6.392 20.019L45.73 96.994c3.409 4.453 5.675 3.607 8.51-.235l26.843-45.683c.542-.981.967-2.026 1.338-3.092A34.446 34.446 0 0 0 85 34.902C85 15.718 69.24 0 50.002 0zm0 16.354c10.359 0 18.597 8.218 18.597 18.548c0 10.33-8.238 18.544-18.597 18.544c-10.36 0-18.601-8.215-18.601-18.544c0-10.33 8.241-18.548 18.6-18.548z';
|
|
15
|
+
const POI_ICON_VIEWBOX_SIZE = 100;
|
|
16
|
+
/** The icon's own point (its pin tip), in viewBox units - this is what gets placed exactly on the annotated coordinate, not the icon's bounding-box center. */
|
|
17
|
+
const POI_ICON_TIP = { x: 50, y: 97 };
|
|
18
|
+
/** Center/radius of the icon's circular head, in viewBox units - where a journey-order badge is drawn, overlapping the icon like a numbered pin. */
|
|
19
|
+
const POI_ICON_HEAD = { x: 50, y: 34.9, radius: 18.6 };
|
|
20
|
+
const POI_ICON_DEFAULT_FILL = '#1e88e5';
|
|
21
|
+
/** Constant on-screen height (CSS px) for the POI icon, regardless of zoom - counter-scaled the same way this class already counter-scales stroke width (see `lineWidth /= zoomRatio` in svgContext). */
|
|
22
|
+
export const POI_ICON_HEIGHT_PX = 32;
|
|
23
|
+
|
|
7
24
|
export default class CanvasAnnotationDisplay {
|
|
8
25
|
/** */
|
|
9
26
|
constructor({ resource, palette, zoomRatio, offset, selected, hovered }) {
|
|
@@ -20,11 +37,70 @@ export default class CanvasAnnotationDisplay {
|
|
|
20
37
|
this.context = context;
|
|
21
38
|
if (this.resource.svgSelector) {
|
|
22
39
|
this.svgContext();
|
|
40
|
+
} else if (this.resource.pointSelector) {
|
|
41
|
+
this.pointContext();
|
|
23
42
|
} else if (this.resource.fragmentSelector) {
|
|
24
43
|
this.fragmentContext();
|
|
25
44
|
}
|
|
26
45
|
}
|
|
27
46
|
|
|
47
|
+
/** */
|
|
48
|
+
currentPalette() {
|
|
49
|
+
if (this.hovered) return this.palette.hovered;
|
|
50
|
+
if (this.selected) return this.palette.selected;
|
|
51
|
+
return this.palette.default;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Draws a POI marker (IIIF PointSelector) as the SVG pin icon, at a constant on-screen size,
|
|
56
|
+
* with the icon's own tip placed exactly on the annotated point. When the annotation carries
|
|
57
|
+
* journey-order metadata (`dbf:journey.order`), also draws a numbered badge over the icon's
|
|
58
|
+
* head, so a POI's position within its journey is visible directly on the map.
|
|
59
|
+
*/
|
|
60
|
+
pointContext() {
|
|
61
|
+
const { x, y } = this.resource.pointSelector;
|
|
62
|
+
const currentPalette = this.currentPalette();
|
|
63
|
+
if (currentPalette.globalAlpha === 0) return;
|
|
64
|
+
|
|
65
|
+
const iconHeight = POI_ICON_HEIGHT_PX / this.zoomRatio;
|
|
66
|
+
const iconScale = iconHeight / POI_ICON_VIEWBOX_SIZE;
|
|
67
|
+
|
|
68
|
+
this.context.save();
|
|
69
|
+
this.context.translate(this.offset.x + x, this.offset.y + y);
|
|
70
|
+
this.context.scale(iconScale, iconScale);
|
|
71
|
+
this.context.translate(-POI_ICON_TIP.x, -POI_ICON_TIP.y);
|
|
72
|
+
|
|
73
|
+
this.context.globalAlpha = currentPalette.globalAlpha ?? 1;
|
|
74
|
+
this.context.fillStyle = currentPalette.fillStyle || POI_ICON_DEFAULT_FILL;
|
|
75
|
+
this.context.fill(new Path2D(POI_ICON_PATH_D));
|
|
76
|
+
|
|
77
|
+
const { journeyOrder } = this.resource;
|
|
78
|
+
if (journeyOrder != null) {
|
|
79
|
+
this.journeyOrderBadgeContext(journeyOrder);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.context.restore();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Draws a small numbered circle over the POI icon's head, in the icon's own (viewBox-unit,
|
|
87
|
+
* already-scaled/translated) coordinate space - called from within pointContext's transform,
|
|
88
|
+
* before it restores the context.
|
|
89
|
+
* @param {number} order
|
|
90
|
+
*/
|
|
91
|
+
journeyOrderBadgeContext(order) {
|
|
92
|
+
this.context.beginPath();
|
|
93
|
+
this.context.arc(POI_ICON_HEAD.x, POI_ICON_HEAD.y, POI_ICON_HEAD.radius, 0, Math.PI * 2);
|
|
94
|
+
this.context.fillStyle = '#ffffff';
|
|
95
|
+
this.context.fill();
|
|
96
|
+
|
|
97
|
+
this.context.fillStyle = this.currentPalette().fillStyle || POI_ICON_DEFAULT_FILL;
|
|
98
|
+
this.context.font = `bold ${POI_ICON_HEAD.radius}px sans-serif`;
|
|
99
|
+
this.context.textAlign = 'center';
|
|
100
|
+
this.context.textBaseline = 'middle';
|
|
101
|
+
this.context.fillText(String(order), POI_ICON_HEAD.x, POI_ICON_HEAD.y);
|
|
102
|
+
}
|
|
103
|
+
|
|
28
104
|
/** */
|
|
29
105
|
get svgString() {
|
|
30
106
|
return this.resource.svgSelector.value;
|