Why will browsers not display my SVG polygon? - svg

I have created an SVG file to display an icon for an open folder.
It consists of a rectangle for the tab and a rectangle for the backleaf of the folder, with the open leaf represented by a polygon.
Image editors display the intended result, but browsers seem to ignore the polygon.
what am I missing?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="folder_icon" xmlns="http://www.w3.org/2000/svg"
width="90" height="60" viewbox="0 0 90 60" preserveAspectRatio="xMidYMid slice"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g width="50%" height="80%">
<g id="g3" fill="#ffee77" stroke="#bb7711" stroke-width="2px" opacity="0.7">
<g id="g2">
<rect x="16%" y="1%" rx="6%" ry="6%" width="30%" height="30%" />
<rect x="1%" y="16%" rx="0%" ry="0%" width="84%" height="82%" />
<polygon points="17% 20%, 90% 20%, 75% 59%, 1% 59%" />
</g>
</g>
</g>
</svg>
The same file converted to a PNG is displayed as intended, but I would prefer to use the scalable graphic.

Related

SVG feImage filter clips stroke - how to stop that?

I'm trying to create a filter for only the stroke of path in SVG, but the feImage keeps getting clipped to what I assume is that bounding box (see green rectangle below in code as bounding box). I've tried setting the filter's x/y and width/height to all sorts of positions/sizes, as seems to be the prevailing advice, but nothing works. x/y just offset the feImage and width/height of greater than 100% has no effect.
I won't know in advance if the stroke or fill is solid or something else (like linearGradient.
The below demonstrates what I'm looking to do - just get the stroke of a shape (regardless of size or fill) and apply a filter to it for all modern browsers.
Notes: FF doesn't even display the left-hand feImage. Chrome clips the left and top. Edge clips all 4 sides.
<html>
<body>
<svg width="960" height="540" >
<rect width="960" height="540" stroke="#385D8A" fill="white" stroke-width="3"/>
<svg name="BoundingBox1" class="rect" x="100" y="100" overflow="visible" fill="none" stroke="#00ff00" stroke-width="1">
<path d="M0,0L121.68,0L121.68,121.68L0,121.68Z" />
</svg>
<!-- BELOW IS MODIFIED "SPEECH" SHAPE. NEED A FILTER ON THE STROKE ONLY. -->
<svg name="Speech-strokeonly" x="100" y="100" overflow="visible" fill="blue" stroke="orange" stroke-width="12" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="strokeOnly" fill="none"/>
<filter id="effs0sp9" color-interpolation-filters="sRGB" x="0" y="0">
<feImage xlink:href="#strokeOnly" />
</filter>
</defs>
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="effs0sp9" filter="url(#effs0sp9)" overflow="visible" />
<text y="160" stroke="black" stroke-width="0.2">this is the one that has undesirable clipping of</text>
<text y="178" stroke="black" stroke-width="0.2">of stroke in Chrome/Edge. Doesn't appear at all in FF</text>
</svg>
<!-- BELOW IS ORIGINAL WITH BOTH FILL AND STROKE -->
<svg name="BoundingBox2" x="400" y="100" overflow="visible" fill="none" stroke="green" stroke-width="1">
<path d="M0,0L121.68,0L121.68,121.68L0,121.68Z" />
</svg>
<svg name="Speech-original" x="400" y="100" overflow="visible" fill="blue" stroke="orange" stroke-width="12">
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="effs0sp9" />
<text y="-22" stroke="black" stroke-width="0.2">this is the original one</text>
<text y="-6" stroke="black" stroke-width="0.2">that I just want the stroke as feImage from</text>
</svg>
</svg>
</body>
</html>
Is there a way to grab the whole stroke of a shape only and use in a filter?

Dynamic svg width/height after applying a stroke

I made an svg with a masked image and applied a stroke to the mask:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%">
<defs>
<g id="path">
<path fill="#ffffff"
d="m380.42 600l -235.11 123.61 44.9 -261.8 -190.21 -185.41 262.87 -38.2 117.56 -238.2 117.56 238.2 262.87 38.2 -190.21 185.41 44.9 261.8 z"/>
</g>
<mask id="image-mask">
<use xlink:href="#path" overflow="visible"/>
</mask>
</defs>
<use xlink:href="#path" overflow="visible" stroke="red" stroke-width="20"/>
<image width="781" height="744" xlink:href="cat3.jpg" mask="url(#image-mask)"/>
</svg>
Unfortunately parts of the stroke get cut off and the result is this:
The top/left part of the border are cut off.
Is there any way to make them visible without modifying the width/height and viewBox by hand?
Like others have said, you could translate the path away from the edge of the SVG. Another option would be to use this technique using clipPath to bring your stroke lines 'inside' the shape rather than outside which is what is causing the lines to be clipped off the edge of the drawing (based on this answer):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="781px" height="744px">
<defs>
<path fill-opacity="0" id="path"
d="m380.42 600l -235.11 123.61 44.9 -261.8 -190.21 -185.41 262.87 -38.2 117.56 -238.2 117.56 238.2 262.87 38.2 -190.21 185.41 44.9 261.8 z"></path>
<clipPath id="clip">
<use xlink:href="#path" />
</clipPath>
</defs>
<image width="781" height="744" xlink:href="cat3.jpg" clip-path="url(#clip)"/>
<use xlink:href="#path" stroke="red" stroke-width="20" clip-path="url(#clip)"/>
</svg>
Also, note that I've brought the image element before use so that the stroke lines are drawn over the image, and applied fill-opacity="0" to the path so the image can be seen through the shape.

