JQuery Drag Drop Interactive Box

Date: 2018-09-26
const $ = require('jquery');

let snapToGrid = false;
let snapToRatio = true;

function snap(v, gridSize) {
    return gridSize * Math.floor((v / gridSize) + 0.5);
}

function snap2grid(handle) {
    if (snapToGrid) {
        let $target = handle.$target;
        let $container = handle.$container;
        let gx = $container.width() / 100;
        let gy = $container.height() / 100;

        let offset = $target.offset();
        $target.offset({
            left: snap(offset.left, gx),
            top: snap(offset.top, gy)
        });
        $target.width(snap($target.width(), gx));
        $target.height(snap($target.height(), gy));
        //console.log({width: $target.width() / gx, height: $target.height() / gy });
    }
}

function snap2ratio(handle, newWidth, newHeight) {
    if (snapToRatio) {
        let ratio = handle.ratio;
        let newRatio = (newWidth / newHeight);

        if (ratio > newRatio) {
            newHeight = (newWidth * handle.height) / handle.width;
        } else {
            newWidth = (newHeight * handle.width) / handle.height;
        }
    }
    return {
        width: newWidth,
        height: newHeight
    };
}

function sizeX(handle, e) {
    let width = Math.max(e.pageX - handle.pX + handle.width, 0);
    return width;
}

function sizeY(handle, e) {
    let height = Math.max(e.pageY - handle.pY + handle.height, 0);
    return height;
}

function sizeXNeg(handle, e) {
    let width = Math.max(handle.width - (e.pageX - handle.pX), 0);
    return width;
}

function sizeYNeg(handle, e) {
    let height = Math.max(handle.height - (e.pageY - handle.pY), 0);
    return height;
}

function handleDrag(handle, e) {
    handle.$target.offset({
        left: handle.tx,
        top: handle.ty
    });
    snap2grid(handle);
}

function handleResize_SouthEast(handle, e) {
    let targetWidth = sizeX(handle, e);
    let targetHeight = sizeY(handle, e);

    let snapped = snap2ratio(handle, targetWidth, targetHeight);
    handle.$target.width(snapped.width);
    handle.$target.height(snapped.height);
    snap2grid(handle);
}

function handleResize_South(handle, e) {
    let targetHeight = sizeY(handle, e);
    handle.$target.height(targetHeight);
    snap2grid(handle);
}

function handleResize_SouthWest(handle, e) {
    let targetWidth = sizeXNeg(handle, e);
    let targetHeight = sizeY(handle, e);

    let snapped = snap2ratio(handle, targetWidth, targetHeight);
    // anchors are top and right
    let right = handle.$target.offset().left + handle.$target.width();

    handle.$target.offset({
        left: (right - snapped.width)
    });
    handle.$target.width(snapped.width);
    handle.$target.height(snapped.height);
    snap2grid(handle);
}

function handleResize_West(handle, e) {
    let targetWidth = sizeXNeg(handle, e);
    handle.$target.offset({
        left: handle.tx
    });
    handle.$target.width(targetWidth);
    snap2grid(handle);
}

function handleResize_NorthWest(handle, e) {
    let targetWidth = sizeXNeg(handle, e);
    let targetHeight = sizeYNeg(handle, e);

    let snapped = snap2ratio(handle, targetWidth, targetHeight);
    // anchors are bottom and right
    let bottom = handle.$target.offset().top + handle.$target.height();
    let right = handle.$target.offset().left + handle.$target.width();

    handle.$target.offset({
        left: (right - snapped.width),
        top: (bottom - snapped.height)
    });
    handle.$target.width(snapped.width);
    handle.$target.height(snapped.height);
    snap2grid(handle);
}

function handleResize_North(handle, e) {
    let targetHeight = sizeYNeg(handle, e);
    handle.$target.offset({
        top: handle.ty
    });
    handle.$target.height(targetHeight);
    snap2grid(handle);
}

function handleResize_NorthEast(handle, e) {
    let targetWidth = sizeX(handle, e);
    let targetHeight = sizeYNeg(handle, e);

    let snapped = snap2ratio(handle, targetWidth, targetHeight);
    // anchors are bottom and left
    let bottom = handle.$target.offset().top + handle.$target.height();
    //let left = handle.$target.offset().left+handle.$target.width();

    handle.$target.offset({
        top: (bottom - snapped.height)
    });
    handle.$target.width(snapped.width);
    handle.$target.height(snapped.height);
    snap2grid(handle);
}

function handleResize_East(handle, e) {
    let targetWidth = sizeX(handle, e);
    handle.$target.width(targetWidth);
    snap2grid(handle);
}

