What is interact.js
https://interactjs.io/
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+).
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
http://interactjs.io/docs
Example
var pixelSize = 16 ;
interact ( '.rainbow-pixel-canvas' ) …
Enter fullscreen mode
Exit fullscreen mode
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 )
};
};
Enter fullscreen mode
Exit fullscreen mode
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 >
);
}
Enter fullscreen mode
Exit fullscreen mode