Flatten clipped areas in SVG to transparency?

I have this SVG file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<g id="main">
<clipPath id="clip_mask">
<path d="M20.9262,32C18.5189,30.6,16.9,27.9878,16.9,25c0,-4.4735,3.6265,-8.1,8.1,-8.1c2.9878,0,5.6,1.6189,7,4.0262V0L0,0l0,32H20.9262z" fill-rule="evenodd"/>
</clipPath>
<g id="icon" clip-path="url(#clip_mask)">
<g id="transformed_icon" transform="translate(-1 -1)">
<path d="M26.7,30.5H5.3c-0.4418,0,-0.8,-0.3582,-0.8,-0.8V2.3c0,-0.4418,0.3582,-0.8,0.8,-0.8h21.4c0.4418,0,0.8,0.3582,0.8,0.8v27.4C27.5,30.1418,27.1418,30.5,26.7,30.5z" fill="#FFFFFF" stroke="#6D6E71" stroke-width="1" stroke-miterlimit="1"/>
<path d="M8.5,8.5h15M8.5,11.5h15M8.5,14.5h15M8.5,17.5h15M8.5,20.5h15M8.5,23.5h15" fill="none" stroke="#3E79B4" stroke-width="1" stroke-linecap="round" stroke-miterlimit="1"/>
</g>
</g>
<g id="overlay">
<path d="M25,18c-3.866,0,-7,3.134,-7,7c0,3.866,3.134,7,7,7s7,-3.134,7,-7C32,21.134,28.866,18,25,18zM26,29.8c0,0.1105,-0.0895,0.2,-0.2,0.2h-1.6c-0.1105,0,-0.2,-0.0895,-0.2,-0.2v-6.6c0,-0.1105,0.0895,-0.2,0.2,-0.2h1.6c0.1105,0,0.2,0.0895,0.2,0.2V29.8zM26,21.5c0,0.1105,-0.0895,0.2,-0.2,0.2h-1.6c-0.1105,0,-0.2,-0.0895,-0.2,-0.2v-1.3c0,-0.1105,0.0895,-0.2,0.2,-0.2h1.6c0.1105,0,0.2,0.0895,0.2,0.2V21.5z" fill-rule="evenodd" fill="#3E79B4"/>
<path d="M26,20.2c0,-0.1105,-0.0895,-0.2,-0.2,-0.2h-1.6c-0.1105,0,-0.2,0.0895,-0.2,0.2v1.3c0,0.1105,0.0895,0.2,0.2,0.2h1.6c0.1105,0,0.2,-0.0895,0.2,-0.2V20.2z" fill="#FFFFFF"/>
<path d="M26,23.2c0,-0.1105,-0.0895,-0.2,-0.2,-0.2h-1.6c-0.1105,0,-0.2,0.0895,-0.2,0.2v6.6c0,0.1105,0.0895,0.2,0.2,0.2h1.6c0.1105,0,0.2,-0.0895,0.2,-0.2V23.2z" fill="#FFFFFF"/>
</g>
</g>
</svg>
It is an icon with an overlay in the bottom-right corner. There is a clip-gap between the main icon area and the overlay area. This clip-gap is displayed correctly in Affinity Designer 1.5.3.69:
But unfortunately, many other programs don't recognize the clip-gap, so they don't display it. For example, here is a screenshot from LibreOffice Draw:
So, is it possible to "flatten" the clipped area in the SVG to the same background transparency as the icon background? This would make the SVG clip-gap visible and transparent in such incompatible programs and would allow programs which don't support clipped areas in SVG to render the clipped area as transparency.
I've found a practical but cumbersome and time-consuming solution: Since the SVG is displayed correctly in Affinity Designer, I print the SVG in Affinity Designer to a PDF printer driver. Then I reimport the PDF in Affinity Designer and export it as SVG. Then I can import the SVG in a renderer which doesn't support clipping and it is rendered perfectly. It works.
Yes it is possible to re-use a clip shape to make the clipped area transparent using a filter. However, I very much doubt that a renderer that can't handle clipping properly will be able to handle a filter. But here's how you would do that:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
<defs>
<clipPath id="clip_mask">
<path id="original-clip-shape" d="M20.9262,32C18.5189,30.6,16.9,27.9878,16.9,25c0,-4.4735,3.6265,-8.1,8.1,-8.1c2.9878,0,5.6,1.6189,7,4.0262V0L0,0l0,32H20.9262z" fill-rule="evenodd"/>
</clipPath>
<filter id="transparentize">
<feImage xlink:href="#original-clip-shape" x="0" y="0"/>
<feComposite operator="in" in="SourceGraphic"/>
</filter>
</defs>
<g id="main">
<g id="icon" clip-path="url(#clip_mask)">
<g id="filter-layer" filter="url(#transparentize)">
<g id="transformed_icon" transform="translate(-1 -1)">
<path d="M26.7,30.5H5.3c-0.4418,0,-0.8,-0.3582,-0.8,-0.8V2.3c0,-0.4418,0.3582,-0.8,0.8,-0.8h21.4c0.4418,0,0.8,0.3582,0.8,0.8v27.4C27.5,30.1418,27.1418,30.5,26.7,30.5z" fill="#FFFFFF" stroke="#6D6E71" stroke-width="1" stroke-miterlimit="1"/>
<path d="M8.5,8.5h15M8.5,11.5h15M8.5,14.5h15M8.5,17.5h15M8.5,20.5h15M8.5,23.5h15" fill="none" stroke="#3E79B4" stroke-width="1" stroke-linecap="round" stroke-miterlimit="1"/>
</g>
</g>
</g>
<g id="overlay">
<path d="M25,18c-3.866,0,-7,3.134,-7,7c0,3.866,3.134,7,7,7s7,-3.134,7,-7C32,21.134,28.866,18,25,18zM26,29.8c0,0.1105,-0.0895,0.2,-0.2,0.2h-1.6c-0.1105,0,-0.2,-0.0895,-0.2,-0.2v-6.6c0,-0.1105,0.0895,-0.2,0.2,-0.2h1.6c0.1105,0,0.2,0.0895,0.2,0.2V29.8zM26,21.5c0,0.1105,-0.0895,0.2,-0.2,0.2h-1.6c-0.1105,0,-0.2,-0.0895,-0.2,-0.2v-1.3c0,-0.1105,0.0895,-0.2,0.2,-0.2h1.6c0.1105,0,0.2,0.0895,0.2,0.2V21.5z" fill-rule="evenodd" fill="#3E79B4"/>
<path d="M26,20.2c0,-0.1105,-0.0895,-0.2,-0.2,-0.2h-1.6c-0.1105,0,-0.2,0.0895,-0.2,0.2v1.3c0,0.1105,0.0895,0.2,0.2,0.2h1.6c0.1105,0,0.2,-0.0895,0.2,-0.2V20.2z" fill="#FFFFFF"/>
<path d="M26,23.2c0,-0.1105,-0.0895,-0.2,-0.2,-0.2h-1.6c-0.1105,0,-0.2,0.0895,-0.2,0.2v6.6c0,0.1105,0.0895,0.2,0.2,0.2h1.6c0.1105,0,0.2,-0.0895,0.2,-0.2V23.2z" fill="#FFFFFF"/>
</g>
</g>
</svg>
As far as workarounds go, it's hard to debug renderer specific problems without the renderer. But here are some thoughts:
It might support clipping but just not support using the stroke as a clip. You could work around this by using a solid circle as the clip-shape.
it might support masking not clipping. In this case, define a mask that's the inverse of the clip and apply that.
it might not support clipping or masking at all. In that case, you'll have to just draw the original content as if it was being clipped using markers to shape the ends of your paths. (ugh!)

