javascriptraphael

Drag and drop in RaphaelJS


I have the following fiddle: http://jsfiddle.net/zugzq7vv/

What I want to do is to be able to drag the number 1 on the left of the input box to the center of the square and make the square change to black and the number white.

How can this be accomplished with RaphaelJS 2.1?

JS code:

// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(document.getElementById("papercanvas"), 320, 200);

var circle = paper.rect(50, 40, 50, 50);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f00");

// Sets the stroke attribute of the circle to white
circle.attr("stroke", "#fff");

var t = paper.text(75, 65,""); //I want this empty string to be a text I drag

And the simple HTML:

1<input id="teste" disabled></input>
<div id="papercanvas"></div>

I know the interface to drag and drop, I just can't seem to be able to apply it to individual numbers.


Solution

  • You cannot make non-svg/Raphael elements to drag using Raphael.js i.e. string "1" which is before input element. So for that you need to have Raphael-text element.

    Even though Raphael supports onDragOver function, it is not sufficient to achieve completely your requirement. Like, It can trigger, when an element was over on it, but it doesnt has any api like onOut, so that you can revert the colors/state back.

    So, as explained in my other SO answer, we need to track the coordinates and based on that we have to take actions in onDragComplete method.

    Here is the working fiddle of what you asked for. But, as it scales you need to add more logic into it, to handle.

    var text = paper.text(10, 10, "1");
    text.attr('cursor','pointer');
    text.attr('font-size', '20px');
    
    text.drag(onDragMove, onDragStart, onDragComplete);
    
    function onDragStart(){
        this.ox = this.attr('x');
        this.oy = this.attr('y');    
    }
    
    function onDragMove(dx,dy){
        this.attr({x: this.ox + dx, y: this.oy + dy });
    }
    
    function onDragComplete(){
        if((this.attr('x') > 20 && (this.attr('x') < 70)) && (this.attr('y') < 50)) {
            this.attr('fill', 'white');
            rect.attr('fill', 'black');
        } else {
            this.attr('fill', 'black');
            rect.attr('fill', 'red');
        }
    };