Sideway
output.to from Sideway
Draft for Information Only

Content

SVG Basics
 Operations: Grouping, Reusing, Scaling, Translation and Rotation
   Grouping
   Inheriting attributes from the group
   <use>
 Putting SVG in a web page
 Sources and References

SVG Basics

Operations: Grouping, Reusing, Scaling, Translation and Rotation

Thus far we have had the opportunity to see much similarity between SVG and HTML: two markup languages with tags and attributes that modify the way those tags look. Where SVG starts to look less like a markup language and more like a programming environment is in its ability to reuse and modify its own content (within its own system). That is, elements can be contained in other elements in such a way that containers modify the appearance of the elements inside them. Specifically we can group and reuse elements in ways that simplify maintenance of code and which shorten the overall length of our documents. The <use> (reuse) and <g> (or group) tags bear similarity to the variables and objects encountered in programming languages. And while those tags can be exemplified with examples drawing just on the "simple objects" discussed earlier in this chapter, their utility becomes, perhaps more pronounced once we have the abilities to transform objects using the isometric planar primitive operations of translation, rotation (including reflection), and scaling.

Grouping

Once we start taking the things we have built and moving them around on the screen, it is natural to want some of them to move together as a unit. The group tag, or <g>, is a tag that merely serves to put elements together, so that they might share a common set of transformations or other attributes.

Consider the simple figure drawn below with its code as shown:

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <rect x='120' y='100' width='100' height='20' fill='#888' />
   <rect x='120' y='160' width='100' height='20' fill='#888' />
   <ellipse cx='170' cy='140' rx='30' ry='100' fill='#bbb' />
   <rect x='120' y='130' width='100' height='20' fill='#888' />
</svg>    
HTML Web Page Embedded Output:

If we wanted to make three copies of it all side by side as in the following illustration, then we could perform two editing replacements: first change all the x="100" statements to x="-20" and the cx="150" to cx="30", then, in the next copy, change the x="100" to x="220"and cx="150" to cx="270". The four statements turn into 12 statements, 8 of which have simple editing applied to effect the change.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <rect x='0'y='100' width='100' height='20' fill='#888' />
   <rect x='0' y='160' width='100' height='20' fill='#888' />
   <ellipse cx='50' cy='140' rx='30' ry='100' fill='#bbb' />
   <rect x='0'y='130' width='100' height='20' fill='#888' />
   <rect x='120' y='100' width='100' height='20' fill='#888' />
   <rect x='120' y='160' width='100' height='20' fill='#888' />
   <ellipse cx='170' cy='140' rx='30' ry='100' fill='#bbb' />
   <rect x='120' y='130' width='100' height='20' fill='#888' />
   <rect x='240' y='100' width='100' height='20' fill='#888' />
   <rect x='240' y='160' width='100' height='20' fill='#888' />
   <ellipse cx='290' cy='140' rx='30' ry='100' fill='#bbb' />
   <rect x='240' y='130' width='100' height='20' fill='#888' />
</svg>    
HTML Web Page Embedded Output:

If the object being replicated were a complex path, the amount of arithmetic we would have to do might become annoying. Fortunately, the <g> tag saves us some work, since instead we might just duplicate the code twice, placing each copy inside groups: <g>copy1</g>, <g>copy2</g> and then apply a separate transform to each as shown:

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <rect x='120' y='100' width='100' height='20' fill='#888' />
   <rect x='120' y='160' width='100' height='20' fill='#888' />
   <ellipse cx='170' cy='140' rx='30' ry='100' fill='#bbb' />
   <rect x='120' y='130' width='100' height='20' fill='#888' />
   <g transform = translate(-120,0)>
       <rect x='120' y='100' width='100' height='20' fill='#888' />
       <rect x='120' y='160' width='100' height='20' fill='#888' />
       <ellipse cx='170' cy='140' rx='30' ry='100' fill='#bbb' />
       <rect x='120' y='130' width='100' height='20' fill='#888' />
   </g>
   <g transform = translate(120,0)>
       <rect x='120' y='100' width='100' height='20' fill='#888' />
       <rect x='120' y='160' width='100' height='20' fill='#888' />
       <ellipse cx='170' cy='140' rx='30' ry='100' fill='#bbb' />
       <rect x='120' y='130' width='100' height='20' fill='#888' />
   </g>
</svg>    
HTML Web Page Embedded Output:

We end up with a few more characters, but considerably less cognitive effort and time will be expended.

Inheriting attributes from the group

The group tag may also be used to define other attributes of elements within the group, such as the color used to fill some or all objects. If an object has an attribute defined as

someNamedAttribute="inherit"

then it will take whatever value of that attribute its containing group has been assigned.

