Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Design

  • Print
  • + Share This
From the author of

Creating a Plug-In Component and Making It Mobile

I pointed out to you earlier that the Adobe SVG Viewer does not now support the import of external SVG images using the <image> element. However, after the viewer has that functionality, you can add a whole new dimension to the reuse of code. Reusing code as separate files in some settings makes lots of sense.

Most of this article has been pretty abstract, so take a look at a practical issue that arises when you are trying to make an SVG visual component fully reusable.

One advantage of using nested <svg> elements—whether in a single document or using the <image> element to import an external SVG file or visual component—is the ability a separate <svg> element gives you to reposition a complex graphic on a Web page.

Consider the following adaptation of a simple logo. In Listing 2, you can see that I have used a nested <svg> element to contain the main rectangle, the group of lines, and the text. That graphic can be moved around the page—but in only one dimension. You can move the graphic horizontally within another <svg> element, but if you want to move it vertically, you need to amend each y attribute. Although that's not a complex task, with just a little more planning, it is an avoidable one.

Listing 2 (RectLinesLogo05.svg)

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
   "http://www.w3.org/TR/2001/PR-SVG-20010719/
   DTD/svg10.dtd">
<svg>
<defs>
<linearGradient id="MyGreenGradient" gradientUnits="userSpaceOnUse"
x1="150" y1="150" x2="220" y2="50" >
<stop offset="10%" style="stop-color:#DDFFDD; stop-opacity:0.8"/>
<stop offset="50%" style="stop-color:#99FF99; "/>
<stop offset="75%" style="stop-color:#DDFFDD"/>
</linearGradient>
<filter id="CombinedDropShadow" width="140%" y="-20%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="0.5" result="ShadowOut" />
<feOffset in="ShadowOut" dx="2" dy="1" result="ShadowOnly" />
<feMerge>
 <feMergeNode in="ShadowOnly"/>
 <feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<svg x="30">
<rect x="5" y="55" width="300" height="80" rx="10" ry="10" style="fill:white;
filter:url(#CombinedDropShadow)"/>
<rect x="10" y="60" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="65" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="70" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="75" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="80" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="85" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="90" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="95" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="100" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="105" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="110" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="115" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="120" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="125" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="130" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<text x="-300" y="110" style="font-family:'Times New Roman', serif; font-size:48;
stroke:#339933; fill:white; filter:url(#CombinedDropShadow)">
<animate begin="1s" dur="2s" attributeName="x" from="-300" to="30" fill="freeze"/>
SVGenius.com
</text>
</svg>
</svg>

If you look at the y attribute of the nested <svg> element and the other elements in this code, you see that you can subtract 50 from each y attribute within the nested <svg> element and add 50 to the y attribute of the nested <svg> element, as shown here:

<svg x="30" y="50">
<rect x="5" y="5" width="300" height="80" rx="10" ry="10" style="fill:white;
filter:url(#CombinedDropShadow)"/>
<rect x="10" y="10" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="15" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="20" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="25" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="30" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="35" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="40" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="45" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="50" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="55" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="60" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="65" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="70" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="75" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<rect x="10" y="80" width="295" height="2" style="fill:url(#MyGreenGradient);
stroke:none;"/>
<text x="-300" y="60" style="font-family:'Times New Roman', serif; font-size:48;
stroke:#339933; fill:white; filter:url(#CombinedDropShadow)">
<animate begin="1s" dur="2s" attributeName="x" from="-300" to="30" fill="freeze"/>
SVGenius.com
</text>
</svg>

After that is done, moving the graphic either vertically or horizontally is a straightforward process. You simply modify the value of the y or x attribute of the nested <svg> element, and the whole graphic can be relocated and the relative positions, including the animation, maintained.

As a generalized way of stating this concept, making the x and y attributes of elements within a potential visual component as close to zero as possible is helpful. Sometimes you might want to consciously leave a margin for some purpose, but the closer to zero the positioning attributes of the contained elements, the fuller control of positioning you have by using the x and y attributes of the outer <svg> element of the visual component. When that outer <svg> element becomes a nested <svg> element, positioning of the entire visual component is straightforward, depending simply on adjusting its x and y attributes.

  • + Share This
  • 🔖 Save To Your Account