0

I am quite new to javascript and to Raphael. I am trying to move a button-like rectangle with text inside. Here is my code :

window.onload = function() {
  var paper = new Raphael(document.getElementById('canvas_container'), "100%", "100%");
  var box1 = paper.rect(100, 100, 120, 50, 10).attr({fill: 'darkorange', stroke: '#3b4449', 'stroke-width': 2, cursor: 'pointer'});

  var box2 = paper.rect(400,100,120,50,10).attr({fill: 'lightblue', stroke: '#3b4449', 'stroke-width': 2});
  var text2 = paper.text(box2.attrs.x + box2.attrs.width/2,box2.attrs.y + box2.attrs.height/2,"[x: " + box2.attrs.x + " y: " + box2.attrs.y + "]").attr({"font-family": "arial", "font-size": 16});
  var button2 = paper.set();
  button2.push(box2); 
  button2.push(text2);

  box1.click(function(){
    // this did not work
    // button2.animate({x: 100, y: 50 }, 1000, 'bounce', function() { // callback function
    //  text2.attr('text',"[x: " + box2.attrs.x + " y: " + box2.attrs.y + "]");
    // });
    button2.animate({transform: "t100,100"}, 1000, 'bounce', function() { // callback function
        text2.attr('text',"[x: " + box2.attrs.x + " y: " + box2.attrs.y + "]");
    });
  });
}

The button2.animate({x: 100, y: 50 }, 1000, 'bounce'); line did not worked properly, the text was not in the right position at the end. By using the transform: I can not use coordinates, I would have to compute them. Also I am not able to get the right coordinates of the blue box at the end when using the transform method.

I was not able to find any answer yet, hope someone can help me.

Thank you

Rangi Lin
  • 9,303
  • 6
  • 45
  • 71
karlitos
  • 1,604
  • 3
  • 27
  • 59

1 Answers1

0

Since you didn't explain how exactly you want to move your button, I'm assuming you want to move the box2 above box1.

There are some misunderstandings and errors in your code, allow me explain one by one.

Why the first way cause text move to wrong position at end ?

Because a set is NOT a group of element which knows its relative position inside the group. A set is merely a collection of elements which is designed for us to operate them in a more convenient way.

So, the code below will move all element in the set to (100, 50)

set.animate({x: 100, y: 50 }, 1000);

and that's why the text is there.

I couldn't find the document, but you can find some explanation here .

Why x, y in attributes seems to be wrong when using transform ?

No, the attribute is correct.

When you transform an element, the result of the transformation will not reflect back to the attributes. You can think like this, when transform(), you are actually attach "transformation" to the elements. Therefore :

paper.circle(100, 100, 5).transform("t100");

You can describe the circle as :

a circle at (100, 100) which will be moved 100px horizontally.

but not - a circle at (200, 100) which will be moved 100px horizontally.


So, here is the code that dose what you want, note that I'm using getBBox() to get coordinate of the button2 set.

  box1.click(function(){
    var moveX = box1.attr("x") - button2.getBBox().x;
    var moveY = (box1.attr("y") - 50) - button2.getBBox().y;
    button2.animate({transform: "t" + moveX + "," + moveY}, 1000, 'ease-in-out', function () {
      text2.attr('text', "[x: " + button2.getBBox().x + "y: " + button2.getBBox().x + "]");
    });
  });

Welcome to SO, and suggest you to write a SSCCE next time.


UPDATE

I do not fully understand why the transformation does not reflect back to the attributes. If I move the circle at the position (100,100) 100px horizontally it will results in a circle at position (200,100). This is what the bounding box gives me. So why I am not able to get the coordinates from the circle after the transformation and have to use the bounding-box method ?

Transform DOSE NOT change the original attribute in the element, because it is something you attach to a element, not function that change a element directly. If you want to know attributes AFTER the transformation applied, you have to use getBBox(), or take a look about matrix.

This is how Raphael.js works. Either you use bounding box function, or extend the Raphael.js by yourself like this

I have changed my previous answer about how I describe transformation a little bit, hope it can help you to understand better this time.

Your code works great but it has the drawback, that you have to compute the transformation values instead of simply setting the position. Is there any other way to move a rectangle with text inside to a position of your choice ?

You can always write helper functions to do these ugly jobs for you anyway, I don't see there's anything wrong with it.

Community
  • 1
  • 1
Rangi Lin
  • 9,303
  • 6
  • 45
  • 71
  • Thank you very much. In between I read about the transformation method elsewhere and it helped me to understand how it works. – karlitos Jan 21 '13 at 13:41
  • You're welcome :). If you think my answer did solve your problem, you can accept the answer by click the check near the vote number. – Rangi Lin Jan 21 '13 at 14:25