I have an svg and when I define the fill it behaves as stroke
For example
<svg stroke="black" fill="red">
<path d="M10 10 H 90 V 90 H 10 Z"/>
</svg>
This works as expected, but when I have
<svg stroke="black" fill="red">
<path d="M12,5.41,19.59,13H15v6H9V13H4.41L12,5.41M12,4,3.71,12.29A1,1,0,0,0,4.41,14H8v5a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V14h3.59a1,1,0,0,0,.71-1.71L12,4Z"/>
</svg>
It doesn't. Any suggestions why the fill doesn't work as the other svg ?
DEMO
<svg stroke="black" fill="red">
<path d="M12,5.41,19.59,13H15v6H9V13H4.41L12,5.41M12,4,3.71,12.29A1,1,0,0,0,4.41,14H8v5a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V14h3.59a1,1,0,0,0,.71-1.71L12,4Z"/>
</svg>
<svg stroke="black" fill="red">
<path d="M10 10 H 90 V 90 H 10 Z"/>
</svg>
If we enlarge the arrow, you will see what is happening.
<svg viewBox="0 0 40 40"
stroke="black" fill="red" stroke-width="0.2">
<path d="M12,5.41,19.59,13H15v6H9V13H4.41L12,5.41M12,4,3.71,12.29A1,1,0,0,0,4.41,14H8v5a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V14h3.59a1,1,0,0,0,.71-1.71L12,4Z"/>
</svg>
As Robert said, you have an arrow shape with an arrow shaped hole inside it. Your arrow was appearing black, instead of red, because at that small size the thickness of the black stroke was hiding the red fill.
If you want a red arrow with a black outline, then you will need to redesign your shape so that it is just a single outline, not a "double-walled" one.
Related
I need strokes to scale with width but not with height.
This is the closest I've come to a solution:
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="50">
<rect width="100%" height="100%" fill="black"/>
<svg viewBox="0 0 1 1" preserveAspectRatio="none">
<path vector-effect="non-scaling-stroke" stroke-width="5" stroke="blue" d="
M 0,0 L 1,1
M 0,1 L 1,0
"/>
</svg>
</svg>
This lets me change the height without affecting the stroke width, but also I need the strokes to scale when the entire svg is scaled. The problem is that I can't make the strokes scalable again. I've tried using percentages, but they are relative to the diagonal size.
Consider the following SVG image code:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<title>Clipped Path Problem Demo</title>
<g id="group:image">
<defs>
<mask id="mask">
<rect id="rectangle:inset" x="250" y="134" width="500" height="732" fill="white"/>
</mask>
</defs>
<g id="group:curves" mask="url('#mask')">
<!-- <rect id="rectangle:filler.shape" width="1" height="1" fill="transparent"/> -->
<path id="path:curves" d="
M 441 327
c -85 88 -85 175 -85 175
c 0 88 85 175 85 175
s 90 103 90 103
c 85 88 85 175 85 175" fill="transparent" stroke="black" stroke-width="73"/>
</g>
</g>
<g id="group:guides">
<rect id="rectangle:guide.area:inset" x="250" y="134" width="500" height="732" fill="transparent" stroke="black" stroke-dasharray="20 10" stroke-width="1"/>
</g>
</svg>
(CodePen: https://codepen.io/patrickdark/full/zPEVVg/. (I added a height="500px" attribute to the pen to make it more likely to fit on screen.))
The left side of the curved path is clipped to a vertical line even though the mask is well over the size needed to contain that portion of the image.
If I insert a shape of any size with non-zero dimensions into the masked g element—such as the 1×1 transparent rectangle in the XML comment—the clipped edge is magically unclipped.
I would think this is a bug except that it’s happening in Chrome (62), Edge (41), and Firefox Developer Edition (58 Beta 4). What I would like to know is why this seemingly nonsensical clipping is occurring.
(Note: Clipping at the bottom of the curved path is intentional.)
Since a mask works on color and alpha channel values (a potentially costly operation), it doesn't stretch to infinity, but rendering is clipped of by default at the object bounding box of the masked element plus 10% in every direction (defined by the attributes x, y, width, height in bounding box units).
The object bounding box although is defined not to include stroke widths. You are surpassing these limits and need to make adjustments at least to the x and width attribute of the mask.
Since this seems to be not intuitive, the general algorithm for applying a mask goes like this:
Identify the region the mask is applied to. This is always the rectangle given by the x, y, width, height attributes of the <mask> element. If, as is the default, the maskUnits attribute is given as objectBoundingBox, the coordinates are determined by the object bounding box of the element the mask is applied to. The contents of the mask are not taken into account. 0 and 1 in that coordinate system are the minimum and maximum of the joined bounding box of the masked element and all its descendants.
Superimpose the content of the mask element with the element it is applied to. As a default, the coordinate system used for placing these elements is given as maskContentUnits="userSpaceOnUse", which means the same coordinate system the masked element is drawn into.
For every point within the region defined above, multiply the opacity of the masked content with the luminance of the masking content to compute a resulting opacity of the masked element.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<title>Clipped Path Problem Resoved</title>
<g id="group:image">
<defs>
<mask id="mask" x="-20%" width="140%">
<rect id="rectangle:inset" x="250" y="134" width="500" height="732" fill="white"/>
</mask>
</defs>
<g id="group:curves"mask="url('#mask')">
<!-- <rect id="rectangle:filler.shape" width="1" height="1" fill="transparent"/> -->
<path id="path:curves" d="
M 441 327
c -85 88 -85 175 -85 175
c 0 88 85 175 85 175
s 90 103 90 103
c 85 88 85 175 85 175" fill="transparent" stroke="black" stroke-width="73"/>
</g>
</g>
<g id="group:guides">
<rect id="rectangle:guide.area:inset" x="250" y="134" width="500" height="732" fill="transparent" stroke="black" stroke-dasharray="20 10" stroke-width="1"/>
</g>
</svg>
Folks, let me start by saying that StackOverflow has been invaluable help in my project to design an open-source javascript eye-testing chart. Thank you all.
My question is how best to draw a capital letter R in a 5 high by 4 wide grid, that will work at 0.1 alpha (so no overlapping elements allowed).
Here's my best attempt so far. The difficulty is in the meeting between the arc and the diagonal, which is not a straight line.
<svg id="Snellen_R" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0.5 5 V 0.5 H 2 M 2 0.5 C 3.5 0.5 3.5 2.5 2 2.5 H 0.5"
stroke="black" fill="none" stroke-width="1" >
</path>
<polygon points="1.4,3 2.1,3 2.2,2.99 2.3,2.98 2.35,2.97 2.4,2.96 2.45,2.95 2.5,2.94 4,5 2.8,5" fill="black" />
</svg>
Thanks.
Inkscape may be able to help you. It's an open source vector graphics editor. I've used it several times for creating text graphics. If anything you can use Inkscape to draw your letter, and then look at the code it generates. You can also save your graphic to a .svg file, or export to another format such as .png.
Here is the link:
https://inkscape.org/en/
Plenty of youtube tutorials out there as well. Good luck!
There's actually no problem having elements overlapping. Just apply the opacity setting to the whole <svg> element instead of setting separate fill-opacity and stroke-opacity values for the drawing elements inside it.
<p>
<svg viewBox="0,0,4,5" height="100" style="margin: 3.49mm;">
<path d="M 0.5 5 V 0.5 H 2 M 2 0.5 C 3.5 0.5 3.5 2.5 2 2.5 H 0.5" stroke="black" fill="none" stroke-width="1" stroke-opacity="0.1">
</path>
<polygon points="1.32,2.9 2.12,2.9 2.42,2.9 4,5 2.8,5" fill="black" fill-opacity="0.1" />
</svg>
<br/>Opacity applied to <tt><path></tt> and <tt><polygon></tt> elements</p>
<p>
<svg viewBox="0,0,4,5" height="100" style="margin: 3.49mm; opacity:0.1">
<path d="M 0.5 5 V 0.5 H 2 M 2 0.5 C 3.5 0.5 3.5 2.5 2 2.5 H 0.5" stroke="black" fill="none" stroke-width="1">
</path>
<polygon points="1.32,2.9 2.12,2.9 2.42,2.9 4,5 2.8,5" fill="black" />
</svg>
<br/>Opacity applied to <tt><svg></tt> element</p>
This is my svg path. I am trying to achieve trapezium. Left of the rectangle has come out fine. I wanted the same way on the right side. How do I bend it?
<path d="M20 20 H 300 V 70 H 10 Z" fill="transparent" style="stroke:black; stroke-width:2"/>
This is the image reference of the shape I wanted:
http://amsi.org.au/teacher_modules/C3/C3g37.png
If you don't want a vertical line best not to use V as that command draws them. I've replaced the V with an L below.
<svg width="100%" height="100%">
<path d="M20 20 H 300 L 310 70 H 10 Z" fill="transparent" style="stroke:black; stroke-width:2"/>
</svg>
I'm wondering, how do SVG elements stack their opacity? More specifically, if I have an element with opacity: 0.4, what will the overlapping element's opacity need to be in order to result in opacity: 0.8 at the overlap?
What is the resulting opacity at the overlap?
https://jsfiddle.net/HZr7v/18/
The answer is 0.6667.
The rule is that transparency combines by multiplication. So if you have two overlapping objects with transparencies of 60% and 33.33%, then the transparency of the overlapping region will be (0.6 × 0.3333) = 0.2.
An object's alpha value is equal to 1 minus its transparency, so the combination of α=0.4 and α=0.6667 is equal to 1 - (1-0.4) × (1-0.6667) = 1 - 0.6 × 0.3333 = 1 - 0.2 = 0.8.
By way of illustration, here's an SVG image containing two overlapping circles with alpha values of 0.4 and 0.6667 next to a solid circle filled with 80% black (#333):
<svg width="340" height="200" viewBox="0 0 340 200">
<circle cx="100" cy="80" r="60" fill="#000" opacity="0.4" />
<circle cx="100" cy="120" r="60" fill="#000" opacity="0.6667" />
<circle cx="180" cy="100" r="60" fill="#333" opacity="1" />
<text x="0" y="30">α=0.4</text>
<text x="0" y="180">α=0.6667</text>
<text x="250" y="110">80% black</text>
</svg>