@knaw-huc/osd-iiif-viewer 0.3.0 → 0.4.0
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/index.d.ts +1 -0
- package/dist/index.js +31 -15
- package/dist/usePointerDown.d.ts +13 -0
- package/dist/useStableState.d.ts +4 -0
- package/dist/util/hasMoved.d.ts +6 -0
- package/dist/util/hasMoved.spec.d.ts +1 -0
- package/package.json +1 -1
- package/dist/useStableProp.d.ts +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Viewer } from './Viewer.tsx';
|
|
2
2
|
export { useImageInfo } from './useImageInfo.tsx';
|
|
3
3
|
export { Overlay } from './Overlay.tsx';
|
|
4
|
+
export { usePointerDown } from './usePointerDown.tsx';
|
|
4
5
|
export { ViewerProvider } from './ViewerProvider';
|
|
5
6
|
export { useViewer } from './useViewer';
|
|
6
7
|
export { useViewerControls } from './useViewerControls';
|
package/dist/index.js
CHANGED
|
@@ -170,7 +170,7 @@ function useManifest() {
|
|
|
170
170
|
function useLoadManifest() {
|
|
171
171
|
return useViewerStoreSelector((s) => s.loadManifest);
|
|
172
172
|
}
|
|
173
|
-
function
|
|
173
|
+
function useStableState(options) {
|
|
174
174
|
const [stable, setStable] = useState(options), [key, setKey] = useState(() => JSON.stringify(options)), json = JSON.stringify(options);
|
|
175
175
|
return json !== key && (setKey(json), setStable(options)), stable;
|
|
176
176
|
}
|
|
@@ -180,7 +180,7 @@ const defaultOptions = {
|
|
|
180
180
|
showNavigationControl: !0
|
|
181
181
|
};
|
|
182
182
|
function Viewer(props) {
|
|
183
|
-
const containerRef = useRef(null), store = useViewerStore(), { vault } = useManifest(), { current } = useCanvas(), tileSource = current ? findTileSource(vault, current) : null, size = useContainerSize(containerRef), isContainerReady = size.width
|
|
183
|
+
const containerRef = useRef(null), store = useViewerStore(), { vault } = useManifest(), { current } = useCanvas(), tileSource = current ? findTileSource(vault, current) : null, size = useContainerSize(containerRef), isContainerReady = size.width && size.height, options = useStableState(props.options);
|
|
184
184
|
useEffect(createOsdViewer, [isContainerReady, store, options]);
|
|
185
185
|
function createOsdViewer() {
|
|
186
186
|
if (!containerRef.current || !isContainerReady)
|
|
@@ -227,10 +227,10 @@ function Viewer(props) {
|
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
function observeResize(element, callback) {
|
|
230
|
-
const
|
|
230
|
+
const observer = new ResizeObserver((entries) => {
|
|
231
231
|
callback(entries[0].contentRect);
|
|
232
232
|
});
|
|
233
|
-
return
|
|
233
|
+
return observer.observe(element), () => observer.disconnect();
|
|
234
234
|
}
|
|
235
235
|
function useContainerSize(ref) {
|
|
236
236
|
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
@@ -238,9 +238,9 @@ function useContainerSize(ref) {
|
|
|
238
238
|
const element = ref.current;
|
|
239
239
|
if (!element)
|
|
240
240
|
return;
|
|
241
|
-
const
|
|
242
|
-
return setSize({ width
|
|
243
|
-
setSize({ width:
|
|
241
|
+
const { width, height } = element.getBoundingClientRect();
|
|
242
|
+
return setSize({ width, height }), observeResize(element, ({ width: width2, height: height2 }) => {
|
|
243
|
+
setSize({ width: width2, height: height2 });
|
|
244
244
|
});
|
|
245
245
|
}, [ref]), size;
|
|
246
246
|
}
|
|
@@ -268,19 +268,33 @@ function Overlay({ location, children }) {
|
|
|
268
268
|
return div.style.position = "absolute", div.style.pointerEvents = "none", div;
|
|
269
269
|
});
|
|
270
270
|
return useEffect(() => {
|
|
271
|
-
function stopPropagation(event) {
|
|
272
|
-
event.target !== overlay && event.stopPropagation();
|
|
273
|
-
}
|
|
274
|
-
return overlay.addEventListener("pointerdown", stopPropagation), () => {
|
|
275
|
-
overlay.removeEventListener("pointerdown", stopPropagation);
|
|
276
|
-
};
|
|
277
|
-
}, [overlay]), useEffect(() => {
|
|
278
271
|
if (viewer)
|
|
279
272
|
return viewer.addOverlay({ element: overlay, location }), () => {
|
|
280
273
|
viewer.isOpen() && viewer.removeOverlay(overlay);
|
|
281
274
|
};
|
|
282
275
|
}, [viewer, location, overlay]), viewer ? createPortal(children, overlay) : null;
|
|
283
276
|
}
|
|
277
|
+
function hasMoved(from, to, threshold) {
|
|
278
|
+
return Math.hypot(to.x - from.x, to.y - from.y) > threshold;
|
|
279
|
+
}
|
|
280
|
+
function usePointerDown({
|
|
281
|
+
onClick,
|
|
282
|
+
onDrag,
|
|
283
|
+
onDragEnd,
|
|
284
|
+
dragThreshold = 5,
|
|
285
|
+
clickTimeLimit = 1 / 0
|
|
286
|
+
}) {
|
|
287
|
+
return function(event) {
|
|
288
|
+
const from = { x: event.clientX, y: event.clientY }, startTime = Date.now(), gesture = new AbortController(), { signal } = gesture;
|
|
289
|
+
let dragging = !1;
|
|
290
|
+
window.addEventListener("pointermove", (move) => {
|
|
291
|
+
const to = { x: move.clientX, y: move.clientY };
|
|
292
|
+
dragging ||= hasMoved(from, to, dragThreshold), dragging && onDrag?.(move);
|
|
293
|
+
}, { signal }), window.addEventListener("pointerup", (up) => {
|
|
294
|
+
gesture.abort(), dragging ? onDragEnd?.(up) : Date.now() - startTime <= clickTimeLimit && onClick?.(up);
|
|
295
|
+
}, { signal }), window.addEventListener("pointercancel", () => gesture.abort(), { signal });
|
|
296
|
+
};
|
|
297
|
+
}
|
|
284
298
|
function ViewerProvider({ children }) {
|
|
285
299
|
const [store] = useState(() => createViewerStore());
|
|
286
300
|
return /* @__PURE__ */ jsx(ViewerContext.Provider, { value: store, children });
|
|
@@ -325,7 +339,8 @@ function useViewerControls(fullscreenRef) {
|
|
|
325
339
|
};
|
|
326
340
|
}
|
|
327
341
|
function findThumbnail(vault, canvas, height = 120) {
|
|
328
|
-
|
|
342
|
+
const id = getImageServiceId(vault, canvas);
|
|
343
|
+
return id ? `${id}/full/,${height}/0/default.jpg` : null;
|
|
329
344
|
}
|
|
330
345
|
export {
|
|
331
346
|
Overlay,
|
|
@@ -338,6 +353,7 @@ export {
|
|
|
338
353
|
useImageInfo,
|
|
339
354
|
useLoadManifest,
|
|
340
355
|
useManifest,
|
|
356
|
+
usePointerDown,
|
|
341
357
|
useViewer,
|
|
342
358
|
useViewerControls,
|
|
343
359
|
useViewerReady,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PointerEvent as ReactPointerEvent } from 'react';
|
|
2
|
+
type PointerDownOptions = {
|
|
3
|
+
onClick?: (event: PointerEvent) => void;
|
|
4
|
+
onDrag?: (event: PointerEvent) => void;
|
|
5
|
+
onDragEnd?: (event: PointerEvent) => void;
|
|
6
|
+
dragThreshold?: number;
|
|
7
|
+
clickTimeLimit?: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Tell a click apart from a drag, and leave the drag itself to the viewer
|
|
11
|
+
*/
|
|
12
|
+
export declare function usePointerDown({ onClick, onDrag, onDragEnd, dragThreshold, clickTimeLimit, }: PointerDownOptions): (event: ReactPointerEvent) => void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
package/dist/useStableProp.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function useStableProp<T>(options: T): T;
|