Files
PacketStation/frontend/src/packet/viewerContext.ts
T

47 lines
1.7 KiB
TypeScript
Raw Normal View History

// The viewer context the drawing overlay reads: pointer to page fractions, mark drags, the page size.
import { createContext, useContext, type PointerEvent as ReactPointerEvent } from "react";
import type { Frac } from "../lib/geometry";
/** The bitmap: at most 2.2 times the PDF size and at most 4200 px wide. */
export function renderScale(pdfWidth: number): number {
return Math.min(2.2, 4200 / Math.max(1, pdfWidth));
}
/** A pointer that moved less than this is a tap. */
export const TAP_PX = 6;
/** A mark drag starts after this. */
export const DRAG_PX = 5;
export interface DragHandlers {
/** The pointer is at f (page fractions, not clamped). */
onMove: (f: Frac) => void;
/** The drag ended at f, or null when it never moved (a tap). */
onEnd: (f: Frac | null) => void;
}
export interface ViewerApi {
/** A client point as page fractions, and whether it lies inside the viewer frame. */
toFrac: (clientX: number, clientY: number) => Frac & { inside: boolean };
/** Starts a mark drag from a pointerdown. Moves and ends follow the window. */
startDrag: (e: ReactPointerEvent, h: DragHandlers) => void;
/** True for a short while after a drag ended, so the click that follows it is ignored. */
justDragged: () => boolean;
}
export interface ViewerInfo extends ViewerApi {
/** Page size in bitmap pixels; 0 until the page is drawn. */
w: number;
h: number;
aspect: number;
}
export const ViewerCtx = createContext<ViewerInfo | null>(null);
/** The viewer the overlay lives in. Marks use it to turn pointers into page fractions. */
export function useViewer(): ViewerInfo {
const v = useContext(ViewerCtx);
if (!v) throw new Error("useViewer must be used inside MapViewer");
return v;
}