CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-gsap

High-performance JavaScript animation library for animating CSS, SVG, canvas, React, Vue, WebGL, and any JavaScript-accessible properties.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

draggable.mddocs/

Draggable

Draggable adds drag and drop functionality to elements with momentum, bounds checking, collision detection, and smooth interactions. It integrates seamlessly with GSAP animations.

Setup

import { Draggable } from "gsap/Draggable";
gsap.registerPlugin(Draggable);

Capabilities

Creating Draggable Instances

Create draggable elements with comprehensive configuration options.

/**
 * Create Draggable instances for elements
 * @param targets - Elements to make draggable
 * @param vars - Draggable configuration
 * @returns Array of Draggable instances
 */
Draggable.create(targets: string | Element | Element[], vars?: Draggable.Vars): Draggable[];

interface Draggable.Vars {
  // Drag type
  type?: "x" | "y" | "rotation" | "top,left" | "x,y";
  
  // Bounds
  bounds?: Element | string | { minX?: number; maxX?: number; minY?: number; maxY?: number; };
  
  // Behavior
  edgeResistance?: number;     // Resistance when hitting bounds (0-1)
  throwResistance?: number;    // Momentum decay resistance (0-10000)
  throwProps?: boolean;        // Enable momentum throwing
  
  // Snapping
  snap?: object | Function;    // Snap configuration
  
  // Interaction
  trigger?: Element | string;  // Element that triggers drag (if different from target)
  cursor?: string;            // CSS cursor during drag
  zIndexBoost?: boolean;      // Boost z-index during drag
  
  // Callbacks
  onPress?: Function;         // Called when press starts
  onDragStart?: Function;     // Called when drag starts
  onDrag?: Function;          // Called during drag
  onDragEnd?: Function;       // Called when drag ends
  onRelease?: Function;       // Called when released
  onThrowUpdate?: Function;   // Called during momentum throw
  onThrowComplete?: Function; // Called when throw completes
}

Usage Examples:

// Basic draggable
Draggable.create(".box", {
  type: "x,y"  // Allow dragging in both directions
});

// Constrained dragging
Draggable.create(".slider-handle", {
  type: "x",                    // Horizontal only
  bounds: ".slider-track",      // Constrain to track element
  edgeResistance: 0.8
});

// With momentum
Draggable.create(".card", {
  type: "x,y",
  throwProps: true,
  bounds: window,
  edgeResistance: 0.65,
  throwResistance: 300
});

Instance Properties

Properties available on Draggable instances for state and position information.

interface Draggable {
  // Position
  x: number;              // Current x position
  y: number;              // Current y position
  rotation: number;       // Current rotation (for rotation type)
  
  // Drag state
  isDragging: boolean;    // Currently being dragged
  isPressed: boolean;     // Mouse/touch is pressed
  isThrowing: boolean;    // Currently in momentum throw
  
  // Start position
  startX: number;         // X position when drag started
  startY: number;         // Y position when drag started
  
  // Deltas
  deltaX: number;         // Change in X since drag start
  deltaY: number;         // Change in Y since drag start
  
  // Pointer info
  pointerX: number;       // Current pointer X position
  pointerY: number;       // Current pointer Y position
  pointerEvent: Event;    // Current pointer event
  
  // Target info
  target: Element;        // The draggable element
  
  // Methods
  disable(): void;        // Disable dragging
  enable(): void;         // Enable dragging
  endDrag(): void;        // Force end current drag
  kill(): void;           // Destroy the Draggable
  update(): void;         // Update bounds and calculations
}

Usage Examples:

const draggable = Draggable.create(".box")[0];

// Access position
console.log(`Position: ${draggable.x}, ${draggable.y}`);

// Check state
if (draggable.isDragging) {
  console.log("Currently dragging");
}

// Control draggable
draggable.disable();  // Temporarily disable
draggable.enable();   // Re-enable
draggable.kill();     // Clean up when done

Static Methods

Utility methods available on the Draggable class.

/**
 * Get existing Draggable instance for an element
 * @param target - Element to get Draggable for
 * @returns Draggable instance or null
 */
Draggable.get(target: Element): Draggable | null;

/**
 * Hit test between two objects
 * @param obj1 - First object (Element or object with x,y,width,height)
 * @param obj2 - Second object
 * @param threshold - Overlap threshold (0-100, as percentage)
 * @returns True if objects overlap
 */
Draggable.hitTest(obj1: any, obj2: any, threshold?: number): boolean;

/**
 * Get time since last drag ended (in milliseconds)
 * @returns Time since last drag
 */
Draggable.timeSinceDrag(): number;

Usage Examples:

// Get existing Draggable
const existingDraggable = Draggable.get(".box");
if (existingDraggable) {
  existingDraggable.disable();
}

// Collision detection
const box1 = document.querySelector(".box1");
const box2 = document.querySelector(".box2");
if (Draggable.hitTest(box1, box2, 50)) {
  console.log("Boxes are overlapping by at least 50%");
}

// Check recent drag activity
if (Draggable.timeSinceDrag() < 1000) {
  console.log("Something was dragged recently");
}

Drag Types

Different types of dragging behavior available.

