1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. // Adapted from: https://github.com/facebookarchive/fixed-data-table/blob/main/src/vendor_upstream/dom/normalizeWheel.js
    
  11. 
    
  12. export type NormalizedWheelDelta = {
    
  13.   deltaX: number,
    
  14.   deltaY: number,
    
  15. };
    
  16. 
    
  17. // Reasonable defaults
    
  18. const LINE_HEIGHT = 40;
    
  19. const PAGE_HEIGHT = 800;
    
  20. 
    
  21. /**
    
  22.  * Mouse wheel (and 2-finger trackpad) support on the web sucks.  It is
    
  23.  * complicated, thus this doc is long and (hopefully) detailed enough to answer
    
  24.  * your questions.
    
  25.  *
    
  26.  * If you need to react to the mouse wheel in a predictable way, this code is
    
  27.  * like your bestest friend. * hugs *
    
  28.  *
    
  29.  * In your event callback, use this code to get sane interpretation of the
    
  30.  * deltas.  This code will return an object with properties:
    
  31.  *
    
  32.  *   - deltaX  -- normalized distance (to pixels) - x plane
    
  33.  *   - deltaY  -- " - y plane
    
  34.  *
    
  35.  * Wheel values are provided by the browser assuming you are using the wheel to
    
  36.  * scroll a web page by a number of lines or pixels (or pages).  Values can vary
    
  37.  * significantly on different platforms and browsers, forgetting that you can
    
  38.  * scroll at different speeds.  Some devices (like trackpads) emit more events
    
  39.  * at smaller increments with fine granularity, and some emit massive jumps with
    
  40.  * linear speed or acceleration.
    
  41.  *
    
  42.  * This code does its best to normalize the deltas for you:
    
  43.  *
    
  44.  *   - delta* is normalizing the desired scroll delta in pixel units.
    
  45.  *
    
  46.  *   - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT.  This
    
  47.  *     should translate to positive value zooming IN, negative zooming OUT.
    
  48.  *     This matches the 'wheel' event.
    
  49.  *
    
  50.  * Implementation info:
    
  51.  *
    
  52.  * The basics of the standard 'wheel' event is that it includes a unit,
    
  53.  * deltaMode (pixels, lines, pages), and deltaX, deltaY and deltaZ.
    
  54.  * See: http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
    
  55.  *
    
  56.  * Examples of 'wheel' event if you scroll slowly (down) by one step with an
    
  57.  * average mouse:
    
  58.  *
    
  59.  *   OS X + Chrome  (mouse)     -    4   pixel delta  (wheelDelta -120)
    
  60.  *   OS X + Safari  (mouse)     -  N/A   pixel delta  (wheelDelta  -12)
    
  61.  *   OS X + Firefox (mouse)     -    0.1 line  delta  (wheelDelta  N/A)
    
  62.  *   Win8 + Chrome  (mouse)     -  100   pixel delta  (wheelDelta -120)
    
  63.  *   Win8 + Firefox (mouse)     -    3   line  delta  (wheelDelta -120)
    
  64.  *
    
  65.  * On the trackpad:
    
  66.  *
    
  67.  *   OS X + Chrome  (trackpad)  -    2   pixel delta  (wheelDelta   -6)
    
  68.  *   OS X + Firefox (trackpad)  -    1   pixel delta  (wheelDelta  N/A)
    
  69.  */
    
  70. export function normalizeWheel(event: WheelEvent): NormalizedWheelDelta {
    
  71.   let deltaX = event.deltaX;
    
  72.   let deltaY = event.deltaY;
    
  73. 
    
  74.   if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {
    
  75.     // delta in LINE units
    
  76.     deltaX *= LINE_HEIGHT;
    
  77.     deltaY *= LINE_HEIGHT;
    
  78.   } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
    
  79.     // delta in PAGE units
    
  80.     deltaX *= PAGE_HEIGHT;
    
  81.     deltaY *= PAGE_HEIGHT;
    
  82.   }
    
  83. 
    
  84.   return {deltaX, deltaY};
    
  85. }