HTML and CSS Reference
In-Depth Information
return p.matrixTransform(m.inverse());
}
});
Q.svgOnly = function() {
Q.Stage = Q.SVGStage;
Q.setup = Q.setupSVG;
Q.Sprite = Q.SVGSprite;
return Q;
};
chapter, replaces the non-SVG classes with their SVG counterparts for easier access.
The
init
,
insert
, and
destroy
methods should look similar to those from
Q.DOMStage
. The
init
method is responsible for creating the
<svg>
child element and adding it to the primary
Q.svg
object. The
insert
method augments the inherited method by calling
appendChild
to add the element to the stage's
<svg>
tag. Finally,
destroy
ensures the stage's
<svg>
tag is cleaned up when the stage is removed.
More interesting are the
viewport
,
centerOn
, and
setViewBox
methods. These allow you to use the
stage's
<svg>
element's
viewBox
like a camera, panning by calling
centerOn
and zooming in and out by
setting the width and height of the
viewBox
by calling
viewport
. The
viewport
method is also smart
enough to check if the user has called
centerOn
previously; if so it uses the stored
cx
and
cy
coordinates to
re-center the screen after it has reset the
viewBox
.
Finally, the
browserToWorld
method deserves some explanation. To determine where in the SVG world
the user has touched or clicked, you need to transform that event's pixel position to the corresponding position
inside of the world. This is made more difficult because the
viewBox
has been set and so the SVG element
may only be partially zoomed in depending on the aspect ratio of the
viewBox
compared to the aspect ratio
of the screen (imagine a portrait shaped
viewBox
on a landscape turned device—figuring out the pixel size of
viewBox
will take some doing).
All these complications mean that figuring out a priori of the SVG location of an event given the event's pixel
location on the screen is a huge hassle. Luckily, the SVG spec provides a method that gets you halfway there.
getScreenCTM
returns the transformation matrix that goes the other way: from SVG units to screen units.
However, with a little bit of matrix math, you can use the inverse of that matrix by calling
m.inverse()
to
go the other way: from screen to SVG units.
Testing the SVG Class
With all this SVG engine code written, it's time to render something on the screen using SVG. The first step,
as usual, is to create a template HTML file that loads the necessary JavaScript files. Create a file called
can-
non.html
, and add the code in
Listing 14-7
.
Listing 14-7:
cannon.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"