I have the following SVG source code that generates a number of boxes with texts:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20050904/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"> <defs> </defs> <title>Draw</title> <g transform="translate(50,40)"> <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" /> <text text-anchor="middle" x="40">Text</text> </g> <g transform="translate(150,40)"> <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" /> <text text-anchor="middle" x="40">Text 2</text> </g> <g transform="translate(250,40)"> <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" /> <text text-anchor="middle" x="40">Text 3</text> </g> </svg>
As you can see, I repeated the <g></g>
three times to get three such boxes, when SVG has <defs>
and <use>
elements that allow reusing elements using id references instead of repeating their definitions. Something like:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20050904/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"> <defs> <marker style="overflow:visible;fill:inherit;stroke:inherit" id="Arrow1Mend" refX="0.0" refY="0.0" orient="auto"> <path transform="scale(0.4) rotate(180) translate(20,0)" style="fill-rule:evenodd;stroke-width:2.0pt;marker-start:none;" d="M 0.0,-15.0 L -20.5,0.0 L 0.0,15.0 "/> </marker> <line marker-end="url(#Arrow1Mend)" id="systemthread" x1="40" y1="10" x2="40" y2="410" style="stroke: black; stroke-dasharray: 5, 5; stroke-width: 1; "/> </defs> <title>Draw</title> <use xlink:href="#systemthread" transform="translate(50,40)" /> <use xlink:href="#systemthread" transform="translate(150,40)" /> <use xlink:href="#systemthread" transform="translate(250,40)" /> </svg>
Unfortunately I can't do this with the first SVG code since I need the texts to be different for each box, while the <use>
tag simply duplicates 100% what's defined in <defs>
.
Is there any way to use <defs>
and <use>
with some kind of parameters/arguments mechanism like function calls?
There is no such thing as variables in SVG. What you can do is dynamically generate (or modify) an SVG using Javascript.
SVG treats a text element in much the same way that it treats graphical and shape elements. You position text with x and y coordinates and use fill and stroke options to color text the same way you would with a <circle> or <rect> element.
The SVG <defs> element is used to embed definitions that can be reused inside an SVG image. Using the SVG <defs> elements you can group SVG shapes together and reuse them as a single shape. The shapes defined inside the <defs> element will be displayed when you reference it by a <use> element.
To create SVG text that follows a path you use a <textPath> element in combination with a path you define inside <defs> tags. To refer to the path you'll use an xlink:href attribute on the <textPath> . Note: SVG 2.0 is dropping the xlink: and will simply use href to refer to the path.
I was searching for an answer to my own SVG question. Your question helped me solve my answer, so I am answering yours.
.... Read your question more closely. Included TWO code samples
Sample #1. Boxes with text
Sample #2. Arrows with text
Sample 1
<html> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="900"> <defs> <g id="my_box" desc="my rectangle template"> <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" /> </g> </defs> <g transform="translate(50 40)"> <text text-anchor="middle" x="40"> This little box went to market </text> <use xlink:href="#my_box" /> </g> <g transform="translate(150 140)"> <use xlink:href="#my_box" /> <text text-anchor="middle" x="40"> This little box stayed home </text> </g> <g transform="translate(250 240)"> <use xlink:href="#my_box" /> <text text-anchor="middle" x="40"> This little box had roast beef </text> </g> </svg> </html>
Note in sample 1 that the order of the box and text are important.
Sample 2
<html> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="900"> <defs> <g id="arrow" desc="arrow with a long dashed tail"> <marker style="overflow:visible;fill:inherit;stroke:inherit" id="Arrow1Mend" refX="0.0" refY="0.0" orient="auto"> <path transform="scale(0.4) rotate(180) translate(20,0)" style="fill-rule:evenodd;stroke-width:2.0pt;marker-start:none;" d="M 0.0,-15.0 L -20.5,0.0 L 0.0,15.0 " desc="The actual commands to draw the arrow head" /> </marker> <line transform="translate(0 -450)" marker-end="url(#Arrow1Mend)" x1="40" y1="10" x2="40" y2="410" style="stroke: black; stroke-dasharray: 5, 5; stroke-width: 1; " desc="This is the tail of the 'arrow'" /> </g> </defs> <g transform="translate(100 450)"> <text> Text BEFORE xlink </text> <use xlink:href="#arrow" /> </g> <g transform="translate(200 550)"> <use xlink:href="#arrow" /> <text> More to say </text> </g> <g transform="translate(300 650)"> <use xlink:href="#arrow" /> <text> The last word </text> </g> <g transform="translate(400 750)"> <use xlink:href="#arrow" /> <text> Text AFTER xlink </text> </g> </svg> </html>
A way to achieve this with the current svg recommendation is not known to me.
But there is a working draft for a svg 2.0 module, see: SVG Referenced Parameter Variables. The example with the flowers there is exactly what you are looking for I suppose! But then you probably have to wait until june 2010 or even longer until this is a W3C recommendation and supported by clients I assume.
For now you could probably solve it with scripting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With