I'm working with an SVG element that should look something like this: (sorry that I have to post this as a link instead of as a picture, but as a new user I didn't have permissions to post images)
A border with rounded corners in the middle of a page, but where the the border is removed where header/footer is to be inserted. User-specified text is to be inserted into header, footer and into the frame itself. The rectangle is painted on top of another background (a picture, another rectangle with a color, etc.). I need to find a way to keep the original background, paint only parts of the border and place the text on top of the original background.
I have come up with this solution:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 620 1100" preserveAspectRatio="xMidYMid meet">
<defs>
<!--Define some texts-->
<text id="text1" x="90" y="100" style="text-anchor:start;font-size:30px;">THIS IS MY HEADER</text>
<text id="text2" x="525" y="1010" style="text-anchor:end;font-size:30px;">MY TEXT HERE</text>
<mask id="Mask1">
<!--draw the entire screen-->
<rect x="0" y="0" width="620" height="1100" style="fill:white;" />
<!--Mask out the two rectangles where text is to be placed-->
<rect x="300" y="980" width="350" height="50" style="fill:black;" />
<rect x="90" y="90" width="350" height="40" style="fill:black;" />
</mask>
</defs>
<!--The original background (here a rect with a fill color, but could also be an image)-->
<rect x="0" y="0" width="620" height="1100" style="fill:#f0ffb6"/>
<!--Draw the rectangle but applying the mask-->
<rect x="100" y="100" rx="20" ry="20" width="420" height="900" mask="url(#Mask1)" style="fill:none;stroke:green;stroke-width:5"/>
<!--Draw the text-->
<use xlink:href="#text1" fill="black" stroke="black" stroke-width="1" />
<use xlink:href="#text2" fill="black" stroke="black" stroke-width="1" />
<text x="200" y="200">This text goes into the border</text>
</svg>
My problem now is that the last two rects in the mask (rectangles where not to draw the border) must have a static width. If the user changes the text width, the user also needs to calculate a new with of the text and update these two rectangles.
Is there a way to mask out a block the exact same width as the text itself and skip the rectangles in the mask. Or is this the only way of creating such a mask? If anybody "out there" has a better and more intuitive way of achieving this layout, I'd be more than interested in hearing from you.
Thanks for your help.
"Removing the background" of svg text without scripting can be done using svg filters.
For example:
Which can be used by the text like this:
This will adapt to the string width automatically. If you need some padding you can tweak the x,y,width,height attributes on the filter element.
Hmm, thinking of this again, this might not be what you wanted exactly. But it's possible to adapt the above. Here's your file with this solution:
I believe a simple way to affect this is to use the user's text as a luminance mask with a big stroke-width set & a black stroke. Next, place the text normally over the masked border.
You could use the SVG DOM. Calling getBBox on the
<use>
elements will give you the bounding box of the text and you could then set the mask's rectangles dimensions based on that. Giving the rects id attributes will allow you to reference them and set their dimensions.As an aside, I'm not sure why you are drawing the text with
<use>
rather than using elements directly.