Overdrag is a JavaScript utility for adding draggable
and resizable behavior
to DOM elements respecting an offset parent boundaries.
You can view a live demo here
To install Overdrag:
- using
npm
npm install overdrag
- using
yarn
yarn add overdrag
- using
pnpm
pnpm add overdrag
Want a React
component? Checkout React
version of this utility NPM, and GH
NOTE
Yes,TS
is fully supported out of the box! No need for installing@types
.
To use Overdrag, import the Overdrag class from the package:
import Overdrag from "overdrag";
The Overdrag class constructor accepts an object with the following properties:
-
element
(required): The DOM element to control. -
minContentHeight
(default:Overdrag.DEFAULTS.minContentHeight
): The minimum height of the DOM element (CSS height) in pixels. This prevents resizing smaller than the specified value. -
minContentWidth
(default:Overdrag.DEFAULTS.minContentWidth
): The minimum width of the DOM element (CSS width) in pixels. This prevents resizing smaller than the specified value. -
maxContentHeight
(default:Overdrag.DEFAULTS.maxContentHeight: Infinity
): The max height of the DOM element (CSS height) in pixels. This prevents resizing bigger than the specified value. -
maxContentWidth
(default:Overdrag.DEFAULTS.maxContentWidth: Infinity
): The max width of the DOM element (CSS width) in pixels. This prevents resizing bigger than the specified value. -
snapThreshold
(default:Overdrag.DEFAULTS.snapThreshold
): The distance to the edge of the relative parent element (top, left, bottom, right) when the element should snap to it. -
controlsThreshold
(default:Overdrag.DEFAULTS.controlsThreshold
): The distance to the edge of the element (top, left, bottom, right) when the element should show resize cursor and activate control points. -
clickDetectionThreshold
(default:Overdrag.DEFAULTS.clickDetectionThreshold
): The threshold distance to detect a click event. If you've started dragging the element, mouse up event will not triggerclick
event. -
stack
(default:false
): If true, anOverdrag
parent element that has a recursively embeddedOverdrag
elements as a child will retainover
state while the child is active. Else, the parent element will be set toout
state (inactive)
const element = document.getElementById("myElement");
const overdrag = new Overdrag({
element: element,
minContentHeight: 100, // optional
minContentWidth: 100, // optional
maxContentHeight: 400, // optional
maxContentWidth: 400, // optional
snapThreshold: 20, // optional
controlsThreshold: 10, // optional
clickDetectionThreshold: 5, // optional
stack: true, // optional
});
overdrag.on(Overdrag.EVENTS.OVER, (instance) => console.log('mouse over the: ', instance))
overdrag.on(Overdrag.EVENTS.CONTROLS_ACTIVE, (instance) => console.log('active senors: ', instance.controls))
// all available events defined here: Overdrag.EVENTS
Controlled element is bound by its parent bounds and requires parent element to have position:relative
CSS property for the controlled element absolute position be relative to its offsetParent
.
NOTE
Absolute position of the target element is enforced during construction of class instance, so don't feel bad if you've forgotten to assign it.
While hovering near and/or over the edge of controlled element (left, right, top, bottom), that includes border sizes, a corresponding sensor will be activated. Pressing mouse down and initiating a drag will move corresponding edge of the element, thereby resizing it.
NOTE
Two adjacent sensors can be activated at once, ex: top-right, in which case dragging mouse around will resize both: width and height of controlled element.
Maximum size is determined by the size of the offset parent, however, a margin values of controlled element are respected, so if controlled element has a right-margin value of 10
the max width of the element will be no larger than offsetParent.width - 10px
NOTE
SeemaxContentWidth/Height
values
While hovering over the element content (passed the control sensors), pressing mouse down
and proceeding to move it will engage drag
motion and element will follow the motion of a mouse while respecting its initial offset. Max top/bottom/right/left position of the element will be constrained by its offsetParent bounds.
In both cases, drag
and resize
the edge of controlled element will snap to the edge of offsetParent
if controlled element distance to offsetParent
edge (including margins) is equal to or less than snapThreshold
value.
Sensitivity of control points is determined by the controlsThreshold
value, where control point is activated if mouse cursor distance to the control point of element is equal to of less than controlsThreshold
value.
NOTE
This allows for a better control precision of when control points become active, preventing edge hunting to activate controls
Overdrag extends the eventemitter3
class and emits various events during the interaction. You can listen to these events using the on
method or by attaching event listeners.
overdrag.on(Overdrag.EVENTS.DOWN, (instance) => {
console.log("Down event:", instance);
});
The available events are:
-
down
: Triggered when the mouse button is pressed down on the element. -
up
: Triggered when the mouse button is released if pressed while element was "engaged". -
click
: Triggered when a click action is detected. -
drag
: Triggered during dragging, on every drag motion with a mouse move. -
over
: Triggered when the mouse is over the element passed the control point sensors. -
out
: Triggered when the mouse moves out of the visible box of element excluding control point sensors. -
...
click to see more events...
-
dragStart
: Triggered when the mouse button is pressed down on the element, but not control points. -
dragEnd
: Triggered when the mouse button is released after dragging. -
controlsActive
: Triggered when any control point is activated (edge of element) within control sensor area. -
controlsInactive
: Triggered when the control points are deactivated. -
controlRightUpdate
: Triggered when the right control point position is updated. -
controlLeftUpdate
: Triggered when the left control point position is updated. -
controlTopUpdate
: Triggered when the top control point position is updated. -
controlBottomUpdate
: Triggered when the bottom control point position is updated. -
resize
: Triggered during resizing on every mouse move (if size change detected). -
resizeStart
: Triggered when resizing starts on mouse down. -
resizeEnd
: Triggered when resizing ends on mouse up. -
update
: Triggered before any other event is dispatched.
During interaction with element, its attributes are set according to the current mode and user actions. Use this to set various CSS properties accordingly to reflect type of interaction.
Say you want your element to change background color while its engaged, here is how you do it:
#element-id[data-overdrag-over]{
/* change style while element is engaged */
background-color: red;
}
-
data-overdrag-controls
: Set while any control point is active with a value of active control type (left
,right
,top
,bottom
), Ex:data-overdrag-controls="right-left"
-
data-overdrag-over
: Set while mouse is over the element pass the control sensors -
data-overdrag-down
: Set while mouse is down (preceded byover
conditions). -
data-overdrag-dragging
: Set while element is dragged. -
data-overdrag-drag-mode
: Set when entering drag mode. -
data-overdrag-resizing
: Set while element is being resized, if resizing is detected -
data-overdrag-resize-mode
: Set when entering resize mode
At every point of interaction with a controlled element, mouse cursor style is set according to the mouse position relative to element control points and being over the content area.
NOTE Mouse cursor is set as an element pointer style which should not interfere with a global cursor state. Moreover, the child DOM overrides are performed by default.
click to see all cursor states
- **`w-resize`**: Set while LEFT control sensor is activated (including sensitivity area)-
e-resize
: Set while RIGHT control sensor is activated (including sensitivity area). -
n-resize
: Set while TOP control sensor is activated (including sensitivity area). -
s-resize
: Set while BOTTOM control sensor is activated (including sensitivity area). -
nw-resize
: Set while TOP and LEFT control sensors are activated (including sensitivity area). -
ne-resize
: Set while TOP and RIGHT control sensors are activated (including sensitivity area). -
sw-resize
: Set while BOTTOM and LEFT control sensors are activated (including sensitivity area). -
se-resize
: Set while BOTTOM and RIGHT control sensors are activated (including sensitivity area). -
grab
: Set while mouse is over the element pass the control sensors. -
default
: Set while no interactions are detected.
- Angular support
Enjoy! πππ