1
0
Fork 0
muzika-gromche/Frontend/src/lib/useVeiwportWheel/index.ts

50 lines
1.8 KiB
TypeScript

import type { Px, ZoomRaw } from "@/lib/units";
import { useEventListener } from "@vueuse/core";
import type { MaybeRefOrGetter, Ref } from "vue";
import type { UseZoomAxis } from "../useZoomAxis";
export interface UseVeiwportWheelOptions {
axisHorizontal: UseZoomAxis;
axisVertical: UseZoomAxis;
scrollOffsetLeft: Ref<Px>;
}
export function useVeiwportWheel(
target: MaybeRefOrGetter<HTMLElement | null>,
options: UseVeiwportWheelOptions,
) {
function handler(event: WheelEvent) {
// Note: Math.random() prevents console output history from collapsing same entries.
// console.log("WHEEEEEL", Math.random().toFixed(3), event.deltaX, event.deltaY, event.target, event);
// TODO: Ignore Ctrl key because it intercepts touchpad pinch to zoom?
// TODO: what if the user doesn't use a touchpad, and thus has
// no way to scroll horizontally other than by dragging a scrollbar?
const ignoreCtrlWheel = false;
// Note: this hardcoded value feels good enough both for discrete mouse wheel and precise touchpad.
const ZOOM_RAW_FACTOR = 100;
if (event.shiftKey) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
options.axisVertical.zoom.raw.value -= event.deltaY / ZOOM_RAW_FACTOR;
} else if (event.altKey) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
options.axisHorizontal.zoom.raw.value -= event.deltaY / ZOOM_RAW_FACTOR;
} else if (event.ctrlKey && !ignoreCtrlWheel) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
options.scrollOffsetLeft.value += event.deltaY;
}
}
return useEventListener(target, "wheel", handler, {
passive: false,
});
}