How must this SVG file change to allow FileMaker to alter its color?

I have an SVG file generated by Sketch that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="47px" viewBox="0 0 72 47" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd" stroke-linecap="square">
<g id="Group" transform="translate(4.000000, 3.000000)"
stroke="#000000" stroke-width="9">
<path d="M0.5,39.5 L63.5,39.5" id="Line"></path>
<path d="M0.5,20.5 L63.5,20.5" id="Line-Copy"></path>
<path d="M0.5,1.5 L63.5,1.5" id="Line-Copy-2"></path>
</g>
</g>
</svg>
I'm trying to edit it in a text editor so that when I import it as an icon button, it can be colored by FileMaker.
I have repeatedly read that adding class="fm_fill" is what's required. I've tried adding this to the outside <g> tag, the inside <g> tag and to each of the <path> tags. I've tried removing superfluous attributes, such as the outside <g> tag's stroke and stroke-width attributes. I've tried consolidating the <g> tags and changing the fill attribute in the outside <g> tag. I've also tried removing the <path> id attributes and using self-closing <path> tags.
My test is a simple button with an icon that I first color. Then I add the edited SVG and see if it retains the color. So far I haven't been able to get it to do so.
Assuming you want the horizontal bars to be colored in FileMaker, you need to convert the stroke to a filled path or a rect.
Something like this:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="72px" height="47px" viewBox="0 0 72 47" overflow="inherit" xml:space="preserve">
<title>Group</title>
<desc>Created with Sketch.</desc>
<g id="Page-1">
<g id="Group" transform="translate(4.000000, 3.000000)">
<rect x="-4" y="35" width="72" height="9"/>
<rect x="-4" y="16" width="72" height="9"/>
<rect x="-4" y="-3" width="72" height="9"/>
</g>
</g>
</svg>
You dont "need" to add the class="fm_fill" per se, but adding a raw SVG does not show the icon in the icon selector, just a blank entry.
If you add the class="fm_fill" and a default fill color, you will see the icon in the icon selector in the default fill color, making it much easier to work with.
Like this:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="72px" height="47px" viewBox="0 0 72 47" overflow="inherit" xml:space="preserve">
<title>Group</title>
<desc>Created with Sketch.</desc>
<g id="Page-1">
<g id="Group" class="fm_fill" fill="grey" transform="translate(4.000000, 3.000000)">
<rect x="-4" y="35" width="72" height="9"/>
<rect x="-4" y="16" width="72" height="9"/>
<rect x="-4" y="-3" width="72" height="9"/>
</g>
</g>
</svg>
In the following screenshot, you can see both variants. The left blue icon is just your raw converted icon, then colored blue in FileMaker. It is not visible in the icon selector, it is the blank entry next to the selected icon. The selected red button's icon is colored red in FileMaker and has the class and default fill applied and thus is visible in the icon selector.
Hope this helps.