In the following illustration, code is reused more effectively than manually editing each of the six rectangles, by letting the rectangles inherit their fill color from their groups.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <g fill='black'>
       <rect x='100' y='100' width='100' height='20' fill='inherit'/>
       <rect x='100' y='160' width='100' height='20' fill='inherit' />
       <ellipse cx='150' cy='140' rx='30' ry='100' fill='#777' />
       <rect x='100' y='130' width='100' height='20' fill='inherit' />
   </g>
   <g transform='translate(120,0)' fill='#bbb'>
       <rect x='100' y='100' width='100' height='20' fill='inherit' />
       <rect x='100' y='160' width='100' height='20' fill='inherit' />
       <ellipse cx='150' cy='140' rx='30' ry='100' fill='#777' />
       <rect x='100' y='130' width='100' height='20' fill='inherit' />
   </g>
</svg>    
HTML Web Page Embedded Output:

In the next section we accomplish the same result but with considerably less code, using the <use> tag.

<use>

One more important way to reuse code, and, hence, simplify the process of adjusting it later on, is the <use> tag. This allows us to define an object, give it an identifier (an "id" attribute) and then to reuse that object later on, without having to copy all of its code. Working again with the example used earlier, we will show one more way to not only reuse code, but to simplify it and reduce the overall number of characters.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <g fill='black'>
   <g id='G'>
       <rect x='100' y='100' width='100' height='20' fill='inherit' />
       <rect x='100' y='160' width='100' height='20' fill='inherit' />
       <ellipse cx='150' cy='140' rx='30' ry='100' fill='#777' />
       <rect x='100' y='130' width='100' height='20' fill='inherit' />
   </g></g>
   <use href='#G' transform='translate(120,0)' fill='#bbb' />
</svg>    
HTML Web Page Embedded Output:

Above we have built the three rectangles and the oval, with the fill color of the rectangles left undefined: that is, to be inherited from their group. We then put all four objects inside a group with id="G". That group can then be referred to within a <use> tag, by simply typing:

xlink:href="G"

This (a hypertext link to the object in this document known as "G")10 takes all the code within the object "G" and, as a part of the <use>, builds another instance. In this case we have applied a transform to the new instance to slide it to the left, but we have also defined fill="#bbb" so that all objects having the fill="inherit" property (in this case, just the three rectangles) are colored light grey. In the meantime, we must still assign a color to the rectangles of the first instance, so I've wrapped the group "G" in yet another container and given that container its own fill color (black).

Another example may help illustrate the compactness and utility that <use> can bring to our code.

Step 1: We begin with an ellipse and two copies of it, rotated either 30 or 60 degrees.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <g stroke='black' stroke-width='2' fill='none' >
       <ellipse id='g1' cx='100' cy='100' rx='75' ry='40' />
       <use xlink:href='#g1' transform='rotate(30 100 100)'/>
       <use xlink:href='#g1' transform='rotate(60 100 100)'/>
   </g>
</svg>    
HTML Web Page Embedded Output:

Step 2: We then take the three ellipses, put them in a group, with id="g2"; and then reuse that group, with a new rotation of 90 degrees applied to the whole group. This means we will now have a whole flower consisting of six ellipses (each with different rotations: 0,30,60,90,120 and 150 degrees). Since we intend to also reuse this flower, we'll wrap it together in its own group with id="g3" and let the stroke and fill properties go up to the outermost container, since all things inside share those attribute values.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='250' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <g id='g3' stroke='black' stroke-width='2' fill='none'>
       <g id='g2'>
           <ellipse id='g1' cx='100' cy='100' rx='75' ry='40' />
           <use href='#g1' transform='rotate(30 100 100)'/>
           <use href='#g1' transform='rotate(60 100 100)'/>
       </g>
       <use href='#g2' transform='rotate(90 100 100)'/>
   </g>
</svg>    
HTML Web Page Embedded Output:

Step 3. Having grouped the six ellipses together into the object "g3", we will now reuse that object three more times, each with a different color and position. To do this we let the stroke property move up to a new top level that contains the first flower, allowing the inner object "g3" to have its own stroke undefined. Each of the <use> tags which reuse "g3" can then impart its own stroke color.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg width='550' height='260' version='1.1'  xmlns='http://www.w3.org/2000/svg'>
   <g stroke='black'>
       <g id='g3' fill='none' stroke-width='2'>
           <g id='g2'>
               <ellipse id='g1' cx='100' cy='100' rx='75' ry='40'/>
               <use href='#g1' transform='rotate(30 100 100)'/>
               <use href='#g1' transform='rotate(60 100 100)'/>
           </g>
           <use href='#g2' transform='rotate(90 100 100)'/>
       </g>
   </g>
   <g stroke='blue' transform='translate(80,0)'>
       <g id='g3' fill='none' stroke-width='2'>
           <g id='g2'>
               <ellipse id='g1' cx='100' cy='100' rx='75' ry='40'/>
               <use href='#g1' transform='rotate(30 100 100)'/>
               <use href='#g1' transform='rotate(60 100 100)'/>
           </g>
           <use href='#g2' transform='rotate(90 100 100)'/>
       </g>
   </g>
   <g stroke='red' transform='translate(0,80)'>
       <g id='g3' fill='none' stroke-width='2'>
           <g id='g2'>
               <ellipse id='g1' cx='100' cy='100' rx='75' ry='40'/>
               <use href='#g1' transform='rotate(30 100 100)'/>
               <use href='#g1' transform='rotate(60 100 100)'/>
           </g>
           <use href='#g2' transform='rotate(90 100 100)'/>
       </g>
   </g>
   <g stroke='green' transform='translate(80,80)'>
       <g id='g3' fill='none' stroke-width='2'>
           <g id='g2'>
               <ellipse id='g1' cx='100' cy='100' rx='75' ry='40'/>
               <use href='#g1' transform='rotate(30 100 100)'/>
               <use href='#g1' transform='rotate(60 100 100)'/>
           </g>
           <use href='#g2' transform='rotate(90 100 100)'/>
       </g>
   </g>
</svg>    
HTML Web Page Embedded Output:

Putting SVG in a web page

Chapter 6 discusses the issue of various HTML containers that can be used to display SVG content in an HTML web page. We might use <iframe>, <embed> <object> or even <img> and each will work to some extent in modern versions of the five browsers: Firefox, ASV+Internet Explorer, Opera, Chrome, and Safari. While <object> would be the preferred approach from the perspective of compliance with W3C standards, some problems exist with both it and the <iframe> that make "<embed>" a persistent practical recommendation from some experts11. Others point out that this is only for consistency with IE and the ASV plugin and that <object> is preferable.

Later, in Chapter 6, concerning SVG and HTML, ways of using the more "standards-compliant" <object> tag for SVG content in HTML, as well as "in-line" SVG will be discussed. My own experiments (see, for example, here and here) together with certain other factors, lead me to use <embed> as the vehicle of choice, though this issue will be discussed in more detail later.

Given an SVG document, saved with a .svg extension, it may be placed in a web page using an <embed> as follows:

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg xmlns='http://www.w3.org/2000/svg'>
   <circle r='50'/>
</svg>    
HTML Web Page Embedded Output:
Page:
SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<strong>
   Here is a web page with an <br> SVG file embedded in it</strong><br>
   <iframe src='http://sideway.to/img/1/circle_001a.svg' height='50' />
    
HTML Web Page Embedded Output:

This is much as it should appear in any of Firefox, ASV+Internet Explorer, Safari, Opera or Chrome. It is a sort of simplest case, in that fewer keystrokes in the SVG file will probably not do anything in at least one of the browsers.

Notes:

  • The xmlns variable, which in essence instructs the browser how to interpret the dialect of XML known as SVG is required by the standard though some browsers may allow us to leave out those 34 characters. Some browsers do require it so it is best to get accustomed to including it.
  • The height="50" attribute in the HTML document may be required in some browsers for the <embed> to be visible.
  • That the circle appears as a quarter-circle rather than a whole circle derives from the fact that no cx or cy is specified; by default, both are assumed to be zero.
  • An additional variable should be set if one uses any xlink:href attributes in one's document. This was mentioned in this chapter when discussed the <image> tag, but many SVG authors include an attribute value which reads xmlns:xlink="http://www.w3.org/1999/xlink" in their opening <svg> tag. This allows the XML definition of compound attributes (beginning with "xlink" as in xlink:href="url(#r)") to be interpreted properly by the browser.

A natural question emerges at this point: how might we adjust the <embed> so that the SVG content fits properly? There are several issues associated with this question.

If we as programmers know how big the content in the SVG file is (a sort of smallest rectangle starting at the origin which contains all the drawn objects), then we simply find that amount of real estate in our web page and allocate it to the SVG object through setting attributes on the <embed>. In the example below, we fail to allocate enough space for the <embed> and it appears truncated on the page.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg xmlns='http://www.w3.org/2000/svg'>
   <circle r='50' cx='100' cy='100' />
</svg>    
HTML Web Page Embedded Output:
Page:
SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<body  style='height:200'><strong>
   Here is a web page with an <br> SVG file embedded in it</strong><br>
   <iframe src='http://sideway.to/img/1/circle_001b.svg' height='100' width='100' style='border:solid #999 1'></iframe>
   And more <br>just for good measure.
    
