Awesome Open Source
Awesome Open Source


Draggable, resizable, rotatable library for creating drag-n-drop applications.


Basic example

Drag, zoom and pan SVG


Library provides dragging/resizing/rotating/snapping SVG/HTML Elements.


Run npm install to install with npm.

npm install subjx

Including via a <script> tag:

<script src="../dist/js/subjx.js"></script>

Get started

Main function subjx returns array of Subjx instances which based on elements finded by passed parameters:

import subjx from 'subjx';
import 'subjx/dist/style/subjx.css';

// possible parameters
const xElem = subjx( 'selector' ) |
                subjx( element ) |
                subjx( elementArray );


// enabling tool by `drag` method with the optional parameters
// by default just call `.drag()`
const xDraggables = xElem.drag();

// method always returns array of new Draggable instances
// for disabling use `disable` method for each object
xDraggables.forEach(item => {

"Draggable" API

const [xDraggable] = xDraggables;

// getter returns root DOM element of 'controls'

// provides access to useful options;
// for example: to get reference to any handle's DOM
const {
  handles: { tl, tr, ...etc }
} =;

// enables dragging
// there is no need to call this method manually

// disables dragging, removes controls and handles

 // adds event listener for some events
xDraggable.on(eventName, cb);

// removes event listener for some events, cb);

// Event names
const EVENTS = [

// execute dragging manually
    dx, // drag along the x axis
    dy // drag along the y axis

// execute resizing manually
    dx, // resize along the x axis
    dy, // resize along the y axis
    revX, // reverse resizing along the x axis
    revY, // reverse resizing along the y axis
    doW, // allow width resizing
    doH  // allow height resizing

// execute rotating manually
    delta // radians

// Align element inside container: ['t', 'l', 'r', 'b', 'v', 'h']

// Call this method when applying scale or viewBox values changing
// useful when element's container was transformed from outside

// Returns rotation point handle to default position


Property Description Type Default
container Transformation coordinate system 'selector' | element element.parentNode
controlsContainer "controls" append to this element 'selector' | element element.parentNode
axis Constrain movement along an axis string: 'x' | 'y' | 'xy' 'xy'
snap Snapping to grid in pixels/radians object { x: 10, y: 10, angle: 10 }
each Mimic behavior with other '.draggable' elements object { move: false, resize: false, rotate: false }
proportions Keep aspect ratio when resizing boolean false
draggable Allow or deny an action boolean true
resizable Allow or deny an action boolean true
rotatable Allow or deny an action boolean true
scalable Applies scaling only to root element boolean false
restrict Restricts element dragging/resizing/rotation 'selector' | element -
rotatorAnchor Rotator anchor direction string: 'n' | 's' | 'w' | 'e' 'e'
rotatorOffset Rotator offset number 50

Notice: In most cases, it is recommended to use 'proportions' option


    onInit(el) {
        // fires on tool activation
    onMove({ clientX, clientY, dx, dy, transform }) {
        // fires on moving
    onResize({ clientX, clientY, dx, dy, transform, width, height }) {
        // fires on resizing
    onRotate({ clientX, clientY, delta, transform }) {
        // fires on rotation
    onDrop({ clientX, clientY }) {
        // fires on drop
    onDestroy(el) {
        // fires on tool deactivation

Subscribing new draggable element to previously activated(useful with each option)

const observable = subjx.createObservable();
subjx('.draggable').drag({...}, observable);

const createDraggableAndSubscribe = e => {
    subjx({...}, observable);

Allowed SVG elements: g, path, rect, ellipse, line, polyline, polygon, circle



const xCloneable = xElem.clone({
    // dropping area
    stack: 'selector',
    // set clone parent
    appendTo: 'selector',
    // set clone additional style
    style: {
        border: '1px dashed green',
        background: 'transparent'


    onInit(el) {
        // fires on tool activation
    onMove(dx, dy) {
        // fires on moving
    onDrop(e) {
        // fires on drop
    onDestroy() {
        // fires on tool deactivation


xCloneable.forEach(item => {


MIT (c) Karen Sarksyan

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Javascript (1,551,389
Svg (3,154
Vanilla Javascript (1,163
Drag (370
No Dependencies (335
Snap (328
Resize (261
Related Projects