Convert Figma logo to code with AI

taye logointeract.js

JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)

12,284
783
12,284
76

Top Related Projects

17,883

The JavaScript Drag & Drop library your grandparents warned you about.

Beautiful and accessible drag and drop for lists with React

29,388

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!

21,948

:ok_hand: Drag and drop so simple it hurts

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Quick Overview

interact.js is a powerful JavaScript library for creating interactive user interfaces. It enables developers to implement drag and drop, resizing, and multi-touch gestures with ease. The library is highly customizable and works seamlessly across both mouse and touch devices.

Pros

  • Lightweight and performant, with no dependencies
  • Supports a wide range of interactions, including drag-and-drop, resizing, and multi-touch gestures
  • Highly customizable with a modular architecture
  • Works well across different devices and input methods (mouse, touch, pen)

Cons

  • Learning curve can be steep for complex interactions
  • Documentation, while comprehensive, can be overwhelming for beginners
  • Some advanced features may require additional setup or configuration
  • Limited built-in UI components compared to full-fledged UI frameworks

Code Examples

  1. Basic draggable element:
interact('.draggable').draggable({
  listeners: {
    move (event) {
      const target = event.target
      const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
      const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy

      target.style.transform = `translate(${x}px, ${y}px)`
      target.setAttribute('data-x', x)
      target.setAttribute('data-y', y)
    }
  }
})
  1. Resizable element:
interact('.resizable').resizable({
  edges: { top: true, left: true, bottom: true, right: true },
  listeners: {
    move (event) {
      const target = event.target
      let x = parseFloat(target.getAttribute('data-x') || 0) + event.deltaRect.left
      let y = parseFloat(target.getAttribute('data-y') || 0) + event.deltaRect.top

      Object.assign(target.style, {
        width: `${event.rect.width}px`,
        height: `${event.rect.height}px`,
        transform: `translate(${x}px, ${y}px)`
      })

      target.setAttribute('data-x', x)
      target.setAttribute('data-y', y)
    }
  }
})
  1. Implementing a simple drop target:
interact('.dropzone').dropzone({
  accept: '.draggable',
  overlap: 0.75,
  ondropactivate: function (event) {
    event.target.classList.add('drop-active')
  },
  ondragenter: function (event) {
    event.target.classList.add('drop-target')
    event.relatedTarget.classList.add('can-drop')
  },
  ondragleave: function (event) {
    event.target.classList.remove('drop-target')
    event.relatedTarget.classList.remove('can-drop')
  },
  ondrop: function (event) {
    event.relatedTarget.textContent = 'Dropped'
  },
  ondropdeactivate: function (event) {
    event.target.classList.remove('drop-active')
    event.target.classList.remove('drop-target')
  }
})

