UNPKG

@jbrowse/plugin-linear-genome-view

Version:

JBrowse 2 linear genome view

70 lines (69 loc) 2.74 kB
import { useEffect, useRef } from 'react'; import { sum } from '@jbrowse/core/util'; export function useWheelScroll(ref, model) { const zoomDelta = useRef(0); const scrollDelta = useRef(0); const timeout = useRef(null); const rafId = useRef(0); const scheduled = useRef(false); useEffect(() => { let samples = []; const curr = ref.current; function onWheel(event) { if (event.ctrlKey) { event.preventDefault(); samples.push(event.deltaY); const averageDeltaY = Math.abs(sum(samples)) / samples.length; const normalizer = averageDeltaY < 6 ? 25 : averageDeltaY > 30 ? averageDeltaY > 150 ? 500 : 150 : 75; zoomDelta.current += event.deltaY / normalizer; model.setScaleFactor(zoomDelta.current < 0 ? 1 - zoomDelta.current : 1 / (1 + zoomDelta.current)); if (timeout.current) { clearTimeout(timeout.current); } timeout.current = setTimeout(() => { model.setScaleFactor(1); model.zoomTo(zoomDelta.current > 0 ? model.bpPerPx * (1 + zoomDelta.current) : model.bpPerPx / (1 - zoomDelta.current), event.clientX - (curr?.getBoundingClientRect().left || 0)); zoomDelta.current = 0; samples = []; }, 300); } else { if (Math.abs(event.deltaX) > Math.abs(2 * event.deltaY)) { event.preventDefault(); } scrollDelta.current += event.deltaX; if (!scheduled.current) { scheduled.current = true; rafId.current = window.requestAnimationFrame(() => { model.horizontalScroll(scrollDelta.current); scrollDelta.current = 0; scheduled.current = false; }); } } } if (curr) { curr.addEventListener('wheel', onWheel, { passive: false }); return () => { curr.removeEventListener('wheel', onWheel); if (timeout.current) { clearTimeout(timeout.current); } if (rafId.current) { cancelAnimationFrame(rafId.current); } }; } return () => { }; }, [model, ref]); }