// Example: InteractiveBox( $('.box'), [ $e: element, move: handleDrag ] );
function InteractiveBox($e, handles, callback, $container) {
    let self = this;
    self.$target = $e;
    self.handles = handles;
    self.$container = $container || $(window);
    self.callback = callback;
    self.mouseUpTimeout = null;
    self.$document = $(self.$target[0].ownerDocument);

    function registerHandle(handle) {
        handle.active = false;
        handle.$target = self.$target;
        handle.$container = self.$container;

        handle.$e.mousedown(
            function(e) {
                handle.active = true;
                let p = handle.$target.offset(); //position();
                handle.x = p.left;
                handle.y = p.top;
                handle.width = handle.$target.width();
                handle.height = handle.$target.height();
                handle.ratio = handle.width / handle.height;
                handle.pX = e.pageX;
                handle.pY = e.pageY;

                if (handle.start) {
                    handle.start(handle, e);
                }

                e.stopPropagation();
            });

        handle.mouseMove = function(e) {
            if (handle.active && handle.move) {
                snapToGrid = e.ctrlKey;
                snapToRatio = e.shiftKey ? false : true;

                handle.tx = handle.x + e.pageX - handle.pX;
                handle.ty = handle.y + e.pageY - handle.pY;

                handle.move(handle, e); // drag or resize target (x, y or xy)
            }

            e.stopPropagation();
        };

        handle.mouseUp = function(e) {
            handle.active = false;
            if (handle.stop) {
                handle.stop(handle, e);
            }

            if (self.callback) {
                clearTimeout(self.mouseUpTimeout);
                self.mouseUpTimeout = setTimeout(function() {
                    self.callback();
                }, 100);
            }

            e.stopPropagation();
        };

        // Let op deze events moeten geunbind worden!
        self.$document.mousemove(handle.mouseMove);
        self.$document.mouseup(handle.mouseUp);
    }

    for (let i = 0; i < self.handles.length; i += 1) {
        registerHandle(self.handles[i]);
    }

    return self;
}
InteractiveBox.prototype.unbind = function() {
    let self = this;
    clearTimeout(self.mouseUpTimeout);

    function unregisterHandle(handle) {
        self.$document.unbind('mousemove', handle.mouseMove);
        self.$document.unbind('mouseup', handle.mouseUp);

        handle.$e.remove(); // remove element from DOM
    }

    for (let i = 0; i < self.handles.length; i += 1) {
        unregisterHandle(self.handles[i]);
    }

    self.$container = null;
    self.$target = null;
    self.handles = null;
};

module.exports = {
    InteractiveBox,
    handleResize_East,
    handleResize_SouthEast,
    handleResize_South,
    handleResize_SouthWest,
    handleResize_West,
    handleResize_NorthWest,
    handleResize_North,
    handleResize_NorthEast,
    handleDrag
};
registerDragMove(element) {
        let self = this;
        let $e = $(element);

        let $dragHandle = $new('div', $e).addClass('jqHandle').addClass('jqDrag');

        let $dragSE = $new('div', $e).addClass('sizeHandle').addClass('rsSE');
        let $dragS = $new('div', $e).addClass('sizeHandle').addClass('rsS');
        let $dragSW = $new('div', $e).addClass('sizeHandle').addClass('rsSW');
        let $dragW = $new('div', $e).addClass('sizeHandle').addClass('rsW');
        let $dragNW = $new('div', $e).addClass('sizeHandle').addClass('rsNW');
        let $dragN = $new('div', $e).addClass('sizeHandle').addClass('rsN');
        let $dragNE = $new('div', $e).addClass('sizeHandle').addClass('rsNE');
        let $dragE = $new('div', $e).addClass('sizeHandle').addClass('rsE');

        let handles = [];
        handles.push({
            $e: $dragHandle,
            move: jqDrag.handleDrag
        });

        handles.push({
            $e: $dragSE,
            move: jqDrag.handleResize_SouthEast
        });
        handles.push({
            $e: $dragS,
            move: jqDrag.handleResize_South
        });
        handles.push({
            $e: $dragSW,
            move: jqDrag.handleResize_SouthWest
        });
        handles.push({
            $e: $dragW,
            move: jqDrag.handleResize_West
        });
        handles.push({
            $e: $dragNW,
            move: jqDrag.handleResize_NorthWest
        });
        handles.push({
            $e: $dragN,
            move: jqDrag.handleResize_North
        });
        handles.push({
            $e: $dragNE,
            move: jqDrag.handleResize_NorthEast
        });
        handles.push({
            $e: $dragE,
            move: jqDrag.handleResize_East
        });

        function callback() {
            let parentWidth = $e.parent().width();
            let parentHeight = $e.parent().height();

            let position = $e.position();
            let selfWidth = $e.width();
            let selfHeight = $e.height();

            let percentageLeft = round100((position.left / parentWidth) * 100);
            let percentageTop = round100((position.top / parentHeight) * 100);
            let percentageWidth = round100((selfWidth / parentWidth) * 100);
            let percentageHeight = round100((selfHeight / parentHeight) * 100);


            if (self.layer) {
                self.applyLayerPosition(percentageLeft, percentageTop, percentageWidth, percentageHeight);
            }
let $container = $('body');
        self.interactiveBox = new jqDrag.InteractiveBox($e, handles, callback, $container);
    }
    unregisterDragMove() {
        let self = this;
        if (self.interactiveBox) {
            self.interactiveBox.unbind();
        }
        if (self.$actions) {
            self.$actions.remove();
        }
    }

}

 

13870cookie-checkJQuery Drag Drop Interactive Box