1.0.7 • Published 9 months ago

@figliolia/drag-detector v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

Drag Detector

Mouse and Touch driven drag detection for DOM elements. This package is great for driving swipe, drag, and movement animations driven by the end-user's pointer.

Installation

npm i @figliolia/drag-detector
# or 
yarn add @figliolia/drag-detector

Basic Usage

Vanilla JavaScript

To use the DragDetector in your vanilla JS code, simply grab a reference to your DOM node and attach it to a DragDetector instance:

import { DragDetector } from "@figliolia/drag-detector";

const node = document.getElementById("myElement");

const detector = new DragDetector({
  xThreshold: Infinity, // Max distance from the left of the target node to detect drag movements - by default the entire X Axis is draggable
  yThreshold: Infinity, // Max distance from the top of the target node to detect drag movements - by default the entire Y Axis is draggable
  callback: ({ 
    x, // pointer X
    y, // pointer Y
    exit, // is this event a touchend/mouseup event
    rect, // node.getBoundingClientRect()
    node, // your DOM element
    xDelta, // pointer x minus previous pointer x
    yDelta, // pointer y minus previous pointer y
    xDistance, // accumulated x distance since drag start 
    yDistance, // accumulated y distance since drag start
  }) => {
    // Logic to run on drag
    node.style.translate = `${x}px ${y}px`;
  }
});

detector.register(node);
const controller = new AbortController();
node.addEventListener("mousedown", detector.onMouseDown, { signal: controller.signal });
node.addEventListener("touchstart", detector.onMouseDown, { signal: controller.signal });

// to clean up
detector.destroy()
controller.abort();

React

This module provides bindings for React users to simplify using the DragDetector inside components

import { useDragDetector } from "@figliolia/drag-detector";

export const DraggableComponent = ({ children }) => {

  const options = useMemo(() => ({
    callback: ({ y, x, node }) => {
      node.style.translate = `${x}px ${y}px`;
    },
  }), []);

  const detector = useDragDetector(options);

  return (
    <div {...detector.bindings}>
      {children}
    </div>
  );
}

Smoothing animations between points

To smooth animation or add easing to your drag detector's callbacks you may choose to lerp between the current and next states of your drag. To accomplish this you can wrap your callback logic in requestAnimationFrame and apply Easing Functions.

The event passed to your callback contains accumulated distances, current positions, as well as deltas which you can use to create more fine-grained animations:

interface DragEvent { 
  x: number; // pointer X
  y: number; // pointer Y
  exit: boolean; // is this event a touchend/mouseup event
  rect: DOMRectReadOnly; // node.getBoundingClientRect()
  node: HTMLElement; // your DOM element
  xDelta: number; // pointer x minus previous pointer x
  yDelta: number; // pointer y minus previous pointer y
  xDistance: number; // accumulated x distance since drag start 
  yDistance: number; // accumulated y distance since drag start
}
1.0.7

9 months ago

1.0.6

9 months ago

1.0.5

9 months ago

1.0.4

10 months ago

1.0.3

10 months ago

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago