The simple and high performance library to allow HTML/SVG element to be dragged.
Document and Examples https://anseki.github.io/plain-draggable/
Features:
- Accept HTML/SVG element as an element that comes to be draggable.
- Restrict the draggable area.
- Snap the draggable element to other elements, points, lines, continuous points (i.e. grid) or something.
- Use
requestAnimationFrame
for high performance. - Provide only basic methods, easy and simple usage.
- No dependency.
- Single file.
- Supports modern browsers.
Load PlainDraggable into your web page.
<script src="plain-draggable.min.js"></script>
This is simplest case:
draggable = new PlainDraggable(element);
Now, the element
can be moved by mouse-dragging operation.
By default, the moving is restricted to inside of the element
's parent element.
<div class="gray">
<div id="draggable">Drag This</div>
</div>
draggable = new PlainDraggable(document.getElementById('draggable'));
The <div id="draggable">
can be moved within the gray box. (See containment
option.)
For options and more details, refer to the following.
draggable = new PlainDraggable(element[, options])
The element
argument is a HTML or SVG element that will be a draggable element. Any element that has a bounding-box is accepted. Other elements such as <g>
can not specified.
The options
argument is an Object that can have properties as options. You can also change the options by setOptions
method or properties of the instance.
self = draggable.setOptions(options)
Set one or more options.
The options
argument is an Object that can have properties as options.
self = draggable.position()
Re-calculate the position of the draggable element, containment
option and snap
option, with current layout of a page.
Tese are re-calculated as needed automatically when a window is resized, or a window or something is scrolled.
You should call position
method if you changed the layout without resizing the window or scrolling something.
Type | Default |
---|---|
HTML/SVG element or Rect |
Parent element |
A rectangle that restricts the draggable element moving. The draggable element can not move to outside this rectangle even if a mouse is moved to there.
It can be a HTML or SVG element, or Rect
object like {left: '10%', top: 20, right: '90%', height: 300}
(See Rect
). The base of the Rect
object is the current document.
Note that the rectangle is "padding-box" of the element if an element is specified. That is, it is the inside of borders of the element.
The default is the draggable element's parent element.
You can specify a <body>
element that means all of a page, or {left: 0, top: 0, width: '100%', height: '100%'}
means all of a document (the document height might differ from the <body>
height).
Type | Default |
---|---|
number, string, HTML/SVG element, Rect , Array, Object or undefined |
undefined |
See Snap.
Type | Default |
---|---|
HTML/SVG element | Draggable element |
A part element of the draggable element that receives mouse operations. A user seizes and drags this element to move the draggable element.
The default is the draggable element itself, and all of the draggable element can be seized and dragged.
Type | Default |
---|---|
number or false |
9000 |
A z-index
CSS property that is applied to the draggable element when it is being dragged. It is restored when the dragging finished.
If false
is specified, it is not changed.
Type | Default |
---|---|
number or undefined |
undefined |
The distance between the top-left corner of the draggable element and the top-left corner of the document, in pixels.
It can be used for initial position when constructing. Also, it can be used to move the draggable element after constructing.
For example, move it to rightward:
draggable.left += 10;
Type | Default |
---|---|
function or undefined |
undefined |
A function that is called when the draggable element is about to be dragged.
It is called even if the draggable is not moved because containment
or snap
avoided the moving. Use onMove
if you want to something the draggable element is moved.
In the function, this
refers to the current PlainDraggable instance.
An Object that has left
and top
properties as new position is passed to the function. It is new position that the draggable element is about to go to. Thefore it might differ from a position of a mouse. These mean same as left
/top
options.
Also, snapped
property is true
if the position was determined by the draggable element being snaped (See Snap).
If the function returns false
, the moving is canceled.
Type | Default |
---|---|
function or undefined |
undefined |
A function that is called when the draggable is moved.
It is not called when the draggable is not moved because containment
or snap
avoided the moving even if the draggable element is dragged.
In the function, this
refers to the current PlainDraggable instance.
Type | Default |
---|---|
function or undefined |
undefined |
A function that is called when the moving the draggable starts after a mouse button is pressed.
It is not called until the draggable element is moved even if it was dragged, and it is called at most once while a mouse button is being pressed.
In the function, this
refers to the current PlainDraggable instance.
Type | Default |
---|---|
function or undefined |
undefined |
A function that is called when a mouse button is released.
In the function, this
refers to the current PlainDraggable instance.
Type | Default |
---|---|
boolean | false |
If true
is specified, a moving the draggable element is stopped and the draggable element is not receive mouse operations.
Type |
---|
HTML/SVG element (Read-only) |
The element that was passed to constructor.
Type |
---|
Rect (Read-only) |
A Rect
object to indicate current position and size of the draggable element.
The base of the Rect
object is the current document.
Properties with the same name as each option to get or set following options:
Static Property
Type | Default |
---|---|
string or Array | PlainDraggable.draggableCursor : (See below)PlainDraggable.draggingCursor : (See below) |
Default values (depend on web browser):
PlainDraggable.draggableCursor
:['grab', 'all-scroll', 'move']
or['all-scroll', 'move']
(For Webkit)PlainDraggable.draggingCursor
:['grabbing', 'move']
or'move'
(For Webkit)
PlainDraggable.draggableCursor
is a cursor
CSS property that is applied to the handle
element.
PlainDraggable.draggingCursor
is a cursor
CSS property that is applied to the handle
element while a mouse button is being pressed.
Note that the allowed values of the cursor
CSS property depend on each web browser. Also, Webkit has a bug about the cursor
CSS property, and the bug is being ignored a long time.
If an Array that contains multiple values is specified, PlainDraggable tries it with each value until any of them succeeded.
If false
is specified, it is not changed.
If false
is specified for both PlainDraggable.draggableCursor
and PlainDraggable.draggingCursor
, PlainDraggable does nothing to a cursor
CSS property.
Static Property
Type | Default |
---|---|
string | PlainDraggable.draggableClass : 'plain-draggable' PlainDraggable.movingClass : 'plain-draggable-moving' |
PlainDraggable.draggableClass
is a class name that is added to the handle
element.
PlainDraggable.movingClass
is a class name that is added to the handle
element within the period after the draggable element starts moving until a mouse button is released. Then, the draggable element has both classes.
An Object to indicate a position and size of a rectangle. It has following properties:
left
orx
top
ory
width
orright
height
orbottom
All values can be a number as pixels or string as percentage like '30%'
.
A "base" determines an origin for the left
/top
/right
/bottom
, and base values for percentage.
- When the
Rect
object is specified forcontainment
option, the base is the current document. - When the
Rect
object is specified forsnap
option, the base is determined bybase
option. - When the
Rect
object is got byrect
property, the base is the current document.
The x
is an alias for left
, and the y
is an alias for top
. The left
/top
/right
/bottom
indicate distance between left or top edge of the base and each side of the rectangle. Note that right
/bottom
also indicate distance from left or top edge of the base, not right or bottom edge.
The width
/height
indicate a size of the rectangle. The right
is required if width
is not specified, and the bottom
is required if height
is not specified.
Note that the left
must be less than or equal to right
, and the top
must be less than or equal to bottom
. In other words, the width
and height
can not be negative value. PlainDraggable does not exchange these, to avoid behavior that you don't want. For example, {left: 400, right: '50%'}
is ignored when the base is resized to smaller than 800px
.
For example, when the base is an element that sized width: 600px; height: 400px;
:
{left: 20, top: '10%', width: '50%', bottom: 390}
indicates a rectangle that isleft: 20px; top: 40px; width: 300px; height: 350px;
, positioned relative to the top-left corner of the element.{left: '50%', top: 0, width: '50%', height: '100%'}
indicates a rectangle that is the right half of the element.{left: '10%', top: '10%', right: '90%', bottom: '90%'}
indicates a rectangle that has10%
margin at all sides.
You can specify snap
option.
It makes one or more "snap targets". The draggable element gravitates toward a snap target when it is moved to near the snap target, and it sticks to the snap target.
Each snap target can be one of the following:
- Point
- Line
- Element
Rect
object
The point and line are the basic of snap target. The element and Rect
object make multiple lines.
Single value creates a point that the value indicates both X and Y coordinates of the point.
draggable.snap = 160; // Point (X: 160px, Y: 160px)
A value as coordinate can be a number as pixels or string as percentage like '30%'
. The percentage works same as that of Rect
.
For example, this indicates the center of the base.
draggable.snap = '50%'; // Point (X: 50%, Y: 50%) i.e. the center
An Object that has x
and y
properties creates a point that the properties indicate coordinates of the point.
draggable.snap = {x: 160, y: '40%'}; // Point (X: 160px, Y: 40%)
That is, something that does not have both x
and y
is regarded as the same one for both x
and y
.
An Object that has either one of x
and y
properties creates a line that the property indicates a coordinate on the axis. By default, the line has full length of size of the base.
draggable.snap = {y: 30}; // Horizontal Line (Y: 30px)
The other property can be an Object that has one or both of start
and end
properties that indicate a coordinate on the axis. This Object indicates the range and length of the line.
draggable.snap = {x: '50%', y: {start: 5, end: '50%'}}; // Vertical Line (X: 50%, Y: 5px .. 50%)
Note that the start
must be less than or equal to end
. PlainDraggable does not exchange these, to avoid behavior that you don't want. For example, x: {start: 400, end: '50%'}
is ignored when the base is resized to smaller than 800px
.
A step
property of the Object copies the point or line repeatedly at specified intervals. This may be called "Grid". It can be also grid on only either one of X and Y axis.
draggable.snap = {step: 30}; // Continuous Points at 30px intervals
draggable.snap = {x: {step: 10}, y: {step: 20}}; // Continuous Points at X: 10px and Y: 20px intervals
draggable.snap = {y: {step: '10%'}}; // Continuous Horizontal Lines at 10% intervals
draggable.snap = {y: {step: '10%', start: 5, end: '50%'}}; // Continuous Lines in specified range
An element or a Rect
object creates four lines that are edges of its rectangle.
draggable.snap = document.getElementById('snap-box'); // Element
draggable.snap = {left: '10%', top: 0, width: '80%', height: 280}; // Rect object
The base of the Rect
object is determined by base
option.
You can specify options for the snap via properties of the Object that is passed to the snap
option, or an Object instead of something that is not Object. For example, you can specify {x: 80, y: 80, gravity: 30}
instead of 80
to specify the gravity
option.
For options and more details, refer to the following.
Actuary, you saw omitted structure of a snap
option in the above.
A basic structure of a snap
option is here:
SnapOptions
:
{
targets: [snapTarget1, snapTarget2...], // `SnapTarget`s
option1: optionValue1, // Common options for all `SnapTarget`s
option2: optionValue2,
:
}
SnapTarget
:
{
x: xValue, // number, string or Object that can have `start`, `end` and `step`
y: yValue,
target: elementOrRect, // Element or Rect object
option1: optionValue1, // Options for this `SnapTarget`, override common option
option2: optionValue2,
:
}
The x
and y
can be a number as pixels, string as percentage like '30%'
or Object. The Object can have start
, end
and step
properties, and these properties can be a number as pixels or string as percentage like '30%'
.
If both x
and y
are not Object, this SnapTarget
is a point, and these properties indicate coordinates of the point.
If either one of x
and y
is an Object that does not have step
, this SnapTarget
is a line. The property that is not Object, the start
and end
properties of the Object indicate a coordinate on each axis. Then the Object indicates the range and length of the line.