SVG feImage filter clips stroke - how to stop that? - svg

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?

Related

SVG element with clippath prevents events on underlying element

Edit: Maybe I need to test my assumption...
Is there a way to render svg so an element underlying another element can receive events?
The red circle does not respond to its hover event where it is under the clipped circle.
The rectangle iindicates the masked and clipped area of the green circle.
I want the visible red and green areas to both receive pointer events.
How would I get the whole red circle to respond - It has to underly the green circle.
Fiddle
<svg id="svg_wrp" width="600" height="600" style='z-index:2'>
<defs>
<mask id="green_mask">
<circle cx="300" cy="300" r="200" fill="#fff"></circle>
<rect x="100" y="50" width="400" height="200" fill="#000"></rect>
</mask>
<clipPath id="green_clip">
<rect x="100" y="50" width="400" height="200" fill='#000'></rect>
</clipPath>
</defs>
<!-- Following for reference only -->
<rect x="100" y="50" width="400" height="200" stroke="#080" fill="none"></rect>
<circle cx="300" cy="300" r="200" fill="rgba(0 0 255 /.2)" stroke="#080"></circle>
<!-- Above for reference only -->
<g>
<circle cx="300" cy="50" r="100" fill="rgba(255 0 0 /1)" class="hover_it" ></circle>
<!-- Following circle will have top part hidden, but mask does not prevent events -->
<circle id="green_hide_area"
cx="300" cy="300" r="200" fill="rgba(0 255 0 /1)" class="hover_it" mask="url(#green_mask)" ></circle>
</g>
<g>
<!-- Following circle will prevent events -->
<circle id="green_event_stop"
cx="300" cy="300" r="200" fill="transparent" clip-path="url(#green_clip)" ></circle>
</g>
</svg>
.hover_it{opacity:.5}
.hover_it:hover{opacity:1}

How to merge two svg flile