Getting Started

  1. Install interact.js using npm:

    npm install interactjs
    
  2. Import the library in your JavaScript file:

    import interact from 'interactjs'
    
  3. Add the necessary HTML elements:

    <div id="draggable" class="draggable">Drag me!</div>
    
  4. Initialize the interaction:

    interact('.draggable').draggable({
      listeners: {
        move: dragMoveListener
      }
    })
    
    function dragMoveListener(event) {
      const target = event.target
      const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
      const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
    
      target.style.transform = `translate(${x}px, ${y}px
    

Competitor Comparisons

17,883

The JavaScript Drag & Drop library your grandparents warned you about.

Pros of Draggable

  • Lightweight and focused specifically on drag-and-drop functionality
  • Seamless integration with Shopify's ecosystem and design patterns
  • Extensive documentation and examples for quick implementation

Cons of Draggable

  • Limited to drag-and-drop interactions, lacking other gesture support
  • Less flexible for complex, multi-touch scenarios
  • Smaller community and fewer third-party extensions compared to Interact.js

Code Comparison

Draggable:

import { Draggable } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('ul'), {
  draggable: 'li'
});

draggable.on('drag:start', () => console.log('Drag started'));

Interact.js:

import interact from 'interactjs';

interact('.draggable').draggable({
  listeners: {
    start (event) { console.log('Drag started') },
    move (event) { event.target.style.transform = `translate(${event.dx}px, ${event.dy}px)` }
  }
});

Both libraries offer straightforward APIs for implementing drag functionality. Draggable focuses on list-like structures, while Interact.js provides more granular control over the drag behavior and supports a wider range of interactions beyond dragging.

Beautiful and accessible drag and drop for lists with React

Pros of react-beautiful-dnd

  • Specifically designed for React applications, offering seamless integration
  • Provides a smooth, natural dragging experience with animations
  • Excellent accessibility features, including keyboard support

Cons of react-beautiful-dnd

  • Limited to drag-and-drop functionality within React applications
  • Less flexible for complex interactions or non-React projects
  • Larger bundle size compared to interact.js

Code Comparison

react-beautiful-dnd:

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <ul {...provided.droppableProps} ref={provided.innerRef}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {(provided) => (
              <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                {item.content}
              </li>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </ul>
    )}
  </Droppable>
</DragDropContext>

interact.js:

interact('.draggable')
  .draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    autoScroll: true,
    listeners: {
      move: dragMoveListener,
    }
  });

Both libraries offer drag-and-drop functionality, but react-beautiful-dnd is more React-specific and declarative, while interact.js provides a more flexible, imperative approach for various interaction types across different frameworks.

29,388

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Pros of Sortable

  • Specifically designed for drag-and-drop sorting, making it more intuitive for list reordering tasks
  • Lighter weight and faster for simple sorting operations
  • Easier to set up for basic sorting functionality with less configuration required

Cons of Sortable

  • Less versatile compared to Interact.js, focusing primarily on sorting and reordering
  • Limited support for complex gestures and multi-touch interactions
  • Fewer options for customizing drag behavior and constraints

Code Comparison

Sortable basic implementation:

new Sortable(document.getElementById('list'), {
  animation: 150,
  ghostClass: 'blue-background-class'
});

Interact.js basic drag-and-drop:

interact('.draggable').draggable({
  inertia: true,
  modifiers: [
    interact.modifiers.restrictRect({
      restriction: 'parent',
      endOnly: true
    })
  ],
  autoScroll: true,
  listeners: { move: dragMoveListener }
});

Summary

Sortable is more focused and easier to use for simple sorting tasks, while Interact.js offers greater flexibility and support for various interaction types. Choose Sortable for straightforward list reordering, and Interact.js for more complex drag-and-drop scenarios or when additional gestures are needed.

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!

Pros of Moveable

  • More comprehensive set of features, including resizing, rotating, and snapping
  • Better support for touch devices and mobile interactions
  • Extensive customization options for visual feedback and styling

Cons of Moveable

  • Steeper learning curve due to more complex API
  • Larger file size and potentially higher performance overhead
  • Less focus on accessibility features compared to Interact.js

Code Comparison

Moveable:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
  resizable: true,
  rotatable: true
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Interact.js:

import interact from 'interactjs';

interact('.target')
  .draggable({
    listeners: {
      move (event) {
        const target = event.target;
        const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

        target.style.transform = `translate(${x}px, ${y}px)`;
        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);
      }
    }
  });

Both libraries offer powerful interaction capabilities, but Moveable provides a more feature-rich experience at the cost of simplicity, while Interact.js focuses on a simpler API with a stronger emphasis on accessibility.

21,948

:ok_hand: Drag and drop so simple it hurts

Pros of Dragula

  • Simpler API and easier to set up for basic drag-and-drop functionality
  • Lightweight with minimal dependencies
  • Better out-of-the-box support for touch devices

Cons of Dragula

  • Less feature-rich compared to Interact.js
  • Limited support for advanced interactions like resizing or multi-touch gestures
  • Fewer customization options for drag behavior and animations

Code Comparison

Dragula:

dragula([document.querySelector('#left'), document.querySelector('#right')])
  .on('drop', function (el) {
    console.log('Dropped: ' + el.textContent);
  });

Interact.js:

interact('.draggable')
  .draggable({
    listeners: {
      move: function (event) {
        var target = event.target;
        var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
        var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
        target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);
      }
    }
  });

Summary

Dragula is simpler and more lightweight, making it ideal for basic drag-and-drop functionality. Interact.js offers more advanced features and customization options, but with a steeper learning curve. Choose Dragula for quick implementation of simple drag-and-drop, and Interact.js for more complex interaction requirements.

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Pros of react-sortable-hoc

  • Specifically designed for React applications, providing seamless integration
  • Offers a higher-level abstraction for sortable lists and grids
  • Provides built-in support for keyboard accessibility

Cons of react-sortable-hoc

  • Limited to sorting functionality, while interact.js offers a broader range of interactions
  • May have a steeper learning curve for developers not familiar with higher-order components
  • Less flexible for non-React projects or complex custom interactions

Code Comparison

react-sortable-hoc:

import { SortableContainer, SortableElement } from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) => <li>{value}</li>);

const SortableList = SortableContainer(({items}) => {
  return (
    <ul>
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </ul>
  );
});

interact.js:

interact('.draggable')
  .draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    autoScroll: true,
    listeners: { move: dragMoveListener }
  })

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

interact.js

JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+).

Gitter jsDelivr Build Status

Features include:

  • inertia and snapping
  • multi-touch, simultaneous interactions
  • cross browser and device, supporting the desktop and mobile versions of Chrome, Firefox and Opera as well as Internet Explorer 9+
  • interaction with SVG elements
  • being standalone and customizable
  • not modifying the DOM except to change the cursor (but you can disable that)

Installation

  • npm: npm install interactjs
  • jsDelivr CDN: <script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
  • unpkg CDN: <script src="https://unpkg.com/interactjs/dist/interact.min.js"></script>
  • Rails 5.1+:
    1. yarn add interactjs
    2. //= require interactjs/interact
  • Webjars SBT/Play 2: libraryDependencies ++= Seq("org.webjars.npm" % "interactjs" % version)

Typescript definitions

The project is written in Typescript and the npm package includes the type definitions, but if you need the typings alone, you can install them with:

npm install --save-dev @interactjs/types

Documentation

http://interactjs.io/docs

Example

var pixelSize = 16;

interact('.rainbow-pixel-canvas')
  .origin('self')
  .draggable({
    modifiers: [
      interact.modifiers.snap({
        // snap to the corners of a grid
        targets: [
          interact.snappers.grid({ x: pixelSize, y: pixelSize }),
        ],
      })
    ],
    listeners: {
      // draw colored squares on move
      move: function (event) {
        var context = event.target.getContext('2d'),
            // calculate the angle of the drag direction
            dragAngle = 180 * Math.atan2(event.dx, event.dy) / Math.PI;

        // set color based on drag angle and speed
        context.fillStyle = 'hsl(' + dragAngle + ', 86%, '
                            + (30 + Math.min(event.speed / 1000, 1) * 50) + '%)';

        // draw squares
        context.fillRect(event.pageX - pixelSize / 2, event.pageY - pixelSize / 2,
                         pixelSize, pixelSize);
      }
    }
  })
  // clear the canvas on doubletap
  .on('doubletap', function (event) {
    var context = event.target.getContext('2d');

    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
  });

  function resizeCanvases () {
    [].forEach.call(document.querySelectorAll('.rainbow-pixel-canvas'), function (canvas) {
      canvas.width = document.body.clientWidth;
      canvas.height = window.innerHeight * 0.7;
    });
  }

  // interact.js can also add DOM event listeners
  interact(document).on('DOMContentLoaded', resizeCanvases);
  interact(window).on('resize', resizeCanvases);

See the above code in action at https://codepen.io/taye/pen/tCKAm

License

interact.js is released under the MIT License.

NPM DownloadsLast 30 Days