Component 10
Component 10

Reputation: 10497

Raphaël convert drag callback coords relative to canvas

I'm trying to create a circular gauge with a 360 indicator that can be moved with the mouse using Raphaël.

I'm wondering how I can get the absolute coordinates for the main panel. My example works out everything relative the created canvas. However, the callbacks set on Element.drag give me the co-ordinates relative to the browser window rather than the canvas.

I need to work out where the canvas is so I can work out what the new angle of the indicator. Can anyone explain how this is done?

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Example using Raphaël</title>
        <script src="raphael-min.js"></script>
        <script>
            window.onload = function () {
                var PANEL_SIZE = 600,
                    r = Raphael("holder", PANEL_SIZE, PANEL_SIZE),
                    PANEL_MID = PANEL_SIZE/2,
                    RADIUS = 200;

                var out = r.set();
                out.push(r.circle(PANEL_MID, PANEL_MID, RADIUS).attr({stroke: "none", fill: "#ffa"}));

                var pathCmd = function( d ) { return "M"+PANEL_MID.toString()+","+(PANEL_MID+30).toString()+"L"+PANEL_MID.toString()+"," + (PANEL_MID - (RADIUS * d)).toString(); }

                var onStart = function (dx, dy) {
                        this.ox = dx;
                        this.oy = dy;
                        console.log("onStart ", dx, " ", dy); },
                    onMove = function (dx, dy) {
                        console.log("onMove ", this.ox + dx, " ", this.oy + dy, " ", this.value, " ", this.total);
                    },                  
                    onEnd = function () { console.log("onEnd"); };

                var pointer = r.path(pathCmd(0.85)).attr( { stroke: "#444", "stroke-width": 20 } ).drag(onMove, onStart, onEnd);
                pointer.total = 360;
                pointer.value = 0;

                (function () {
                    pointer.animate({transform: "r0,"+PANEL_MID.toString()+","+PANEL_MID.toString()}, PANEL_MID, "elastic" );
                })();
            };
        </script>
    </head>
    <body>
        <div id="holder"></div>
    </body>
</html>

Upvotes: 0

Views: 63

Answers (2)

Ian
Ian

Reputation: 13842

I don't see why this is needed, everything in Raph should be set as needed as you are only using Raph methods.

Firstly in this case, you don't need dx/dy as you don't actually need to use the differences, you can just figure it out from x,y which is passed into the onmove function as the 3,4 parameters.

Raph also has an angle method, to calculate that. So we can add a small bit of code, and remove the dx,dy stuff..

So all you need is...

angle = Raphael.angle( x, y, PANEL_MID, PANEL_MID)
this.transform('r'+(angle+90)+','+PANEL_MID+','+PANEL_MID)

jsfiddle (drag hand)

You can also then get rid of the onstart/onend methods, as they aren't needed either.

Upvotes: 1

11thdimension
11thdimension

Reputation: 10633

You can try using jQuery's offset() method.

var holderOffset = $("#holder").offset();
//now dx and dy would become
dx -= holderOffset.left;
dy -= holderOffset.top;

Upvotes: 1

Related Questions