Masking an SVGPattern

fiIs it possible to Mask an SVGPattern?
I've made the following SVG, but I can't get the mask to work.
Or should I be using clipPath?
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="160px" height="600px" viewBox="0 0 160 600" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="circlePattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" fill="blue" >
<circle cx='4' cy='4' r='4'/>
</pattern>
<clipPath id="clipPath" maskUnits="userSpaceOnUse">
<rect x="0" y="0" width="200" height="100" fill="white" />
</clipPath>
</defs>
<!-- Outline the drawing area in blue -->
<g id="box">
<rect fill="url(#circlePattern)" width="160" height="600" clip-path="url(#clipPath)"/>
</g>
</svg>
UPDATE: (I would like to use this complex path)
I can't seem to use this path to create the mask/clipPath
<path style="fill:#FFFFFF;" d="M9.35,37.5c4.1,2.467,8.566,3.7,13.4,3.7
c7.667,0,13.783-2.05,18.35-6.15c5.066-4.566,7.6-11.167,7.6-19.8c0-5.7-2.367-12.133-7.1-19.3c-4.1-6.267-9.7-12.684-16.8-19.25
c-5.133-4.8-10.383-8.983-15.75-12.55c-2.4-1.6-3.883-2.6-4.45-3c-1.733-1.033-3.267-1.8-4.6-2.3h-0.05c-1.3,0.5-2.8,1.267-4.5,2.3
c-0.633,0.434-2.133,1.417-4.5,2.95c-5.467,3.667-10.867,8-16.2,13c-6.967,6.566-12.467,12.917-16.5,19.05
c-4.633,7.1-6.95,13.467-6.95,19.1c0,8.633,2.534,15.233,7.6,19.8c4.567,4.1,10.684,6.15,18.35,6.15c4.833,0,9.3-1.233,13.4-3.7
c4-2.367,7.1-5.6,9.3-9.7C2.25,31.9,5.383,35.133,9.35,37.5z"/>
Your mask rect has no fill specified so it will use the default which is black i.e. i.e. rgba(0, 0, 0, 1). So the luminance of the mask is 0 everywhere and you see nothing.
If you change the fill on the mask <rect> to fill="white" you'll see the mask act as a clip which would seem to be what you're looking for. Other colours like "orange" or "blue" as they have a luminance which is neither 0 nor 1 will give you an intermediate effect.
clipPaths clip a shape to a boundary. Masks generally modify colours, you can use them to clip by having a white mask but if all you want is to clip something then a clipPath is faster.
clipPaths and masks can contain any graphics element including a path.

Resources