Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 drag and drop element over div with Hammer.js drag events

TL;DR

I want to use HTML5 drag and drop of an element to a container with drag Hammer.js events. However, there are conflicts.

Detailed description:

As presented in the attached figure, I have two containers:

  1. Left: container with draggable elements
  2. Right: container with Hammer.js events, namely drag, dragstart and dragend.

enter image description here

I want to drag and drop elements from the left container to the right one. However, while dragging, when entering on the right container, the Hammer.js dragstart event is activated. After dropping the element, I apply the drag event on the right container. However, the Hammer.js drag event is activated and it considers the deltaX and deltaY from the previous dragstart event.

Hammer.js is being used with preventDefault: true:

Hammer(this.container, {preventDefault: true}).on('dragstart', function (event) { ... }

I have already used event.preventDefault() and event.stopPropagation() on the dragstart of the draggable element, without success.

I have also partially solved the problem. In the dragstart event of the Hammer.js container, I have added the following verification, in order to check if the source element and the target are the same. However, the drag in the right container only works on the second action, since the first one is ignored.

if (event.gesture.startEvent.srcEvent.srcElement != event.gesture.target) {
     return false;
}

Any idea on how to prevent Hammer.js events while dragging elements using the HTML5 drag and drop API?

I want to use flags as a last resort, since Hammer.js events should be developed by third-parties.

Thanks for your help.

like image 724
David Campos Avatar asked Nov 11 '22 06:11

David Campos


1 Answers

Hammer.js events should only be captured if they have previously been bound.

Try using a case statement...(this is from an app that I built recently) I can case the statement then break out or return false etc to prevent things. Theoretically though, if I unbind or exclude the event "drag" it should work anyway.

<script>
var hammertime = Hammer(document.getElementById('image-wrapper'), {
        transform_always_block: true,
        transform_min_scale: window.initScale,
        transform_max_scale: 1,
        drag_block_horizontal: true,
        drag_block_vertical: true,
        drag_min_distance: 0
    });

    //console.log(hammertime);

    var posX = window.calcLeft, posY = window.calcTop,
        lastPosX = window.calcLeft, lastPosY = window.calcTop,
        bufferX = 0, bufferY = 0,
        scale = window.initScale, last_scale,
        rotation = window.rotationNeeded, last_rotation, dragReady = 0;


 hammertime.on('touch drag dragend transform release mouseleave transformend pinchin pinchout', function (ev) {
        elemRect = document.getElementById('the-image');
        manageMultitouch(ev);
    });
function manageMultitouch(ev) {
        var pinchDirection;
        ev.stopPropagation();

        //console.log(ev.type);

        switch (ev.type) {
            case 'touch':
                last_scale = scale;
                last_rotation = rotation;

                break;

            case 'drag':

                posX = ev.gesture.deltaX + lastPosX;
                posY = ev.gesture.deltaY + lastPosY;

                break;

            case 'pinchin':

                console.log('pinchin');
                pinchDirection = "in";

                break;

            case 'pinchout':


                console.log('pinchout');
                pinchDirection = "out";


                break;

            case 'transform':

                rotation = window.rotationNeeded;// rotation + ev.gesture.rotation;//we can change this to snap rotation eventually.
                //console.log('Last Scale: ', last_scale);
                scale = Math.max(hammertime.options.transform_min_scale, Math.min(last_scale * ev.gesture.scale, 1));
                var propsImage = document.getElementById('the-image').getBoundingClientRect();
                //console.log(propsImage);
                var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
                //console.log(propsBox);


                break;

            case 'transformend':
                console.log('We are finished transforming.');
                //when they finish transforming, we need to determinw what the new left reset position would be.
                var propsImage = document.getElementById('the-image').getBoundingClientRect();
                var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
                //window.calcLeft = Math.round(window.preBounds.left - propsImage.left);
                //console.log(ev.type);
                //if (pinchDirection = "out") {

                window.calcLeft = Math.round(window.calcLeft + ((propsImage.width - propsBox.width) / 2));

                //} else if (pinchDirection = "in") {

                //window.calcLeft = Math.round(window.calcLeft - ((propsImage.width - propsBox.width) / 2));
                //}
                //window.calcTop = Math.round(window.calcTop + ((propsImage.top - propsBox.top) / 2));
                //console.log(window.calcLeft);


                break;

            case 'dragend':
                //console.log('We are finished dragging.');
                //console.log(window.calcLeft);
                lastPosX = posX;
                lastPosY = posY;
                checkBounds();


                break;

            case 'mouseleave':
                //console.log('Release!', posX, posY);
                //checkBounds();
                break;

        }

<script>
like image 151
Judson Terrell Avatar answered Nov 14 '22 21:11

Judson Terrell