### Install and use interactjs (npm streamlined)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
Installs and imports only the necessary Interact.js features for a smaller JavaScript payload. This example demonstrates installing core, actions, modifiers, and dev-tools, then setting up a draggable element.
```js
import '@interactjs/auto-start'
import '@interactjs/actions/drag'
import '@interactjs/actions/resize'
import '@interactjs/modifiers'
import '@interactjs/dev-tools'
import interact from '@interactjs/interact'
interact('.item').draggable({
listeners: {
move (event) {
console.log(event.pageX, event.pageY)
},
},
})
```
--------------------------------
### Install interactjs (npm pre-bundled)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
Installs the 'interactjs' npm package, which includes all features of the library in an ES5 bundled format. This is the quickest way to get started.
```sh
# install pre-bundled package with all features
$ npm install --save interactjs
```
--------------------------------
### Basic Draggable Element Setup (HTML, CSS, JS)
Source: https://github.com/taye/interact.js/blob/main/docs/draggable.md
This snippet demonstrates the fundamental setup for creating a draggable element. It includes the HTML structure, necessary CSS for touch and selection, and the JavaScript code using interact.js to enable dragging with event listeners for start and move.
```html
Draggable Element
```
```css
.draggable {
touch-action: none;
user-select: none;
}
```
```javascript
const position = { x: 0, y: 0 }
interact('.draggable').draggable({
listeners: {
start (event) {
console.log(event.type, event.target)
},
move (event) {
position.x += event.dx
position.y += event.dy
event.target.style.transform = `translate(${position.x}px, ${position.y}px)`
},
},
})
```
--------------------------------
### Install Interact.js Features with npm
Source: https://github.com/taye/interact.js/blob/main/docs/tooling.md
Installs specific Interact.js features using npm. This allows you to include only the necessary components for your application, reducing the overall JavaScript payload size. This command installs the core interact library along with auto-start, actions (drag and resize), modifiers, and dev-tools.
```sh
# install only the features you need
$ npm install --save @interactjs/interact \
@interactjs/auto-start \
@interactjs/actions \
@interactjs/modifiers \
@interactjs/dev-tools
```
--------------------------------
### Basic Dropzone Setup and Event Handling (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/dropzone.md
Demonstrates the basic setup of a dropzone using Interact.js and how to handle the 'ondrop' event to display an alert when an element is dropped. It also shows how to add a class to the target element during 'dropactivate'.
```javascript
interact(dropTarget)
.dropzone({
ondrop: function (event) {
alert(event.relatedTarget.id
+ ' was dropped into '
+ event.target.id)
}
})
.on('dropactivate', function (event) {
event.target.classList.add('drop-activated')
})
```
--------------------------------
### Clone Target for Dragging (JavaScript & HTML)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This example shows how to implement dragging a clone of a target element. It involves listening for the 'move' event, creating a clone of the current target, appending it to the document, and then starting a new drag interaction targeting the clone using `interaction.start()`.
```html
```
```javascript
interact('.item')
.draggable({ manualStart: true })
.on('move', function (event) {
var interaction = event.interaction
// if the pointer was moved while being held down
// and an interaction hasn't started yet
if (interaction.pointerIsDown && !interaction.interacting()) {
var original = event.currentTarget,
// create a clone of the currentTarget element
clone = event.currentTarget.cloneNode(true)
// insert the clone to the page
// TODO: position the clone appropriately
document.body.appendChild(clone)
// start a drag interaction targeting the clone
interaction.start({ name: 'drag' }, event.interactable, clone)
}
})
```
--------------------------------
### Resize Modifiers: Snap and Restrict in Interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/migrating.md
Illustrates the usage of new snap and restrict modifiers for resize actions in Interact.js. It includes examples for snapSize to set grid-based targets and restrictSize for minimum dimensions, as well as restrictEdges to keep element edges within a parent.
```javascript
interact(target).resize({
edges: { bottom: true, right: true },
snapSize: {
targets: [
interact.snappers.grid({ x: 25, y: 25, range: Infinity }),
],
},
restrictSize: {
min: { width: 100, height: 50 },
},
restrictEdges: {
outer: 'parent',
endOnly: true,
},
})
```
--------------------------------
### Include interactjs (CDN pre-bundled)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
Shows how to include the Interact.js library in an HTML file using CDN links from jsDelivr or unpkg. This method makes 'interact' available as a global variable.
```html
```
--------------------------------
### Install interactjs types (npm dev dependency)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
Installs the TypeScript type definitions for Interact.js as a development dependency. This is useful for projects using TypeScript or for enhanced autocompletion in JavaScript.
```sh
# install just the type definitions
$ npm install --save-dev @interactjs/types
```
--------------------------------
### Import interactjs (npm pre-bundled)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
Demonstrates how to import the 'interactjs' package in JavaScript, supporting both ES6 module imports and CommonJS/AMD require statements.
```js
// es6 import
import interact from 'interactjs'
```
```js
// or if using commonjs or AMD
const interact = require('interactjs')
```
--------------------------------
### Configure Drag Handle (JavaScript & HTML)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This example demonstrates how to define a specific element as a drag handle for a parent draggable element. The `allowFrom` option in the draggable configuration ensures that a drag action can only be initiated if the pointer interaction starts on the element matching the specified selector or the element itself.
```html
```
```javascript
interact('.item').draggable({
allowFrom: '.handle',
})
```
--------------------------------
### Calculating Start Coordinates on End Events in Interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/migrating.md
Demonstrates how to calculate the difference between the start and end coordinates for drag events in Interact.js. Since dx/dy now represent the difference from the last move event, event.X0 and event.Y0 should be used to retrieve the initial coordinates.
```javascript
interact(target).draggable({
onend: function (event) {
console.log(event.pageX - event.X0, event.pageY - event.Y0)
},
})
```
--------------------------------
### Implement Drag and Drop with Dropzones using Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Sets up draggable elements and dropzones that accept specific draggable items. It handles drag start, move, and end events, along with dropzone activation, deactivation, drag enter, drag leave, and successful drop events. Requires the Interact.js library.
```javascript
const dragPositions = {}
// Setup draggable elements
interact('.drag-item').draggable({
listeners: {
start(event) {
const id = event.target.id
dragPositions[id] = {
x: parseInt(event.target.getAttribute('data-x'), 10) || 0,
y: parseInt(event.target.getAttribute('data-y'), 10) || 0
}
},
move(event) {
const position = dragPositions[event.target.id]
position.x += event.dx
position.y += event.dy
event.target.style.transform =
`translate(${position.x}px, ${position.y}px)`
},
end(event) {
const position = dragPositions[event.target.id]
event.target.setAttribute('data-x', position.x)
event.target.setAttribute('data-y', position.y)
}
}
})
// Setup dropzone with specific accept criteria
interact('.dropzone').dropzone({
// Only accept elements matching this selector
accept: '.drag-item',
// Require 25% overlap for a valid drop
overlap: 0.25,
// Dropzone event listeners
ondropactivate(event) {
// When a compatible drag starts
event.target.classList.add('can-drop')
},
ondropdeactivate(event) {
// When drag ends
event.target.classList.remove('can-drop', 'drop-over')
}
})
.on('dragenter', (event) => {
// Draggable enters dropzone
event.target.classList.add('drop-over')
event.relatedTarget.classList.add('can-drop-here')
})
.on('dragleave', (event) => {
// Draggable leaves dropzone
event.target.classList.remove('drop-over')
event.relatedTarget.classList.remove('can-drop-here')
})
.on('drop', (event) => {
// Successful drop
const draggedElement = event.relatedTarget
const dropzoneElement = event.target
console.log(`${draggedElement.id} dropped into ${dropzoneElement.id}`)
event.target.classList.remove('drop-over')
})
```
--------------------------------
### Interact.js CDN Import and Basic Drag Functionality (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
This snippet demonstrates how to import Interact.js modules from a CDN and configure a basic draggable element. It requires a modern browser supporting ES6 imports. The output is logged to the console during drag.
```html
```
--------------------------------
### Interact.js Rails Integration with Yarn (Ruby)
Source: https://github.com/taye/interact.js/blob/main/docs/installation.md
This snippet shows how to add Interact.js to a Rails 5.1+ application using the Yarn package manager. It assumes Yarn is set up and then demonstrates how to require the Interact.js library in your Rails assets.
```ruby
//= require interactjs/interact
```
--------------------------------
### Start Dragging After Hold (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This snippet demonstrates how to configure interact.js to start a drag operation only after the pointer has been held down for a specified duration. It utilizes the 'hold' option within the draggable configuration.
```javascript
interact(target)
.draggable({
// start dragging after the pointer is held down for 1 second
hold: 1000
})
```
--------------------------------
### Trigger Reflow Action Sequences with interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/reflow.md
Demonstrates how to use the reflow method to programmatically start drag and resize actions on an interactable element. The method triggers a complete start -> move -> end sequence with modifiers and drop calculations. Returns a Promise that resolves when interactions complete, including inertia effects if configured.
```javascript
const interactable = interact(target).draggable({}).resizable({})
async function onWindowResize () {
// start a resize action and wait for inertia to finish
await interactable.reflow({ name: drag, axis: 'x' })
// start a drag action
await interactable.reflow({
name: 'resize',
edges: { left: true, bottom: true }
})
}
window.addEventListener(onWindowResize, 'resize')
```
--------------------------------
### Manage Multiple Interactions in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Configure interact.js to allow a specified number of simultaneous interactions on elements. This example demonstrates setting unlimited concurrent interactions and setting up draggable elements within a loop.
```javascript
// Allow unlimited concurrent interactions
interact.maxInteractions(Infinity)
// Default is 1 interaction at a time
// interact.maxInteractions(1)
// Allow up to 3 simultaneous interactions
// interact.maxInteractions(3)
// Setup multiple draggable elements
for (let i = 1; i <= 5; i++) {
interact(`#item-${i}`).draggable({
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
}
}
})
}
```
--------------------------------
### HTML Structure for Resizable Elements
Source: https://github.com/taye/interact.js/blob/main/docs/resizable.md
Example HTML structure for a resizable element. It includes a main resizable container and child divs that act as handles for resizing specific edges (e.g., top-left, bottom-right).
```html
```
--------------------------------
### Dynamically Configure Interactable Elements in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Learn how to dynamically enable, disable, reconfigure, and remove interactable elements using interact.js. This example shows updating draggable options and checking the current state.
```javascript
const element = interact('.dynamic-element')
// Enable dragging
element.draggable(true)
// Disable dragging
element.draggable(false)
// Get current draggable options
const options = element.draggable()
// Update specific options
element.draggable({
inertia: true,
modifiers: [
interact.modifiers.snap({
targets: [interact.snappers.grid({ x: 20, y: 20 })]
})
]
})
// Check if element is draggable
if (element.draggable()) {
console.log('Element is draggable')
}
// Remove the interactable entirely
element.unset()
```
--------------------------------
### Manual Interaction Start with manualStart Option in JavaScript
Source: https://github.com/taye/interact.js/blob/main/docs/auto-start.md
Demonstrates how to disable automatic interaction start in interact.js by setting manualStart to true on a draggable element, then manually initiating the drag action from a doubletap event listener. When manual start is enabled, you must explicitly call interaction.start() with action information, and the cursor will not be set automatically.
```javascript
interact(target)
.draggable({
manualStart: true,
})
.on('doubletap', function (event) {
var interaction = event.interaction
if (!interaction.interacting()) {
interaction.start(
{ name: 'drag' },
event.interactable,
event.currentTarget,
)
}
})
```
--------------------------------
### Enable Inertia for Draggable and Resizable Elements
Source: https://github.com/taye/interact.js/blob/main/docs/inertia.md
Configure inertia physics for drag and resize interactions on a target element. Inertia enables momentum-based movement continuation after pointer release. The example shows simple boolean enabling for drag and detailed configuration with resistance and speed parameters for resize.
```javascript
interact(target)
.draggable({
inertia: true
})
.resizable({
inertia: {
resistance: 30,
minSpeed: 200,
endSpeed: 100
}
})
```
--------------------------------
### Handle Pointer Events (Hold) in JavaScript
Source: https://github.com/taye/interact.js/blob/main/docs/events.md
This example demonstrates how to listen for and handle 'hold' pointer events using Interact.js. When a hold event occurs on a target element, it logs the event type and the target element to the console. Dependencies: Interact.js library.
```javascript
interact(target).on('hold', function (event) {
console.log(event.type, event.target)
})
```
--------------------------------
### Custom Dropzone Checker Function (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/dropzone.md
Implements a custom function to perform additional checks before a drop is allowed. This example prevents dropping into a dropzone that already contains child nodes.
```javascript
interact(target).dropzone({
checker: function (
dragEvent, // related dragmove or dragend
event, // Touch, Pointer or Mouse Event
dropped, // bool default checker result
dropzone, // dropzone Interactable
dropzoneElement, // dropzone element
draggable, // draggable Interactable
draggableElement // draggable element
) {
// only allow drops into empty dropzone elements
return dropped && !dropElement.hasChildNodes();
}
});
```
--------------------------------
### Basic Draggable Element in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Enables drag functionality for elements with the 'draggable' class. It tracks pointer movements and updates the element's position using CSS transforms. Includes listeners for drag start, move, and end events.
```javascript
const position = { x: 0, y: 0 }
interact('.draggable').draggable({
listeners: {
start(event) {
console.log('Drag started on', event.target)
},
move(event) {
// event.dx and event.dy contain the movement delta
position.x += event.dx
position.y += event.dy
// Update element position using transform
event.target.style.transform = `translate(${position.x}px, ${position.y}px)`
},
end(event) {
console.log('Drag ended at', position)
}
}
})
```
--------------------------------
### AspectRatio Modifier for Resizing in Interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/migrating.md
Shows how to use the aspectRatio modifier for resize actions in Interact.js, replacing the older preserveAspectRatio and square options. It supports maintaining the original aspect ratio or enforcing a specific ratio, and can be combined with other modifiers.
```javascript
interact(target).resizable({
edges: { left: true, bottom: true },
modifiers: [
interact.modifiers.aspectRatio({
ratio: 'preserve',
modifiers: [interact.modifiers.restrictSize({ max: 'parent' })],
}),
],
})
```
```javascript
interact(target).resizable({
modifiers: [
interact.modifiers.aspectRatio({
equalDelta: true,
}),
],
})
```
--------------------------------
### Per-action Modifiers Array in Interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/migrating.md
Demonstrates creating and applying restrict and snap modifiers to draggable elements. Modifiers are created using interact.modifiers[modifierName](options) and passed as an array to the action's modifiers option. This allows for easier reuse and ordering of modifier configurations.
```javascript
const restrictToParent = interact.modifiers.restrict({
restriction: 'parent',
elementRect: { left: 0, right: 0, top: 1, bottom: 1 },
})
const snap100x100 = interact.modifiers.snap({
targets: [interact.snappers.grid({ x: 100, y: 100 })],
relativePoints: [{ x: 0.5, y: 0.5 }],
})
interact(target)
.draggable({
modifiers: [restrictToParent, snap100x100],
})
.on('dragmove', event => console.log(event.pageX, event.pageY))
```
--------------------------------
### Prevent Scrolling/Zooming with Touch (CSS)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This CSS example demonstrates how to disable default touch behaviors like scrolling and zooming to allow for custom touch interactions within interact.js. Applying `touch-action: none;` (and its vendor-prefixed version) to elements involved in touch interactions prevents the browser from interfering.
```css
.draggable, .resizable, .gesturable {
-ms-touch-action: none;
touch-action: none;
user-select: none;
}
```
--------------------------------
### Handle Interaction Events with JavaScript Listeners
Source: https://context7.com/taye/interact.js/llms.txt
Demonstrates various methods for listening to interaction events like dragstart, dragmove, and dragend using interact.js. Includes inline listeners, chained event listeners, and global listeners.
```javascript
// Method 1: Inline listeners
interact('.element').draggable({
listeners: {
start(event) { console.log('start', event) },
move(event) { console.log('move', event) },
end(event) { console.log('end', event) }
}
})
// Method 2: Chained event listeners
interact('.element')
.draggable()
.on('dragstart', (event) => {
event.target.classList.add('dragging')
})
.on('dragmove', (event) => {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
})
.on('dragend', (event) => {
event.target.classList.remove('dragging')
})
// Method 3: Global listeners for all interactables
interact.on('dragstart', (event) => {
console.log('Any element started dragging')
})
// Listen to DOM events
interact(document).on('DOMContentLoaded', () => {
console.log('Document ready')
})
interact(window).on('resize', () => {
console.log('Window resized')
})
```
--------------------------------
### Basic Slider Input with interact.js
Source: https://github.com/taye/interact.js/blob/main/docs/introduction.md
This code demonstrates how to set up a draggable slider using interact.js. It targets elements with the 'slider' class, enables dragging with inertia and restriction, and updates the element's style and a data attribute on drag events. The `interact` function initializes the target, and `.draggable()` configures the drag action. Event listeners are added using `.on('dragmove', ...)`. Dependencies include the interact.js library.
```javascript
// Step 1
const slider = interact('.slider') // target elements with the "slider" class
slider
// Step 2
.draggable({
origin: 'self', // (0, 0) will be the element's top-left
inertia: true, // start inertial movement if thrown
modifiers: [
interact.modifiers.restrict({
restriction: 'self', // keep the drag coords within the element
}),
],
})
// Step 3
.on('dragmove', function (event) {
const sliderWidth = interact.getElementRect(event.target.parentNode).width
const value = event.pageX / sliderWidth
event.target.style.paddingLeft = (value * 100) + '%'
event.target.setAttribute('data-value', value.toFixed(2))
})
```
--------------------------------
### Optimized Interact.js Imports (Source and Result)
Source: https://github.com/taye/interact.js/blob/main/docs/tooling.md
Demonstrates how Interact.js imports are transformed for production builds, both in the source file and the resulting optimized code. This shows the change from standard imports to `.prod` versions, which exclude development hints, leading to smaller production bundles.
```js
// source file
import '@interactjs/actions/drag'
import interact from '@interactjs/interact'
```
```js
// result
import '@interactjs/actions/drag/index.prod'
import interact from '@interactjs/interact/index.prod'
```
--------------------------------
### Implementing Resizable Element with Move Event Listener
Source: https://github.com/taye/interact.js/blob/main/docs/resizable.md
Sets up a resizable element using interact.js, allowing resizing from all edges. The `move` event listener updates the element's dimensions, position, and dataset attributes based on the resize movement. CSS properties like `touch-action: none` and `user-select: none` are recommended for optimal touch and selection behavior.
```javascript
interact('.resizable').resizable({
edges: { top: true, left: true, bottom: true, right: true },
listeners: {
move (event) {
let { x, y } = event.target.dataset
x = (parseFloat(x) || 0) + event.deltaRect.left
y = (parseFloat(y) || 0) + event.deltaRect.top
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`,
})
Object.assign(event.target.dataset, { x, y })
},
},
})
```
--------------------------------
### Manual Interact.js Production Imports Without Build Tools
Source: https://github.com/taye/interact.js/blob/main/docs/tooling.md
Shows how to manually import the production-optimized versions of Interact.js modules when not using build tools like Babel. This involves appending `.prod` to the import paths, and for index files, explicitly adding `index.prod` (e.g., `@interactjs/actions/index.prod`).
```js
import '@interactjs/actions/drag/index.prod'
import interact from '@interactjs/interact/index.prod'
```
--------------------------------
### Axis-Locked Dragging in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Demonstrates how to constrain drag movements to a specific axis (horizontal or vertical) or the starting direction. It utilizes 'startAxis' and 'lockAxis' options within the draggable configuration.
```javascript
// Lock to horizontal axis
interact('.horizontal-only').draggable({
startAxis: 'x',
lockAxis: 'x',
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
event.target.style.transform = `translateX(${x}px)`
event.target.setAttribute('data-x', x)
}
}
})
// Lock to starting direction (whichever axis the user starts dragging in)
interact('.lock-to-start').draggable({
startAxis: 'xy',
lockAxis: 'start',
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
}
}
})
```
--------------------------------
### Draggable Axis Locking and Starting Direction Control (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/draggable.md
This code illustrates how to control the drag axis using interact.js's `startAxis` and `lockAxis` options. It shows how to lock dragging to the initial direction or a specific axis (x or y).
```javascript
// lock the drag to the starting direction
interact(singleAxisTarget).draggable({
startAxis: 'xy'
lockAxis: 'start'
});
// only drag if the drag was started horizontally
interact(horizontalTarget).draggable({
startAxis: 'x'
lockAxis: 'x'
});
```
--------------------------------
### Implement Inertia Dragging with Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Adds momentum-based movement to draggable elements using Interact.js. Configurable parameters include resistance, minimum speed, end speed, and smooth end duration. Requires the Interact.js library.
```javascript
interact('.inertia-drag').draggable({
inertia: {
// Enable inertia
resistance: 20, // Higher = slows down faster (default: 10)
minSpeed: 100, // Minimum speed to trigger inertia (px/second)
endSpeed: 10, // Speed at which movement stops (px/second)
allowResume: true, // Allow resuming drag during inertia
smoothEndDuration: 300 // Duration of snap transition (ms)
},
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
event.target.setAttribute('data-x', x)
event.target.setAttribute('data-y', y)
}
}
})
// Simple inertia with defaults
interact('.simple-inertia').draggable({
inertia: true,
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
}
}
})
```
--------------------------------
### Handle Multi-Touch Gestures with Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Enables handling of two-finger gestures like pinch, rotate, and scale on elements using Interact.js. The 'gesturable' module tracks changes in angle (event.da) and scale (event.ds). Requires Interact.js library.
```javascript
let currentAngle = 0
let currentScale = 1
interact('.gesturable-element').gesturable({
listeners: {
start(event) {
console.log('Gesture started')
},
move(event) {
// event.da = change in angle (degrees)
// event.ds = change in scale
// event.distance = distance between two touches
// event.angle = angle of line between touches
currentAngle += event.da
currentScale *= (1 + event.ds)
event.target.style.transform =
`rotate(${currentAngle}deg) scale(${currentScale})
// Update info display
document.getElementById('angle-display').textContent =
`${currentAngle.toFixed(1)}°`
document.getElementById('scale-display').textContent =
`${currentScale.toFixed(2)}x`
},
end(event) {
console.log('Gesture ended', {
finalAngle: currentAngle,
finalScale: currentScale,
distance: event.distance,
box: event.box // Bounding box of all touch points
})
}
}
})
```
--------------------------------
### Basic Resizable Configuration with Edges
Source: https://github.com/taye/interact.js/blob/main/docs/resizable.md
Configures an element to be resizable. The `edges` option specifies which sides of the element can be resized and how (e.g., using pointer coordinates, selectors, or specific elements). Resize events provide `rect` (current dimensions) and `deltaRect` (change in dimensions).
```javascript
interact(target)
.resizable({
edges: {
top : true,
left : false,
bottom: '.resize-s',
right : handleEl
}
})
```
--------------------------------
### Ignore Elements During Drag (JavaScript & HTML)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This code snippet shows how to prevent drag actions from starting when the pointer is activated on specific child elements. The `ignoreFrom` option prevents interactions if the pointer down event occurs on an element that matches the provided CSS selector or is the specified HTMLElement.
```html
A resizable item
```
```javascript
interact('.item')
.draggable({
// don't drag from textarea elments
ignoreFrom: 'textarea',
});
```
--------------------------------
### Enable Dynamic Dropzones (JavaScript)
Source: https://github.com/taye/interact.js/blob/main/docs/faq.md
This snippet shows how to enable dynamic dropzone recalculation. Setting `interact.dynamicDrop(true)` is necessary when dropzone elements are added, removed, or change dimensions during a drag operation, ensuring accurate dropzone detection.
```javascript
interact.dynamicDrop(true)
```
--------------------------------
### Optimize Interact.js Imports with Babel Plugin
Source: https://github.com/taye/interact.js/blob/main/docs/tooling.md
Configures the Babel build process to optimize Interact.js imports for production. By adding the `@interactjs/dev-tools/babel-plugin-prod` plugin to your production Babel configuration, all `@interactjs/**` imports are automatically transformed to their optimized versions, removing development hints.
```json
// babel config
{
"env": {
"production": {
"plugins": [
"@interactjs/dev-tools/babel-plugin-prod",
]
}
}
}
```
--------------------------------
### Handle Interact.js Events with Listeners
Source: https://github.com/taye/interact.js/blob/main/docs/events.md
This JavaScript code demonstrates how to attach event listeners for drag, resize, and gesture actions using the Interact.js library. It shows various methods for registering listeners, including single events, multiple events, and object mapping. The listener function receives an event object with properties relevant to the interaction.
```javascript
function listener(event) {
event.target.textContent = `${event.type} at ${event.pageX}, ${event.pageY}`
}
interact(target)
.on('dragstart', listener)
.on('dragmove dragend', listener)
.on(['resizemove', 'resizeend'], listener)
.on({
gesturestart: listener,
gestureend: listener,
})
interact(target).draggable({
onstart: listener,
onmove: listener,
onend: listener,
})
interact(target).resizable({
listeners: [
{
start: function (event) {
console.log(event.type, event.pageX, event.pageY)
},
},
],
})
```
--------------------------------
### Configure Dropzone Events in JavaScript
Source: https://github.com/taye/interact.js/blob/main/docs/events.md
This snippet shows how to configure a dropzone using Interact.js. It defines an 'ondrop' function to display an alert when an item is dropped and an 'on('dropactivate')' function to add a CSS class when the drop zone becomes active. Dependencies: Interact.js library.
```javascript
interact(dropTarget)
.dropzone({
ondrop: function (event) {
alert(event.relatedTarget.id + ' was dropped into ' + event.target.id)
},
})
.on('dropactivate', function (event) {
event.target.classList.add('drop-activated')
})
```
--------------------------------
### JavaScript Drag and Drop with Snapping and Drawing on Canvas
Source: https://github.com/taye/interact.js/blob/main/README.md
This JavaScript code snippet demonstrates how to use interact.js to enable drag-and-drop functionality on elements with the class 'rainbow-pixel-canvas'. It includes snapping to a grid, drawing colored squares on the canvas as the user drags, and clearing the canvas on a double-tap. It also handles canvas resizing based on window dimensions and DOM loading.
```javascript
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);
```
--------------------------------
### Implement Snap to Grid with Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Enables draggable elements to snap to a grid, either continuously during movement or only when the drag ends. This utilizes Interact.js's modifier system for snapping. The code defines grid targets and snapping behavior.
```javascript
interact('.grid-snap').draggable({
modifiers: [
interact.modifiers.snap({
// Snap to a 30x30 pixel grid
targets: [
interact.snappers.grid({ x: 30, y: 30 })
],
// Snap relative to the element's top-left corner
relativePoints: [{ x: 0, y: 0 }],
// Range within which snapping occurs (Infinity = always snap)
range: Infinity
})
],
listeners: {
move(event) {
// event.pageX and event.pageY are already snapped
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
event.target.setAttribute('data-x', x)
event.target.setAttribute('data-y', y)
}
}
})
// Snap only when drag ends (smooth snap transition)
interact('.end-snap').draggable({
modifiers: [
interact.modifiers.snap({
targets: [interact.snappers.grid({ x: 50, y: 50 })],
endOnly: true // Only apply snapping at the end
})
],
listeners: {
move(event) {
// Smooth dragging, snaps when released
const x = event.pageX
const y = event.pageY
event.target.style.left = `${x}px`
event.target.style.top = `${y}px`
}
}
})
```
--------------------------------
### Create Canvas Drawing with Snap in Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Enables interactive canvas drawing where pixels are snapped to a grid and their color is determined by drag angle and speed. Features clearing the canvas on double-tap. Requires Interact.js and HTML Canvas API.
```javascript
const pixelSize = 16
interact('.drawing-canvas')
.origin('self')
.draggable({
modifiers: [
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: pixelSize, y: pixelSize })
]
})
],
listeners: {
move(event) {
const context = event.target.getContext('2d')
// Calculate drag angle for color
const dragAngle = 180 * Math.atan2(event.dx, event.dy) / Math.PI
// Set color based on angle and speed
context.fillStyle = `hsl(${dragAngle}, 86%, ${
30 + Math.min(event.speed / 1000, 1) * 50
}%)`
// Draw pixel at snapped position
context.fillRect(
event.pageX - pixelSize / 2,
event.pageY - pixelSize / 2,
pixelSize,
pixelSize
)
}
}
})
.on('doubletap', function(event) {
// Clear canvas on double tap
const context = event.target.getContext('2d')
context.clearRect(0, 0, context.canvas.width, context.canvas.height)
})
```
--------------------------------
### JavaScript Drag and Drop with Snapping and Gestures
Source: https://github.com/taye/interact.js/blob/main/packages/interactjs/README.md
This JavaScript code snippet demonstrates how to use interact.js to enable drag-and-drop functionality on elements with the class 'rainbow-pixel-canvas'. It includes snapping to a grid, drawing colored squares based on drag direction and speed, and clearing the canvas on a double-tap. It also sets up listeners for DOMContentLoaded and window resize events to adjust canvas dimensions.
```javascript
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);
```
--------------------------------
### Specify Handles for Draggable and Resizable Actions
Source: https://github.com/taye/interact.js/blob/main/docs/action-options.md
Uses the `allowFrom` option to define specific child elements (handles) that must be the target of the pointer down event for drag and resize actions to begin. This is also applicable to `pointerEvents`.
```javascript
interact('.movable-box')
.draggable({
allowFrom: '.drag-handle',
})
.resizable({
allowFrom: '.resize-handle',
})
.pointerEvents({
allowFrom: '*',
})
```
--------------------------------
### Configure Pointer Events in JavaScript
Source: https://github.com/taye/interact.js/blob/main/docs/events.md
This code configures pointer events for an Interact.js target, setting options like 'holdDuration', 'ignoreFrom', 'allowFrom', and 'origin'. This allows for fine-grained control over how pointer interactions are detected and processed. Dependencies: Interact.js library.
```javascript
interact(target).pointerEvents({
holdDuration: 1000,
ignoreFrom: '[no-pointer]',
allowFrom: '.handle',
origin: 'self',
})
```
--------------------------------
### Initialize Gesturable with Rotation Handler
Source: https://github.com/taye/interact.js/blob/main/docs/gesturable.md
Configures Interact.js gesturable() listener on #rotate-area element with onmove callback. Calculates cumulative rotation angle from gesture delta angle (event.da), applies CSS transform to rotate arrow element, and updates angle display with degree symbol. Requires two simultaneous touch pointers to trigger gesture events.
```javascript
var angle = 0
interact('#rotate-area').gesturable({
onmove: function (event) {
var arrow = document.getElementById('arrow')
angle += event.da
arrow.style.webkitTransform =
arrow.style.transform =
'rotate(' + angle + 'deg)'
document.getElementById('angle-info').textContent =
angle.toFixed(2) + '\u00b0'
},
})
```
--------------------------------
### Custom Cursor Checkers for Resizable and Draggable
Source: https://github.com/taye/interact.js/blob/main/docs/action-options.md
Implements custom cursor behavior for resize and drag actions. The `cursorChecker` function allows defining specific cursor styles based on interaction details like resize edges or disabling cursors altogether for drag actions.
```javascript
interact(target)
.resizable({
edges: { left: true, right: true },
cursorChecker (action, interactable, element, interacting) {
// the library uses biderectional arrows <-> by default,
// but we want specific arrows (<- or ->) for each diriection
if (action.edges.left) { return 'w-resize' }
if (action.edges.right) { return 'e-resize' }
},
})
.draggable({
cursorChecker () {
// don't set a cursor for drag actions
return null
},
})
```
--------------------------------
### Combine Modifiers for Complex Interactions in Interact.js
Source: https://context7.com/taye/interact.js/llms.txt
Chains multiple Interact.js modifiers, such as restriction to a parent element and snapping to a grid, for sophisticated drag behaviors. Inertia can also be combined. Requires Interact.js library and its modifiers.
```javascript
interact('.complex-interaction').draggable({
modifiers: [
// First restrict to parent
interact.modifiers.restrict({
restriction: 'parent',
endOnly: true
}),
// Then snap to grid
interact.modifiers.snap({
targets: [interact.snappers.grid({ x: 20, y: 20 })],
range: 10,
relativePoints: [{ x: 0, y: 0 }]
})
],
// Add inertia
inertia: {
resistance: 30,
minSpeed: 200,
endSpeed: 100
},
listeners: {
move(event) {
const x = (parseFloat(event.target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(event.target.getAttribute('data-y')) || 0) + event.dy
event.target.style.transform = `translate(${x}px, ${y}px)`
event.target.setAttribute('data-x', x)
event.target.setAttribute('data-y', y)
}
}
})
```
--------------------------------
### Configure Auto-Scroll for Draggable and Resizable
Source: https://github.com/taye/interact.js/blob/main/docs/action-options.md
Enables and configures auto-scrolling behavior for drag and resize actions. The `autoScroll` option can be a boolean to enable default scrolling or an object to customize container, margin, distance, interval, and speed.
```javascript
interact(element)
.draggable({
autoScroll: true,
})
.resizable({
autoScroll: {
container: document.body,
margin: 50,
distance: 5,
interval: 10,
speed: 300,
}
})
```
--------------------------------
### Resizable Element in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Enables resizing for elements with the 'resizable' class from any edge or corner. It updates the element's dimensions and position based on drag deltas, using CSS transforms and data attributes for state.
```javascript
interact('.resizable').resizable({
// Enable resizing from all edges
edges: { top: true, left: true, bottom: true, right: true },
listeners: {
move(event) {
let { x, y } = event.target.dataset
// Update position for top/left edge resizing
x = (parseFloat(x) || 0) + event.deltaRect.left
y = (parseFloat(y) || 0) + event.deltaRect.top
// Apply new dimensions and position
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`
})
Object.assign(event.target.dataset, { x, y })
}
}
})
```
--------------------------------
### Resize with Aspect Ratio in JavaScript
Source: https://context7.com/taye/interact.js/llms.txt
Implements aspect ratio locking during resizing for elements with the 'aspect-ratio-resize' class. It uses the 'aspectRatio' modifier to maintain a specified ratio and 'restrictSize' to set min/max dimensions.
```javascript
interact('.aspect-ratio-resize').resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.aspectRatio({
// Keep aspect ratio at 2:1 (width:height)
ratio: 2,
// Nest other modifiers to ensure they respect the aspect ratio
modifiers: [
interact.modifiers.restrictSize({
min: { width: 100, height: 50 },
max: { width: 800, height: 400 }
})
]
})
],
listeners: {
move(event) {
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`
})
}
}
})
```