ROASP:
| |
An Open-Source contribution from RO IT Systems |
|
Perl SVG Tutorials |
Home | Free Code Samples | SVG Module Documentation | SVG Tutorials | SVG Gallery | Forum & Discussion | SVG Perl Modules | SVG-Perl Articles | External Links | Local Copies of Modules (Win32 & CPAN) | YASB: A Perl SVG Browser |
During the last tutorial, we learned how to generate a simple SVG document using SVG.pm.
In this tutorial, we are going to go a little deeper and learn how to draw:
Starting with what we had at the end of tutorial 1, we'll add s bit of usefulness. After all, SVG is all about interactivity and styling.
#!/usr/bin/perl -w use strict; use SVG; # create an SVG object my $svg= SVG->new(width=>200,height=>200); # draw a circle at position (100,100) with ID 'this_circle' $svg->circle(id=>'this_circle',cx=>100,cy=>100,r=>50);
Now let's work with style. Every drawing object can have a style attribute defined. There are two ways to add style definitions to an object: They can be added in-line as direct attributes:
$svg->circle(cy=>20, cy=>10, r=>30, stroke=>'red',fill=>'green');
Or styles can be added as a hash reference tied to the style attribute:
$svg->circle(cy=>20, cy=>10, r=>30, style=>{stroke=>'red', fill=>'green'});
We'll use the latter in these examples.
# Define a style %group_style my %group_style = ( 'opacity'=>1,fill=>'red', 'stroke'=>'green','fill-opacity'=>0.4, 'stroke-opacity'=>'1');
Before we go any further, this would be a good place to add a comment in the SVG so we can find our way when we read through the code.
# create a group with
style %style.
# Every drawn object within this group
# will have the styles defined in %group_style unless
# otherwise specified.
# but first, let's draw an XML <!-- --> comment
$svg->comment('Draw a group with two circles that have url links');
Now we get to the cool stuff. What makes SVG.pm powerful is that it deals with children (tags within tags) seamlessly.
To help understand the concept of a child, let's look at something we should all understand fairly well, the HTML format. In HTML, the minimum content we can have and still be well-composed is:
<html>
<head>
</head>
<body>
</body>
</html>
Here, the <head> and <body> tags are children of the <html> tags. This is because they are between the opening and closing html tags.
In SVG, as in all XML, we have to deal very carefully with children. If a child is in the wrong place, then it breaks the XML, preventing the image from rendering at all.
When we type $svg->XXX();
we define another child XXX of $svg, where $svg is the variable that points to the current tag. As $svg is the default external-most tag, then XXX is a child of the external (<svg></svg>) tag set, or is a child of the svg tag.
We can define a new tag $gp1, and then define new tags to be that group's child, like this:
$svg->comment('Define
a child of $svg called $gp1');
my $gp1 = $svg->group(id=>'group_1',style=>\%group_style);
my $a1 = $gp1->anchor(-href=>'www.w3c.org');
$a1->circle(id=>'this_circle',cx=>170,cy=>100,r=>20);
$a1->circle(id=>'that_circle',cx=>100,cy=>170,r=>20);
# define a third circle with a separate style (stroke colour),
# overriding the group stroke colour definition.
$a1->circle(id=>'the_other_circle',cx=>180,cy=>160,r=>20,
style=>{stroke=>'cyan'});
Above, we have defined $gp1 to be a child of $svg, and then defined $a1 to be a child of $gp1. Then, we have assigned 3 children (circles) to $a1. The above snippet creates the following XML snippet:
<!-- Define a child of $svg called $gp1 --> <g style="stroke-opacity: 1; stroke: green; fill-opacity: 0.4; fill: red; opacity: 1" id="group_1"> <a xlink:href="http://www.w3c.org"> <circle id="this_circle" cx="170" cy="100" r="20" /> <circle id="that_circle" cx="100" cy="170" r="20" /> <circle style="stroke: cyan" cx="180" id="the_other_circle" cy="160" r="20" /> </a> </g>
As you see, we have a <g> group tag which says that everything within the group group_1 has a set of defined style properties: "stroke-opacity: 1; stroke: green; fill-opacity: 0.4; fill: red; opacity: 1".
Its children are:
an anchor tag
defined with the anchor(-href =>"XXX"...) instruction telling SVG to process
it as aan external xlink call;
three circles
which are children of the anchor. This means (see for yourself on the result
link below) that each circle contains an http link to the same site.
Furthermore, notice that the third circle (id = "the_other_circle") has its own style instructions, which act in addition to, and supercede existing, style definitions.
The fill colour was kept the same as the other circles, but the stroke colour changed to cyan.
Finally, let's add a second group with text in it. In XML, text is usually contained as character data, also known as cdata. The snippet below shows how a tag with a child can be defined at the same time as its child. Notice that rather than defining the text tag, and then the cdata child of the text, we can take the short-cut and define both at once.
The text for 'Tutorial' is defined in two steps, while the text fot 'Two' is defined in a single step.
# add
a second group, and give that group
# two text elements with cdata entries
$svg->comment('Draw a second group with two text entries One entry has
an anchor');
my $gp2 = $svg->group(id=>'group_2');
$svg->comment('Here is one way to define text');
my $t1 = $gp2->text(x=>80,y=>20);
$t1->cdata('Tutorial');
$svg->comment('Here is another way to define text');
$gp2->text(x=>120,y=>20)->cdata('Two');
$gp2->anchor(-href=>'/SVG.html')
->text(x=>20,y=>40,fill=>'rgb(200,30,100)')
->cdata('Brought to you by the letters
SVG and pm');
$svg->comment("Well, we're done here");
my $out = $svg->xmlify;
print $out;
And here is the XML source for this marvel. The perl source is below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg height="200" width="200"> <circle id="this_circle" cx="100" cy="100" r="50" /> <!-- Draw a group with two circles that have url links --> <!-- Define a child of $svg called $gp1 --> <g style="stroke-opacity: 1; stroke: green; fill-opacity: 0.4; fill: red; opacity: 1" id="group_1"> <a xlink:href="http://www.w3c.org"> <circle id="this_circle" cx="170" cy="100" r="20" /> <circle id="that_circle" cx="100" cy="170" r="20" /> <circle style="stroke: cyan" cx="180" id="the_other_circle" cy="160" r="20" /> </a> </g> <!-- Draw a second group with two text entries One entry has an anchor --> <g id="group_2"> <text x="80" y="20">Tutorial</text> <text x="120" y="20">Two</text> <a xlink:href="/SVG.html"> <text x="20" fill="rgb(200,30,100)" y="40">Brought to you by the letters SVG and pm</text> </a> </g> <!-- Here is 1 way to define text --> <!-- Here is 1 way to define text --> <!-- Well, we're done here --> </svg>
For more information, please send the author an email: Ronan Oger
Click here for the source code, and Click here to see the result.
Previous Tutorial | Tutorial Home | Next Tutorial
August 15-18, Enschede, the Netherlands
At the SVG Open 2005 Conference you will have the opportunity to learn about the SVG standard, how to use it to create effective and compelling Web content, techniques for developing SVG software solutions, and the latest developments from the W3C. You will meet the authors of the SVG specifications and the creators of SVG applications in person, and you will have the opportunity to provide your own input for future development.
You will get a chance to see the newest SVG applications and tools, and you will hear early announcements of upcoming SVG product releases. SVG Open 2005 courses will enlighten you on SVG, XML and related standards, graphic design and Web application design. Courses will be available at both introductory and advanced levels, in order to serve the needs of all conference attendees.
Click on the image below to proceed to the SVG Open website
| SVG Home | © 2002-2005 Ronan Oger | Site Info |