I'm trying to draw a partial circle with svg's path. I have the circle center coordinates, radius and the start/end coordinates (where the partial circle will end), but I can't wrap my head around on how to draw the circle.
I hope that this small example can help you. The path starts in 50%,50% (center), moves to 50%,0 (that is 12 o'clock), creates an arc where radius x and y are 50 (the fist two numbers after a) and ends in the position that is a calculation with sin() and cos() on 45 degrees (the angle should be in radians). The three numbers in between (0 0 1) are flags.
See more here: d - Elliptical Arc Curve
// 45 deg:
console.log(Math.cos(Math.PI/4)*50, 50-Math.sin(Math.PI/4)*50);
document.querySelector('path')
.setAttribute('d', `M50,50 L50,0 a 50 50 0 0 1 ${Math.cos(Math.PI/4)*50} ${50-Math.sin(Math.PI/4)*50} z`);
<svg width="200" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="lightblue" />
<path fill="navy" />
</svg>
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>
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 need to create a block with specific borders around it:
I want to have this block scalable, that is why I try doing it with svg.
Here is what I've done:
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none slice" viewBox="0 0 300 400">
<path stroke-width="1" stroke="#7DD37D" fill="red" d="
M20 0h260
m20 20v360
m-20 20H20
m-20 -20V20
M0 20a20 20 0 0 0 20 -20
M300 20a20 20 0 0 1 -20 -20
M300 380a20 20 0 0 0 -20 20
M0 380a20 20 0 0 1 20 20" id="path"/>
</svg>
Demo on codepen
The border was created as path from lines and arcs.
The problem is, that I can't make svg to fill the area inside this path. It fills some space inside arcs instead of rectangle. What I'm doing wrong?
When I do something similar with Inkscape, the resulting path is combined from lines and Cubic Bezier curves. Can it be done with simple arcs instead of Bezier curves?
Each time you use a move ('m' or 'M') path command, it creates a new subpath. Each subpath gets filled, not the whole thing.
If you want the whole thing filled, it has to be a continuous path. In other words, in this case, it should be a move followed by a line, then an arc, then another line, and arc, and so on until you have completed all four sides of the shape.
I want to draw a shape in SVG that has the centre hollowed out.
I asked this question for drawing a circle with a circle in the middle here.
I would like to draw any shape in SVG with the middle (of another shape) hollowed out.
Any ideas?
I'm thinking it could be possible using Masks or ClipPaths but I'm not sure if I understand them fully
Create your shape as a path, which consists of two sub-paths. The first subpath describes your outer shape; the second subpath describes the inside shape. Set the fill-rule of the pathto 'evenodd'.
e.g. for a hollowed out rectangle, we make a path consisting of two sub-paths. One for the outside rectangle; one for the inner rectangle:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M 100 100 L 200 100 L 200 200 L 100 200 z
M 110 110 L 190 110 L 190 190 L 110 190 z"
fill="red"
stroke="black" stroke-width="1"
fill-rule="evenodd"/>
</svg>