0

I have this shape for my SVG buttons so far, but now I have been given a request to redesign it a bit. I need to have curved edges instead of the sharp edges I achieved, and it needs to be longer as well. For the one I already made, I used some arcs and lines. I have provided the design image for reference along with the code I have for the previous version of the button so far. How can I refine the shape I have into looking like the new design image? They want the button to match the inner green part, the outer thick border is just there so the shape is easier to see.

HTML

<svg viewbox="0 0 100 20" class="bottom-nav-circle-button-2" width="100" height="100">
  <path d="M 100 0 A 100 50 0 0 0 29.2 29.2 L 57.58 57.58 A 60 60 0 0 1 100 40 Z"></path>
</svg>

Example Image: enter image description here

1 Answers1

2

For rounded edges pease add stroke-linejoin="round" To make it bigger please refer to my answer to your other question: How to make a “bent rectangle” in SVG? i.e: you will have to increase the angle for the segment.

<svg viewbox="0 -50 200 200" class="bottom-nav-circle-button-2" width="200" height="200">
  <path stroke="grey" stroke-width="10" stroke-linejoin="round" d="M 100 0 A 100 50 0 0 0 29.2 29.2 L 57.58 57.58 A 60 60 0 0 1 100 40 Z"></path>
</svg>

UPDATE

The OP is commenting that he/she needs the shape to be rounded and the stroke width to be only 1px. I'm updating my answer. Now the corners of the shape become control points for quadratic Bézier curves. The offset angle is a and the vertical offset is o. I need those offset to define the starting and ending points of the Beziers.

In the comments you may find the d attribute for the original shape, and for a beveled one.

In order to get a different rounding effect you may try to change the values for the angles and for the offset.

const rad = Math.PI / 180;

let cx = 50, cy = 100, R = 50, r = 35, A = 40 , a = 5, o=4;
// o for offset
testG.setAttributeNS(null, "transform", `rotate(${-90 -(A / 2) - a} ${cx} ${cy})`)


// control points for the quadratic Bézier
let px1 = cx + R * Math.cos(0);
let py1 = cy + R * Math.sin(0);
let px2 = cx + R * Math.cos((2*a + A)*rad);
let py2 = cy + R * Math.sin((2*a + A)*rad);
let px3 = cx + r * Math.cos((2*a + A)*rad);
let py3 = cy + r * Math.sin((2*a + A)*rad);
let px4 = cx + r * Math.cos(0);
let py4 = cy + r * Math.sin(0);

// points used to draw the shape
let x11 = cx + (R-o) * Math.cos(0);
let y11 = cy + (R-o) * Math.sin(0);

let x1 = cx + R * Math.cos(a*rad);
let y1 = cy + R * Math.sin(a*rad);

let x2 = cx + R * Math.cos((a + A)*rad);
let y2 = cy + R * Math.sin((a + A)*rad);

let x21 = cx + (R-o) * Math.cos((2*a + A)*rad);
let y21 = cy + (R-o) * Math.sin((2*a + A)*rad);

let x31 = cx + (r+o) * Math.cos((2*a + A)*rad);
let y31 = cy + (r+o) * Math.sin((2*a + A)*rad);

let x3 = cx + r * Math.cos((a + A)*rad);
let y3 = cy + r * Math.sin((a + A)*rad);

let x4 = cx + r * Math.cos(a*rad);
let y4 = cy + r * Math.sin(a*rad);

let x41 = cx + (r+o) * Math.cos(0);
let y41 = cy + (r+o) * Math.sin(0);

/*
No rounded corners
let d = `M${x1},${y1} A${R},${R},0 0,1 ${x2},${y2}
         L${x3},${y3} A${r},${r},0 0,0 ${x4},${y4}
         L${x1},${y1}Z`;*/

/*
Beveled corners
let d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         L${x21},${y21} 
         L${x31},${y31}
         L${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         L${x41},${y41}
         L${x11},${y11}
         L${x1},${y1}Z`;*/

// Rounded corners with quadratic Bézier curves
    d = `M${x1},${y1} 
         A${R},${R},0 0,1 ${x2},${y2}
         Q${px2},${py2} ${x21},${y21} 
         L${x31},${y31}
         Q${px3},${py3} ${x3},${y3}
         A${r},${r},0 0,0 ${x4},${y4}
         Q${px4},${py4} ${x41},${y41}
         L${x11},${y11}
         Q${px1},${py1} ${x1},${y1}Z`;

test.setAttributeNS(null,"d",d);
svg{border:1px solid; max-width:90vh; }

path{stroke:black; fill:none;}
<svg viewBox="0 40 100 40">
  <g id = "testG" >
    <path id="test"/>
  </g>
</svg>

SECOND UPDATE

And this is the resulting SVG:

<svg viewBox="0 40 100 40">
  <g id="testG" transform="rotate(-115 50 100)">
    <path id="test" stroke="black" fill="none" d="M99.80973490458729,104.35778713738291 
         A50,50,0 0,1 85.35533905932738,135.35533905932738
         Q82.13938048432698,138.3022221559489 79.5682300455808,135.23804438347298 
         L75.06871677777504,129.87573328164015
         Q72.49756633902888,126.81155550916424 74.74873734152916,124.74873734152916
         A35,35,0 0,0 84.86681443321109,103.05045099616804
         Q85,100 89,100
         L96,100
         Q100,100 99.80973490458729,104.35778713738291Z"></path>
  </g>
</svg>
Community
  • 1
  • 1
enxaneta
  • 31,608
  • 5
  • 29
  • 42
  • I can make it longer, but the problem is with the rounded edges. I already tried "stroke-linejoin: round;" in my css and the edges are not rounded as desired. I don't need the wide border, I need the shape to be rounded. The stroke width is only 1px. Does a narrow stroke cause issues with rounding? – James Hammond Oct 20 '18 at 19:16
  • Thank you very much, sadly I cannot use jQuery on this project. Would it be possible to see how to path this? I tried putting some Qs into my path for those curves, but my result was pitiful. – James Hammond Oct 23 '18 at 01:31
  • 1
    I am not using jQuery. It's JavaScript. I've updated my answer with the resulting SVG code. Please take a look. – enxaneta Oct 23 '18 at 07:04
  • Thank you for your extremely detailed assistance. I still have much to learn for sure! – James Hammond Oct 23 '18 at 18:22