SVG Animation and JavaScript - Part 2 of Chapter 7 from Perl Graphics Programming (4/4) | WebReference

SVG Animation and JavaScript - Part 2 of Chapter 7 from Perl Graphics Programming (4/4)

To page 1To page 2To page 3current page
[previous]

Perl Graphics Programming, Chapter 7: Creating SVG with Perl

The grid of animated squares defines three JavaScript functions. The first is StartAnimation( ), which initializes the variable used to calculate the center of the block and the table used to keep track of the position and direction of each square. A reference to each element is also stored in the elements[ ] table for convenience. This function is called when the SVG image is first loaded.

function StartAnimation(evt) {
      parent =evt.target.ownerDocument;
      for (i=0; i<25; i++) {
          element[i] = parent.getElementById("box"+i);
          x = element[i].getAttribute("x");
          y = element[i].getAttribute("y");
          xIncrement[i] = (cx-element[i].getAttribute("x"))/frames;
          yIncrement[i] = (cy-element[i].getAttribute("y"))/frames;
      }
      MoveElements(  );
    }

The MoveElements( ) function is called after the environment is initialized and after the center point is moved by the user. This function is a loop that moves each of the squares in the grid toward (or away from) the center and rotates each square.

    function MoveElements(  ) {
        angle = angle+360/frames; 
        count = count+1;
        if (count=  =frames) {
          direction=direction*-1;
          count =0;
        }
        for (i=0; i<25; i++) {
            x = element[i].getAttribute("x");
            y = element[i].getAttribute("y");
            element[i].setAttribute("transform",  
                "rotate("+angle+","+x+","+y+")");
            element[i].setAttribute("x", 
                x - direction * xIncrement[i]);
            element[i].setAttribute("y", 
                y - direction * yIncrement[i]);
   
        }
        setTimeout("MoveElements(  )", delay)
    }

The ChangeColor( ) function is called whenever a mouseover event occurs for any of the 25 squares. It changes the fill attribute of the square to red. When the mouse is no longer over a square, ChangeColorBack( ) changes its fill back to transparent.

    function ChangeColor(evt) {
        evt.target.setAttribute("fill", "#FF0000");
    }
   
    function ChangeColorBack(evt) {
        evt.target.setAttribute("fill", "none");
    }
]]>
ENDSCRIPT
$writer->endTag('script');

Next, add 25 squares in a grid:

foreach my $row (1..5) {
    foreach my $col (1..5) {
        $writer->emptyTag('rect',
                  id => "box".(($row-1)*5+$col-1),
                  onmouseover => "ChangeColor(evt)",
                  onmouseout => "ChangeColorBack(evt)",
                  width => 20, height => 20,
                  'stroke-width' => 1,
                  stroke => '#000000',
                  fill  => 'none',
                  x => 30*$col, y => 30*$row);
    }
}
$writer->endTag('svg');

Now create the top-level wrapper SVG:

my $toplevel = new IO::Scalar;
$writer = XML::Writer->new(OUTPUT => $toplevel);
$writer->setDataMode(1);
$writer->setDataIndent(2);
$writer->startTag('svg',
                  height => $height,
                  width  => $width,
                  'xmlns:xlink' => 'http://www.w3.org/1999/Xlink');
$writer->startTag('script',
                  type => "text/ecmascript");

The top-level SVG image defines one JavaScript function, MoveCenter( ), which moves the center of the animated block of squares to the point that the user clicked.

print $toplevel <<ENDSCRIPT;
<![CDATA[
    function MoveCenter(evt) {
      var sprite = evt.target.ownerDocument.getElementById("sprite");
      sprite.setAttribute("x", evt.clientX-$width/2);
      sprite.setAttribute("y", evt.clientY-$height/2);
    }
]]>
ENDSCRIPT
$writer->endTag('script');

Finally, add a pink background that doubles as a button:

$writer->emptyTag('rect',
                  id => "background",
                  onmousedown => "MoveCenter(evt)",
                  width => 400, height => 400,
                  fill  => 'pink');
print $toplevel $sprite;
$writer->endTag('svg');
   
print $toplevel;

To page 1To page 2To page 3current page
[previous]

Created: February 19, 2003
Revised: February 19, 2003

URL: http://webreference.com/programming/perl/chap7/2/4.html