type DragType = 
  | "x"          // Horizontal dragging only
  | "y"          // Vertical dragging only  
  | "x,y"        // Free dragging in both directions
  | "top,left"   // Drag using CSS top/left instead of transforms
  | "rotation";  // Rotational dragging around center point

Usage Examples:

// Horizontal slider
Draggable.create(".h-slider", { type: "x" });

// Vertical slider  
Draggable.create(".v-slider", { type: "y" });

// Free movement
Draggable.create(".free-box", { type: "x,y" });

// Rotational knob
Draggable.create(".knob", { 
  type: "rotation",
  bounds: { minRotation: 0, maxRotation: 270 }
});

// Layout properties (for special cases)
Draggable.create(".positioned", { type: "top,left" });

Bounds and Constraints

Configure boundaries and movement constraints.

interface BoundsConfig {
  // Element bounds
  bounds?: Element | string;  // Constrain within element
  
  // Numeric bounds
  bounds?: {
    minX?: number;
    maxX?: number;
    minY?: number;
    maxY?: number;
    minRotation?: number;
    maxRotation?: number;
  };
  
  // Special bounds
  bounds?: Window;            // Constrain to viewport
}

Usage Examples:

// Constrain to parent element
Draggable.create(".child", {
  type: "x,y",
  bounds: ".parent"
});

// Numeric constraints
Draggable.create(".constrained", {
  type: "x,y",
  bounds: { minX: 0, maxX: 500, minY: 0, maxY: 300 }
});

// Viewport bounds
Draggable.create(".viewport-bound", {
  type: "x,y",
  bounds: window
});

// Rotation bounds
Draggable.create(".dial", {
  type: "rotation",
  bounds: { minRotation: -180, maxRotation: 180 }
});

Snapping

Configure snapping behavior for precise positioning.

interface SnapConfig {
  snap?: {
    x?: number | number[] | Function;  // X snap increments/positions
    y?: number | number[] | Function;  // Y snap increments/positions
    rotation?: number | number[];      // Rotation snap increments
  };
}

Usage Examples:

// Grid snapping
Draggable.create(".grid-item", {
  type: "x,y",
  snap: {
    x: 50,    // Snap to multiples of 50px
    y: 50
  }
});

// Specific positions
Draggable.create(".card", {
  type: "x,y", 
  snap: {
    x: [0, 100, 200, 300],  // Snap to specific X positions
    y: [0, 150, 300]        // Snap to specific Y positions
  }
});

// Function-based snapping
Draggable.create(".custom-snap", {
  type: "x,y",
  snap: {
    x: function(endValue) {
      return Math.round(endValue / 25) * 25;  // Custom snap logic
    }
  }
});

Event Callbacks

Handle drag lifecycle events for interactive feedback.

interface DragCallbacks {
  onPress?: (event: Event) => void;           // Mouse/touch press
  onDragStart?: (event: Event) => void;       // Drag starts (after threshold)
  onDrag?: (event: Event) => void;            // During drag
  onDragEnd?: (event: Event) => void;         // Drag ends
  onRelease?: (event: Event) => void;         // Mouse/touch release
  onThrowUpdate?: (event: Event) => void;     // During momentum
  onThrowComplete?: (event: Event) => void;   // Momentum complete
}

Usage Examples:

Draggable.create(".interactive", {
  type: "x,y",
  onPress: function(event) {
    gsap.to(this.target, { scale: 1.1, duration: 0.1 });
  },
  onDragStart: function(event) {
    console.log("Drag started");
    gsap.to(this.target, { rotation: 5, duration: 0.2 });
  },
  onDrag: function(event) {
    // Update other elements based on drag position
    gsap.set(".shadow", { x: this.x + 10, y: this.y + 10 });
  },
  onDragEnd: function(event) {
    gsap.to(this.target, { scale: 1, rotation: 0, duration: 0.3 });
  },
  onRelease: function(event) {
    console.log("Released");
  }
});

Integration with GSAP Animations

Combining Draggable with GSAP animations for enhanced interactions.

// Animate to position after drag
const draggable = Draggable.create(".box", {
  type: "x,y",
  onDragEnd: function() {
    // Animate to nearest corner
    const corners = [
      { x: 0, y: 0 },
      { x: 300, y: 0 },
      { x: 300, y: 200 },
      { x: 0, y: 200 }
    ];
    
    let closest = corners[0];
    let minDistance = Infinity;
    
    corners.forEach(corner => {
      const distance = Math.sqrt(
        Math.pow(this.x - corner.x, 2) + 
        Math.pow(this.y - corner.y, 2)
      );
      if (distance < minDistance) {
        minDistance = distance;
        closest = corner;
      }
    });
    
    gsap.to(this.target, {
      x: closest.x,
      y: closest.y,
      duration: 0.5,
      ease: "back.out(1.7)"
    });
  }
});

// Disable dragging during animation
const animateAndDisable = () => {
  draggable[0].disable();
  gsap.to(".box", {
    x: 200,
    y: 100,
    duration: 1,
    onComplete: () => draggable[0].enable()
  });
};

docs

advanced-plugins.md

animation-control.md

core-animation.md

css-properties.md

draggable.md

index.md

scroll-trigger.md

svg-animation.md

text-animation.md

timeline-system.md

utility-functions.md

tile.json