There are two modern web technologies for creating rich drawn graphics within
the browser:
HTML5 Canvas and
Scalable Vector Graphics
(SVG).
- Canvas: A hypertext markup language element introduced in
HTML5 for creating and analyzing bitmap images as pixels.
The Canvas specification provides a Javascript API for accessing
the element's graphics context and performing drawing operations
with it.
- SVG: An XML-based vector graphics format.
It is a markup language for describing all aspects of an image or
Web application, from the geometry of shapes, to the styling of
text and shapes, to animation and interactivity. SVG can also be generated through
Javascript.
This presentation focuses on SVG. SVG is fully described in the
W3C SVG Specification.
SVG is an XML (Extensible Markup Language) technology. XML is a simple
text-based format for representing structured information. See W3C's
XML Essentials.
The graphical renderings in the problems below were produced with SVG.
SVG is incorporated into web pages by embedding the
svg element
in a parent HTML document.
The
svg element accepts graphics elements as children to draw
lines, shapes, text, etc.
The
svg element has attributes for, among other things,
- Specifying the SVG namespace
- Giving dimensions to the drawing area
- Styling the drawing area
The example file shown below renders the image shown to the right.
Note that the
svg element shown has no children.
The following pages show the addition of graphics elements as children
of the
svg element.
We begin by depicting the water jug puzzle.
The
polyline element defines a set of connected straight line
segments.
It has attributes for specifying, among other things,
- The endpoints of the line segments (points)
- The fill and stroke color (fill, stroke)
- The stroke width (stroke-width)
Below we have added two
polyline elements as children of
the
svg element to draw outlines of the water jugs.
The
text element defines a graphics element consisting of text.
It has attributes for specifying, among other things,
- The text's baseline position coordinates (x, y)
- The text's color (fill)
- The text's font size (font-size)
The text to be rendered is given in the
text element's body.
Below we have added six
text elements as children of
the
svg element to label the water jugs.
The
rect element defines a rectangle.
It has attributes for specifying, among other things,
- The coordinates of the upper-left corner (x, y)
- The width and height (width, height)
- The background color (fill)
Below we have added two
rect elements as children of
the
svg element to represent the water in the jugs.
Note that the
rect elements precede the
polyline elements
so that the jugs' black outlines are rendered over the blue water.
A
path element represents the outline of a shape that can be
filled or stroked.
A path can be understood by analogy with a pen drawing on paper. The
pen has a current position, which can be changed, and the pen can be
dragged on the paper to create straight or curved lines.
The outline of the shape is specified through the
path
element's
d attribute, which provides
path data in the
form of commands for moving the pen and drawing.
Some path data commands:
- M: start a new path by moving to a given point (no
drawing is done)
- L: draw a line from the current point to a given
point
- Q: draw a curve (quadratic Bezier curve) from the current
point to a given point using another given point as control
- T: draw a curve (quadratic Bezier curve) from the current
point to a given point using the reflection of the
previous command's control point relative to the current
point as control
- Z: Close the path by drawing a straight line
from the current point to the path's initial point
See
the
W3C Path Specification
The example shown below produces a curving blue river on a green
background for the farmer, wolf, goat, and cabbage problem.
The next example depicts waves on the river:
by specifying connected
elliptical arcs in a
path element's path data attribute.
The arc command (
a) requires:
- The two radii of the ellipse describing the arc
- How much the ellipse as a whole is rotated relative to the x
axis
- Two flags combining to indicate which part of the ellipse is
drawn
- The end point of the arc
The path data in the example below begins with an
M command to
move to a start point for the waves path.
Since the
a command is lower case, the end point it
specifies is relative to the start point.
An upper case
A command would specify absolute
coordinates for its end point.
(Later we show how the waves can be rotated to match with
the flow of the river.)
The code below produces the same water jug representation as before,
but:
- In the absence of x and y attributes, the
rectangle is first placed at the origin of the total drawing
area
- The transform attributes specify translations that move
the rectangles to their proper positions
In this example we use a transform to rotate the path representing the
waves of the river in the farmer, wolf, goat, and cabbage problem so
that the waves match the flow of the river.
- The starting point for the path representing the waves is the
origin of the drawing area
- The transform attribute first translates the
waves to an appropriate point in the river, then
- The same transform attribute rotates the waves to
orient with the flow of the river
Using the various SVG animation elements, you can define motion paths,
fade-in or fade-out effects, and objects that grow, shrink, spin or
change color.
We will describe the
animate and
animateMotion elements.
The
animate element is used to animate a single attribute or property
over time.
It is specified as a child element of a graphical element whose
attribute(s) you wish to animate.
The
animate element has attributes for specifying, among other things,
- The name of the attribute of the graphical element animated (attributeName)
- The values the attribute will take on during the animation
(from, to)
- The time and duration of the animation (dur, begin)
In the animation shown to the right, the
rect elements are
animated by changing their
height attributes from zero to a
target value over a duration of 0.5 seconds.
The animation is initiated by clicking a
rect element object.
This event is specified by the
begin attribute. Note:
- This event is not a DOM event, but an SVG animation event
- The event is referred to by "click" (not "onclick")
- The rect element to which the event occurs is described in terms of the
element's id attribute (xWater or yWater)
The code is shown below.
For the purposes of animating water jugs, the example so far is
insufficient, since we want the blue rectangles to grow from the bottom
of the jugs.
We can achieve this effect by rotating each rectangle 180 degrees about
its center — (40,40) for jug X and (40,80) for jug Y.
Note that the rotation point for each rectangle is relative to the
translated coordinate system.
The code below shows such rotations added to the
transform
attribute of the rectangles.
The
animateMotion element animates its parent graphics element by moving
it along a
motion path like the one shown here in black in the middle of the
river in the farmer, wolf, goat, and cabbage problem:
The
animateMotion element has attributes for specifying, among other things,
- The motion path (path)
- The duration of the animated motion (dur)
- How many times to repeat the animation (repeatCount)
- How to orient the graphics element along the motion path (rotate)
In the code below, the
path element representing the river waves
is animated by sending it down the motion path.
Note:
- The river waves path element is defined with a horizontal
orientation with its base centered horizontally on the origin.
This is important for initially aligning the waves along the
motion path.
- The "auto" value for the rotate attribute results
in the waves element being automatically rotated to align with the
motion path's tangent line.
- The motion path could have been given as a value of
the animateMotion element's path attribute.
However, in this case the motion path is defined in its
own path element (id motionPath) and made the value of the
xlink:href attribute of the child
element mpath.
SVG is an XML technology, and the SVG code examples shown so far have
been pure XML.
SVG elements, like ordinary HTML elements, are part of the DOM
(Document Object Model) and thus manipulable by scripting languages.
This section describes how the SVG elements depicting
the problems shown in the
Examples menu item to the left are
manipulated using Javascript.
As of this writing, SVG had not been fully integrated with JQuery, so
the code used will be plain Javascript.
Recall our last Javascript/JQuery implementation of the farmer,
wolf, goat, cabbage and water jug problems, shown below.
The main HTML page
presents the problem's current state by placing state objects'
toString return
values in an HTML
textarea element:
To accommodate graphics, we replace the
textarea element with
a
div container element whose child will be an
appropriate
svg element:
Since
textarea elements are no longer used to display states,
the framework code that set the text area size attributes goes away.
The
textarea elements are replaced by
div elements
containing
svg elements that draw individual states:
- The svg elements are provided by individual state objects
through an svg method
- To carry out animation, the current state object will require the
previous state object, which will be passed to it via
the svg method
These changes are sketched in the framework code shown here:
The new
solve.html and
solve.js files are shown in the
submenu.
We will show the application code's
svg methods after
considering how to create SVG elements using Javascript.
This section shows how to create SVG elements under Javascript control.
Recall the pure XML code below that produces the water jug image to the
right.
To create an
svg element or one of its children, use
the
document object's
createElementNS method.
- The "NS" suffix indicates that an element outside of the
HTML namespace is being created
- The first argument to createElementNS is the namespace
URI
- The second argument is the element name
To give the created element attributes, use the
element's
setAttribute method.
To make an element
e1 a child of another element
e2,
use
e2's
appendChild method.
Here is the HTML and Javascript code that creates the water jug image:
manual-svg.js
Manual creation of SVG elements is tedious and error-prone, so we will
create an SVG element creation utility.
It exploits two features of Javascript:
- We can create objects using the literal "{ . . . }"
syntax
- We can iterate through an object's properties using the
"for (var ... in ...)" syntax
For example, in the code below,
- An object attrs is created whose properties correspond to the
attributes of the polyline element used to draw jug X
- A polyline element is created
- The element's attributes are set by iterating
through attr's properties
Since making SVG elements and setting their attributes is a common
operation, we define a
makeSVG function that takes a tag name
and attributes object as parameters and returns an appropriately
created element object:
make-svg.js
Here is the HTML and Javascript code that creates the previous water
jug image using the
makeSVG utility function:
utility-svg.js
The SVG Document Object Model (DOM) allows registration of event
listeners for SVG graphics elements.
For example, in the 8-puzzle application, the
rect elements
representing 8-puzzle tiles have event handlers that attempt to move
them into the blank space when clicked.
The SVG DOM is similar to the HTML DOM, and event handling is similar:
- Events include click, mousedown, mouseover,
etc.
- The corresponding attribute names
are onclick,
onmousedown,
onmouseover,
etc.
Here is the Javascript code that attaches a click handler to a tile:
The only application domain changes are to the constructor
functions
WaterJugState,
FarmerState,
and
PuzzleState.
- The toString method is no longer needed
- The width and height properties are no longer
needed
- The svg method is added:
- Must create and return an svg element that draws the
current state
- The previous state is passed as an argument for use in
animation