RactiveJS drag and drop using mouseevent

I am trying to achieve a simple drag and drop DIV using RactiveJS using proxy events (on-mousedown, up, move, out)

After the JSFiddle, it works just fine, however, when the user moves the mouse too quickly, the drag stops. This is simply because the mouseevent handlers in my case are in the DIV tag instead of body or document elements. The last idea is to create a slider component, however my aim is to provide a better user experience and make it work more like a jQuery draggable.

Template:

<div class="rect {{drag ? 'dragging' : ''}}" 
         on-mousedown="startDrag"
         on-mouseup="stopDrag" 
         on-mouseout="stopDrag" 
         on-mousemove="drag"
         style="top:{{top}}px; left:{{left}}px;">
</div>

      

Active instance:

var ractive = new Ractive({
    el: "#content",
    template: "#template",
    data: {left:20,top:80}
});
ractive.on({
    startDrag : function (event) {
        this.set({
            'drag': true,
            'mouseX': event.original.clientX - this.get('left'),
            'mouseY': event.original.clientY - this.get('top')
        });
    },
    stopDrag : function (event) {
        this.set('drag', false);
    },
    drag : function (event) {
        if(this.get('drag')) {
            var x = event.original.clientX, 
                y = event.original.clientY;
            this.set({
                top: y - this.get('mouseY') ,
                left: x - this.get('mouseX')
            });
            event.original.stopPropagation();
        }
    }
})

      

How can I improve the above code?

+3


source to share


2 answers


Usually mousemove

and mouseend

should be on document

. I find that with Ractive, the decorator usually works better for drag and drop. Here's one example to get you going ( http://jsfiddle.net/h9j2hdyj/1/ ):

<div class="rect noSelect {{ dragging ? 'dragging' : ''}}" 
     decorator='drag:"position"'
     style="{{#position}}top:{{top}}px;left:{{left}}px{{/}}">
</div>

      



decorator:

Ractive.decorators.drag = function(node, keypath){

    var ractive = this, initial, begin, startPos;

    node.addEventListener('mousedown', start, false)

    function listenOnDocument(){
        document.addEventListener('mousemove', move, false)
        document.addEventListener('mouseup', unlistenOnDocument, false)
    }

    function unlistenOnDocument(){
        document.removeEventListener('mousemove', move, false)
        document.removeEventListener('mouseup', end, false)
    }

    function start(e){
        begin = { x: e.x, y: e.y }
        startPos = ractive.get(keypath)
        startPos = { x: startPos.left, y: startPos.top }
        ractive.set('dragging', true)
        listenOnDocument()
        e.preventDefault()
        e.stopPropagation()
    }

    function move(e){
        ractive.set(keypath, {
            left: startPos.x + (e.x - begin.x),
            top: startPos.y + (e.y - begin.y)
        })
        e.preventDefault()
        e.stopPropagation()
    }

    function end(){
        unlistenOnDocument()
        ractive.set('dragging', false)
    }

  return {
      update: function(pos){
          console.log(pos)
          position = pos
      },
    teardown: function(){
        node.removeEventListener('mousedown', start, false)
        end()
    }
  }

}

      

+5


source


Another option is to use the ractive-touchpan

event plugin - they use Hammer.js under the hood to make them mouse - and touch.



+2


source







All Articles