What is interact.js
JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+).JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+).JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+).
taye / interact.js
JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)
JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)
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+:
yarn add interactjs
//= 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
Example
var pixelSize = 16;
interact('.rainbow-pixel-canvas')
…Recently I've worked on Electron + reactjs for h/w(hardware). Then I needed to implement gestures such as long press, swipe, scroll up/down, and drag & drop.
Actually, I thought if I used hammerjs, it would be easy, but actually I gave up using that since it seemed that hammerjs's development wasn't active any more unfortunately.
The last tag was 2016, for personal development that would be fine but the project isn't a personal project so I gave up using that. Then I was doing some research on Openbase.
I checked a few libraries and created a compare list to get feedback from team members. Then we decided to use interact.js because the number of starts is good and it supports gestures the design team requested. In addition, its document is well-organized and we can use it with typescript easily.
docs
https://interactjs.io/docs/
In this article, I will introduce dropzone ui with interact.js + react hooks.
useDrag.ts
https://interactjs.io/docs/draggable/
If you want to use vanillajs, you can use the sample code directly.
import React from "react";
import interact from "interactjs";
type Partial<T> = {
[P in keyof T]?: T[P];
};
const initialPosition = {
width: 100,
height: 100,
x: 0,
y: 225
};
export const useDraggable = (
position: Partial<typeof initialPosition> = initialPosition
) => {
const [elementPosition, setElementPosition] = React.useState<
typeof initialPosition
>({
...initialPosition,
...position
});
const [isEnabled, setIsEnabled] = React.useState<boolean>(true);
const interactiveRef = React.useRef(null);
let { x, y, width, height } = elementPosition;
const enable = () => {
interact((interactiveRef.current as unknown) as HTMLElement)
.draggable({
modifiers: [],
inertia: false
})
.on("dragmove", (event) => {
x += event.dx;
y += event.dy;
setElementPosition({
width,
height,
x,
y
});
});
};
const disable = () => {
interact((interactiveRef.current as unknown) as HTMLElement).unset();
};
React.useEffect(() => {
if (isEnabled) {
enable();
} else {
disable();
}
return disable;
}, [isEnabled]);
return {
ref: interactiveRef,
style: {
transform: `translate3D(${elementPosition.x}px, ${elementPosition.y}px, 0)`,
width: `${elementPosition.width}px`,
height: `${elementPosition.height}px`,
position: "absolute" as React.CSSProperties["position"],
touchAction: "none"
},
position: elementPosition,
isEnabled,
enable: () => setIsEnabled(true),
disable: () => setIsEnabled(false)
};
};
App.tsx
https://interactjs.io/docs/dropzone/
import { useRef } from "react";
import interact from "interactjs";
import "./styles.css";
import { useDraggable } from "./hooks/useDraggable";
export default function App() {
const targetRef = useRef(null);
const draggable = useDraggable();
// dropzone
if (targetRef?.current) {
interact((targetRef.current as unknown) as HTMLElement)
.dropzone({
accept: ".test",
overlap: 0.75
})
.on("dropactivate", (event: Interact.InteractEvent) => {
event.target.classList.add("drop-active");
})
.on("dragenter", (event: Interact.InteractEvent) => {
console.log("dragenter");
const draggableElement = event.relatedTarget;
const dropzoneElement = event.target;
dropzoneElement.classList.add("drop-target");
draggableElement?.classList.add("can-drop");
if (draggableElement) {
draggableElement.style.color = "#fff";
draggableElement.textContent = "release me";
}
})
.on("dragleave", (event: Interact.InteractEvent) => {
const draggableElement = event.relatedTarget;
const dropzoneElement = event.target;
dropzoneElement.classList.remove("drop-target");
draggableElement?.classList.remove("can-drop");
if (draggableElement) {
draggableElement.textContent = "dragging me";
}
})
.on("drop", (event: Interact.InteractEvent) => {
const draggableElement = event.relatedTarget;
if (draggableElement) {
draggableElement.style.color = "#fff";
draggableElement.textContent = "hello world";
}
})
.on("dropdeactivate", (event: Interact.InteractEvent) => {
event.target.classList.remove("drop-active");
event.target.classList.remove("drop-target");
});
}
return (
<div className="App">
<h1>interactjs samples</h1>
<div className="test" ref={draggable.ref} style={draggable.style}>
<p>drag me</p>
<p>
{`x: ${draggable.position.x.toFixed(0)}`}
{`y: ${draggable.position.y.toFixed(0)}`}
</p>
</div>
<div className="dropzone" ref={targetRef}>
dropzone
</div>
</div>
);
}
Top comments (7)
Actually for react I would suggest dndkit.com/
Thank you for your suggestion. I will try that in the future.
I'm using interact.js because I need other gestures for an Electron app 😂
So much "JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)" 😵💫
Yeah, that is true.
But fortunately I do need to care about only chrome since I'm working on Electron app 😆
Great to see Openbase helped you in your research!
Thank you for such an awesome product!
Thanks @0xkoji for the informative tips.
Open source is essential for application developers. It is unfortunate that Open Base has shut down. While searching for alternate, came across kandi from Open Weaver. It helps developers find code snippets, packages, libraries and solutions from millions of assets.
Thanks to such tools for support to the open source community. Happy coding!