Archiv der Kategorie ‘Raphael‘

 
 

Raphael Tutorials

I recored two new tutorials about the raphaeljs library. Have a look:

and part two:

Raphael Pie Chart Part 1

So awhile back I created a pie chart in raphael without the use of the SVG arc command. So, my old pie chart works, but it has lots of vector points – it’s all done with moveTo and lineTo. Rather than use the pie chart example from Raphael, I wanted to see if I could create my own from scratch. I got 80% there but then had to peak at how this (http://raphaeljs.com/growing-pie.html) example works. Here are a few arcs put together:

And here is the source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="raphael-min.js"></script>
    <script>
      $(function(){
 
        var p = new Raphael(0,0,"100%","100%");
 
        p.path(arc(200,200,150,0,2) +
               arc(200,200,150,2,3) + 
               arc(200,200,150,3,4.5) + 
               arc(200,200,150,4.5,5) + 
               arc(200,200,150,5,Math.PI*2)).attr("stroke", "white");
 
        function arc(x, y, radius, start, end){
          var f = ((end - start) > Math.PI) ? 1 : 0;
 
          var sx = radius * Math.cos(start);
          var sy = radius * Math.sin(start);
          var ex = x + radius * Math.cos(end);
          var ey = y + radius * Math.sin(end);
 
          var path = "M " + x + " " + y + " l " 
              + sx + " " + sy + " A " + radius 
              + " " + radius + " 0 " + f + " 1 " 
              + ex + " " + ey + " z";
          return path;
        }
 
      });
    </script>
    <style>
      body,html{
        background-color : #333;
      }
    </style>
  </head>
  <body>
 
  </body>
</html>

SVG arc commands are pretty confusing. I had a few problems making this. The first was that I used “L” instead of “l”. Turns out “l” is relative positioning. Another problem was the large-arc-flag and the sweep-flag. I’m still not sure I fully grasp these.

Unlike the one in the example from raphaeljs.com I wanted my arc function to use radians. Over the years I’ve just gotten used to working in radians instead of degrees. I also prefer building a large string rather than using a series of arrays to define a path. Here is what the arc segment function looks like from raphaeljs.com:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
r.customAttributes.segment = function(x, y, r, a1, a2) {
  var flag = (a2 - a1) > 180,
      clr = (a2 - a1) / 360;
  a1 = (a1 % 360) * Math.PI / 180;
  a2 = (a2 % 360) * Math.PI / 180;
  return {
    path: [
      ["M", x, y],
      ["l", r * Math.cos(a1), r * Math.sin(a1)],
      ["A", r, r, 0, +flag, 1, x + r * Math.cos(a2), y + r * Math.sin(a2)],
      ["z"]
    ],
    fill: "hsb(" + clr + ", .75, .8)"
  };
};

I formatted this a bit for readability.

Raphael Animation Along a Path

In earlier versions of Raphael you could use the animateAlong() function to move something along a path. This method no longer exists in Raphael 2.0, instead a different technique is used. Here is the demo from raphaeljs.com: http://raphaeljs.com/gear.html. After tweaking this a little, I was able to create two custom attributes for use with Raphael’s animate() and attr() functions… “along” and “guide” where along is a percentage value (between 0 – 1) of how far along a given path you would like to move and guide is a reference to the path you want to move along. Here is an example:

Here are the custom attributes, “guide” and “along” wrapped in a function called addGuides().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;(function() {
  Raphael.fn.addGuides = function() {
    this.ca.guide = function(g) {
      return {
        guide: g
      };
    };
    this.ca.along = function(percent) {
      var g = this.attr("guide");
      var len = g.getTotalLength();
      var point = g.getPointAtLength(percent * len);
      var t = {
        transform: "t" + point.x + " " + point.y
      };
      return t;
    };
  };
})();

This is the code for the demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="raphael-min.js"></script>
    <script src="raphael-guides.js"></script>
    <script>
      $(function(){
 
        var p = new Raphael(0,0,"100%","100%");
 
        // give raphael guide and along custom attributes
        p.addGuides();
 
        var white = {stroke : "white"};
        var path;
 
        var path1 = p.path("M 100 100 Q 200 500 300 100").attr(white);
 
        var path2 = p.path("M 300 100 \
                           R 350 150 \
                           400 50 \
                           450 100 \
                           500 40 \
                           550 100").attr(white);
 
        var circ1 = p.circle(0, 0, 10).attr(white);
 
        var circ2 = p.circle(0, 0, 10).attr(white);
 
        $(document).on("click", function(){
          // animate along a path
          circ1.attr({guide : path1, along : 0})
            .animate({along : 1}, 3000, "ease-out");
 
          circ2.attr({guide : path2, along : 1})
            .animate({along : 0}, 3000, "ease-out");
        });
 
      });
    </script>
    <style>
      body,html{
        background-color : #333;
        color : white; 
        font-family : sans-serif;
      }
    </style>
  </head>
  <body>
    click me to see animation
  </body>
</html>