I have two files(svg) from get font-awesome
1 Icon search
https://fontawesome.com/icons/search?style=solid
2 Icon desktop
https://fontawesome.com/icons/desktop?style=solid
I would like to get finish result like
I'm sorry, I can't use Adobe Illustrator
Thank you in advance your diligence
Im putting both paths (the computer #cp and the magnifying glass) in the same svg element. Please note that the magnifying glass is a symbol and has it's own viewBox attribute. This will allow me to resize it and position it as needed by using a <use> element with a position (x, y) and a size (width):
<use xlink:href="#mg" fill="red" width="300" x="400" y="100" stroke-width="30" stroke="white" paint-order = "stroke fill" />
I hope you'll find this useful:
<svg viewBox="0 0 700 540" >
<defs>
<symbol viewBox="-20 0 500 438" id="mg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M287.686,317.613c-44.246,32.716-92.632,44.711-145.867,34.022
c-44.507-8.937-80.279-32.364-107.23-68.768C-17.896,211.978-9.703,111.877,52.721,50.913
c65.372-63.843,167.875-67.842,237.902-10.879c64.849,52.75,93.084,159.289,27.631,247.105c4.34,0,8.222,0.143,12.089-0.031
c6.949-0.312,12.7,2.262,17.505,7.059c27.479,27.436,54.99,54.837,82.342,82.398c10.109,10.187,9.872,21.971-0.188,32.144
c-7.265,7.347-14.526,14.699-21.934,21.901c-9.676,9.407-20.949,9.446-30.493-0.055c-27.99-27.865-55.854-55.857-83.824-83.743
c-5.25-5.234-6.842-11.599-6.585-18.683C287.279,324.973,287.475,321.819,287.686,317.613z
M68.576,177.429c-0.658-58.105,47.084-109.266,109.23-109.212
c60.523,0.052,109.069,48.696,109.216,109.302c0.145,60.339-48.154,109.597-109.557,109.436
C115.029,286.791,67.692,235.734,68.576,177.429z"/>
</symbol>
</defs>
<g id="cp">
<path fill-rule="evenodd" d="M355.128,397.23c4.431,13.312,8.741,26.191,12.992,39.09
c0.933,2.829,3.232,1.861,5.027,1.868c19.163,0.074,38.327-0.067,57.488,0.113c11.443,0.107,20.518,9.763,20.256,21.033
c-0.233,10.074-8.367,18.81-18.422,19.729c-1.655,0.151-3.329,0.136-4.994,0.136c-75.652,0.009-151.304-0.029-226.955,0.067
c-8.242,0.011-15.168-2.292-19.817-9.298c-4.163-6.274-4.849-13.108-1.293-19.912c3.73-7.136,9.618-11.604,17.847-11.695
c18.994-0.211,37.993-0.229,56.985,0.009c4.068,0.051,5.775-1.184,6.953-5.021c3.267-10.639,6.842-21.191,10.627-31.657
c1.416-3.917,0.533-4.573-3.4-4.564c-52.822,0.118-105.646,0.12-158.468,0.051c-18.57-0.024-32.642-9.713-39.553-26.76
c-2.249-5.548-2.435-11.332-2.434-17.184c0.015-49.49,0.002-98.98,0.003-148.47c0.001-40.492-0.057-80.984,0.044-121.476
c0.046-18.598,10.123-32.75,27.482-39.483c5.455-2.116,11.1-2.012,16.745-2.013c94.647-0.024,189.296-0.016,283.943-0.012
c40.658,0.002,81.319,0.241,121.975-0.085c18.796-0.151,33.316,10.927,39.614,26.602c2.225,5.539,2.468,11.321,2.466,17.178
c-0.024,58.322-0.019,116.644-0.019,174.965c-0.001,30.827-0.705,61.676,0.232,92.475c0.729,23.897-17.471,44.839-44.371,44.501
c-51.481-0.646-102.977-0.188-154.466-0.187C359.634,397.23,357.65,397.23,355.128,397.23z
M314.081,96.229c61.994,0,123.988,0.045,185.981-0.096
c4.433-0.01,5.834,0.936,5.824,5.659c-0.16,78.492-0.163,156.984,0.005,235.477c0.01,4.762-1.452,5.607-5.818,5.604
c-123.987-0.112-247.976-0.114-371.963-0.003c-4.371,0.004-5.832-0.848-5.821-5.604c0.166-78.491,0.163-156.984,0.006-235.476
c-0.009-4.686,1.333-5.693,5.805-5.683c61.994,0.145,123.988,0.098,185.981,0.098C314.081,96.212,314.081,96.22,314.081,96.229z"/>
</g>
<use xlink:href="#mg" width="300" x="400" y="100" stroke-width="30" stroke="white" paint-order = "stroke fill" />
</svg>

SVG how to set max width for group

I have some SVG elements grouped together in a <g> element (exactly the barcode 1D, PHP generates a barcode).
<g
style="fill:#000000;stroke:none"
id="barcode1D"
transform="matrix(1.2083333,0,0,0.8247805,62.027778,573.54235)">
<rect
x="0"
y="0"
width="4"
height="30"
id="xyz" />
....
<rect
x="224"
y="0"
width="0"
height="30"
id="xyzn" /> </g>
The barcode is generated in various widths, lengths. How can I set the width permanently ?
Based on this example, I am asking for a hint. Thank you for your help in advance.
SVG g element does not have width and height attributes. Therefore, you can not set height and width on it.
You should use a foreignObject with a svg inside of it to do so.
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<foreignObject id="G" width="300" height="200">
<svg>
<!-- Barcode here -->
<rect fill="black" stroke-width="2" height="112" width="84" y="55" x="55" stroke="#000000"/>
<circle fill="#FF0000" stroke="#000000" stroke-width="5" cx="155" cy="65" id="svg_7" r="50"/>
</svg>
</foreignObject>
</svg>

SVG path mask not working

According to example of this tutorials I want to mask my icon (black and white) instead of text in this tutorial. but right side of icon is still dark. how can I make left side of my icon black stroke and right side of icon goes white stroke?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="41px" height="50px" viewbox="-3 -3 40 48">
<defs>
<mask id="myMask" maskUnits="userSpaceOnUse"
x="0" y="0" width="18" height="50">
<rect x="0" y="0" width="15" height="50" fill="white"/>
</mask>
<path id="fire-icon" d="m 25.55134,17.573125 c 0.647761,1.273107 1.136636,2.596633 1.344412,4.021007 0.21999,1.47479 0.13444,2.924371 -0.342217,4.348739 -0.427768,1.273111 -1.124413,2.382358 -2.004391,3.378155 -0.977758,1.096637 -2.114394,1.991591 -3.348802,2.773105 -0.183328,0.113445 -0.366658,0.226895 -0.57443,0.365546 1.429964,-3.214282 1.686623,-5.760501 0.366659,-8.924365 -0.904421,-2.155462 -2.395495,-3.743696 -3.519909,-4.4874 0,0 0.305545,3.655466 -2.248829,5.9874 0.391098,-1.184876 -0.672208,-2.31933 -0.672208,-2.31933 -0.31777,1.386549 -0.8922,1.651268 -1.662178,2.836135 -0.366658,0.567227 -0.708873,1.159666 -0.941085,1.802516 -0.342214,0.970596 -0.403325,1.953785 -0.207778,2.96219 0.134444,0.668067 0.342218,1.310925 0.63554,1.941174 0.02446,0.05042 0.04889,0.113449 0.08556,0.226893 C 12.156129,32.308418 11.899468,32.169763 11.655035,31.993294 10.921719,31.463881 10.163961,30.959677 9.467313,30.37985 8.5628918,29.623547 7.8173555,28.715982 7.3284794,27.619344 7.0351536,26.951277 6.8640469,26.245395 6.8151593,25.514301 c -0.097775,-1.65126 0.2933257,-3.201685 0.9899743,-4.676472 0.5010979,-1.071427 0.9777525,-2.142852 1.4544067,-3.226887 0.1344411,-0.31513 0.2199942,-0.66807 0.3055478,-1.008411 0.085554,-0.327726 0.1344412,-0.668063 0.1955503,-1.033609 0.9777516,0.46639 1.4544056,2.521009 0.9044216,3.857144 0.02444,0 0.03666,0 0.06111,0 0.232216,-0.302517 0.464431,-0.605039 0.696652,-0.907563 0.977751,-1.323526 1.869945,-2.684872 2.566595,-4.184872 0.623316,-1.34874 1.099973,-2.735295 1.185527,-4.247902 0.02445,-0.5294123 -0.02445,-1.0714263 -0.03667,-1.6008383 0.01223,0 0.02445,0 0.03667,0 0.65998,0.315125 1.307741,0.680673 1.882172,1.134457 1.014423,0.8193243 1.857728,1.7899163 2.566601,2.8991563 0.892198,1.411766 1.515512,2.936975 1.955505,4.550418 0.01223,0.06302 0.03667,0.126055 0.06111,0.214286 1.344407,-1.210083 0.513317,-4.172266 0.501096,-4.222688 -0.02445,-0.0252 2.261053,2.029411 3.409911,4.512605 z"
fill="none" stroke="#303233" stroke-width="1.3" />
</defs>
<!-- Draw black rectangle in the background -->
<rect x="18" y="0" width="15" height="50" fill="#000" />
<!-- Draw the text string twice. First, the white text without mask.
Second, the black text with the mask applied-->
<use xlink:href="#fire-icon" stroke="white"/>
<use xlink:href="#fire-icon" stroke="black" mask="url(#myMask)"/>
</svg>
There's no mask issue. The stroke on the path overrides the stroke on the use element, so in the question there are two grey (#303233) stroked paths. Removing the path stroke atribute allows the use to set one.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="41px" height="50px" viewbox="-3 -3 40 48">
<defs>
<mask id="myMask" maskUnits="userSpaceOnUse"
x="0" y="0" width="18" height="50">
<rect x="0" y="0" width="15" height="50" fill="white"/>
</mask>
<path id="fire-icon" d="m 25.55134,17.573125 c 0.647761,1.273107 1.136636,2.596633 1.344412,4.021007 0.21999,1.47479 0.13444,2.924371 -0.342217,4.348739 -0.427768,1.273111 -1.124413,2.382358 -2.004391,3.378155 -0.977758,1.096637 -2.114394,1.991591 -3.348802,2.773105 -0.183328,0.113445 -0.366658,0.226895 -0.57443,0.365546 1.429964,-3.214282 1.686623,-5.760501 0.366659,-8.924365 -0.904421,-2.155462 -2.395495,-3.743696 -3.519909,-4.4874 0,0 0.305545,3.655466 -2.248829,5.9874 0.391098,-1.184876 -0.672208,-2.31933 -0.672208,-2.31933 -0.31777,1.386549 -0.8922,1.651268 -1.662178,2.836135 -0.366658,0.567227 -0.708873,1.159666 -0.941085,1.802516 -0.342214,0.970596 -0.403325,1.953785 -0.207778,2.96219 0.134444,0.668067 0.342218,1.310925 0.63554,1.941174 0.02446,0.05042 0.04889,0.113449 0.08556,0.226893 C 12.156129,32.308418 11.899468,32.169763 11.655035,31.993294 10.921719,31.463881 10.163961,30.959677 9.467313,30.37985 8.5628918,29.623547 7.8173555,28.715982 7.3284794,27.619344 7.0351536,26.951277 6.8640469,26.245395 6.8151593,25.514301 c -0.097775,-1.65126 0.2933257,-3.201685 0.9899743,-4.676472 0.5010979,-1.071427 0.9777525,-2.142852 1.4544067,-3.226887 0.1344411,-0.31513 0.2199942,-0.66807 0.3055478,-1.008411 0.085554,-0.327726 0.1344412,-0.668063 0.1955503,-1.033609 0.9777516,0.46639 1.4544056,2.521009 0.9044216,3.857144 0.02444,0 0.03666,0 0.06111,0 0.232216,-0.302517 0.464431,-0.605039 0.696652,-0.907563 0.977751,-1.323526 1.869945,-2.684872 2.566595,-4.184872 0.623316,-1.34874 1.099973,-2.735295 1.185527,-4.247902 0.02445,-0.5294123 -0.02445,-1.0714263 -0.03667,-1.6008383 0.01223,0 0.02445,0 0.03667,0 0.65998,0.315125 1.307741,0.680673 1.882172,1.134457 1.014423,0.8193243 1.857728,1.7899163 2.566601,2.8991563 0.892198,1.411766 1.515512,2.936975 1.955505,4.550418 0.01223,0.06302 0.03667,0.126055 0.06111,0.214286 1.344407,-1.210083 0.513317,-4.172266 0.501096,-4.222688 -0.02445,-0.0252 2.261053,2.029411 3.409911,4.512605 z"
fill="none" stroke-width="1.3" />
</defs>
<!-- Draw black rectangle in the background -->
<rect x="18" y="0" width="15" height="50" fill="#000" />
<!-- Draw the text string twice. First, the white text without mask.
Second, the black text with the mask applied-->
<use xlink:href="#fire-icon" stroke="white"/>
<use xlink:href="#fire-icon" stroke="black" mask="url(#myMask)"/>
</svg>

svg mask and bounding box

I need to apply mask to a different objects.
Mask should cover whole object (visible part of it). I put the mask inside one specific place, at the top of the page, changed maskContentUnits to objectBoundingBox, so it worked perfectly.
But then a problem appeared.
I made a fiddle to illustrate the problem: http://jsfiddle.net/8qdt7vjr/1/
<body>
<svg width="0" height="0">
<defs>
<mask id="mask1" maskContentUnits="objectBoundingBox">
<ellipse cx=".5" cy=".5" rx=".5" ry=".5" fill="white" />
</mask>
</defs>
</svg>
<svg class="svg" width="200" height="150" overflow="visible">
<rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
<svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
<rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
</svg>
<rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
</svg>
</body>
In this fiddle i want to apply mask to svg element with id="zzz". But inside this element there is a rect element, that increases zzz's bounding box. In the fiddle it is rect, but in my project it is an image tag. zzz has overflow set to hidden (in the fiddle I changed it to visible, so it is easier to see the problem), so I have a specific portion of image visible inside zzz.
The real problem is that zzz's inner content increases zzz's bounding box.
In the fiddle I want ellipse mask to be inside red rectangle (visible zzz's area), but it is inside green rectangle (zzz's bounding box) instead.
So the main question is: is there any way to achieve this goal? Mask will be used by many elements with different sizes and content and I do not want to clone it.
Is there any way to do this without cloning mask inside each element?
Is there any way to reduce bounding box to visible area?
Is there any way to show a part of an image without expanding parent's bounding box?
Is there any other way to do this?
Is it something like this you try to achieve?
<body>
<svg width="0" height="0">
<defs>
<mask id="mask1" maskContentUnits="userSpaceOnUse">
<ellipse cx="100" cy="75" rx="100" ry="75" fill="white" />
</mask>
</defs>
</svg>
<svg class="svg" width="200" height="150" overflow="visible">
<rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
<svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
<rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
</svg>
<rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
</svg>
</body>
Maybe using userSpaceOnUse instead of objectBoundingBox can help achieve what you want... In combination with nested svg elements you can define the userspace to use and with that the part the mask is applied to...

Resources