HTML Web Page Embedded Output:

Increasing the size of the <embed> allows the graphic to fit in the viewing area. But in this case we had to take what we knew of the radius of the circle and add that to its center to calculate an appropriate size for the <embed>. We might prefer a technique which adjusts to the graphic more automatically. The following accomplishes this by establishing a "viewBox": a relativized coordinate system within the SVG. By centering the circle relative to the SVG space through the viewBox (which is, in this case, a 200 x 200 pixel rectangle) and then letting the height and width attributes of the SVG expand to 100% of the available space, then, the SVG will expand or contract as needed to fit the <embed>. More on the viewBox attribute will be discussed in the section on zooming and panning in a later chapter.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 200 200'>
   <circle r='50' cx='100' cy='100' />
</svg>    
HTML Web Page Embedded Output:
Page:
SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<body  style='height:200'><strong>
   Here is a web page with an <br> SVG file embedded in it</strong><br>
   <iframe src='http://sideway.to/img/1/circle_001c.svg' height='100' width='100' style='border:solid #999 1'></iframe>
   And more <br>just for good measure.
    
HTML Web Page Embedded Output:

The above solution scales nicely, in the sense that if we define the size of the embed as a percentage of the browser window then the SVG will expand or contract in a more customized way.

SVG Code Input:
<?xml version="1.0" standalone="no"?>

    
<body  style='height:200'><strong>
   Here is a web page with an <br> SVG file embedded in it</strong><br>
   <iframe src='http://sideway.to/img/1/circle_001c.svg' height='50%' width='100%' style='border:solid #999 1'></iframe>
   And more <br>just for good measure.
    
HTML Web Page Embedded Output:

If we wish to use JavaScript to interact with the SVG document (though these topics are the subject of much to come in later chapters), then we may wish to know the size of the SVG object (if it is specified in absolute terms). To determine its width and height we might use

document.embeds[0].clientWidth
document.embeds[0].clientHeight.

Since users of Internet Explorer and some older browsers will need the Adobe SVG Viewer plugin, it makes good sense to include the following attribute in one's embed tag:

pluginspage="http://www.adobe.com/svg/viewer/install/"

This allows the user to find out what they need in order to actually see the SVG should the browser not be SVG capable.

If one is interested in compliance even with very old browsers (e.g. Netscape Navigator 4 or older) the SVG Wiki12 suggests wrapping an <object> around an <embed> as follows:

<object data="sample.svgz" type="image/svg+xml" width="400" height="300">
<embed src="/sample.svgz" type="image/svg+xml" width="400" height="300" />
</object>

What does seem to work for both ASV+Internet Explorer and other browsers is the following:

<object id="E" type="image/svg+xml" data="ovals.svg" width="320" height="240">
<param name="src" value="ovals.svg">
</object>

Again, while it seems that the browser developers are beginning to converge on workable solutions to these things, the future may see the use of <embed> decline as support for <object> becomes stronger, consistent with published standards. However, with the HTML standard under current revision (<embed> is in the current HTML5 draft) and with alternatives to the Adobe plugin likely to emerge it is difficult to see how this particular microfuture may develop.

Using events within either HTML or SVG to send messages to the other's scripts and DOM is covered in detail later.

Sources and References

https://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#read_book

©sideway

ID: 211200009 Last Updated: 12/9/2021 Revision: 0 Ref:

close

References

  1. http://www.w3.org/TR/1999/REC-html401-1999, 1999, HTML 4.01 Specification: W3C Recommendation, updated 24 December 1999
close

Latest Updated LinksValid XHTML 1.0 Transitional Valid CSS!Nu Html Checker Firefox53 Chromena IExplorerna
IMAGE

Home 5

Business

Management

HBR 3

Information

Recreation

Hobbies 8

Culture

Chinese 1097

English 339

Reference 79

Computer

Hardware 249

Software

Application 213

Digitization 32

Latex 52

Manim 205

KB 1

Numeric 19

Programming

Web 289

Unicode 504

HTML 66

CSS 65

SVG 46

ASP.NET 270

OS 429

DeskTop 7

Python 72

Knowledge

Mathematics

Formulas 8

Algebra 84

Number Theory 206

Trigonometry 31

Geometry 34

Coordinate Geometry 2

Calculus 67

Complex Analysis 21

Engineering

Tables 8

Mechanical

Mechanics 1

Rigid Bodies

Statics 92

Dynamics 37

Fluid 5

Fluid Kinematics 5

Control

Process Control 1

Acoustics 19

FiniteElement 2

Natural Sciences

Matter 1

Electric 27

Biology 1

Geography 1


Copyright © 2000-2024 Sideway . All rights reserved Disclaimers last modified on 06 September 2019