5

I read SVG docs but I can't find solution to this. How to draw in SVG ellipse gradient like in picture below?

reference gradient in graphics software

I use svg radialGradient but it renders circle which is not I want. So next I draw ellipse and fill it with radialGradient and I end up with this: enter image description here

I use svg mask to crop ellipse but it not working as I expected. Is there any way to achieve that?

Link to svg code: https://codesandbox.io/s/fancy-dew-skokw

<svg
  tabindex="0"
  focusable="true"
  shape-rendering="optimizeSpeed"
  viewBox="0 0 640 545"
  style="border: 1px solid blue; width: 100%; height: 100%;"
>
  <g id="text_7">
    <rect
      x="138"
      y="455"
      width="355"
      height="60"
      style=" mask: url('#mask_ellipse_7)'"
    ></rect>
    <ellipse
      cx="292"
      cy="80"
      rx="116"
      ry="51"
      transform="matrix(1,0,0,1,65,400)"
      style="fill:url('#bg-ellipse-gradient_7'); "
    ></ellipse>
    <text font-size="12" transform="matrix(1,0,0,1,65,400)">
      <tspan x="75" y="67" dy="0" fill="#FF0000" fill-opacity="1">
        Lorep ipsum - radial gradient
      </tspan>
    </text>     
    <defs>
      <radialGradient
        id="bg-ellipse-gradient_7"
        fx="74%"
        fy="37%"
      >
        <stop
          stop-color="#00FFFF"
          stop-opacity="1"
          offset="0.000000"
        ></stop>
        <stop
          stop-color="#FFFF00"
          stop-opacity="1"
          offset="0.500000"
        ></stop>
        <stop
          stop-color="#000000"
          stop-opacity="1"
          offset="1.000000"
        ></stop>
      </radialGradient>
    </defs>
    <defs>
      <mask
        id="mask_ellipse_7"
        cx="292"
        cy="80"
        rx="116"
        ry="51"
        transform="matrix(1,0,0,1,65,400)"
        style="fill:url('#bg-ellipse-gradient_7'); "
      ></mask>
    </defs>
  </g>
</svg>
miuosh
  • 836
  • 3
  • 12
  • 35
  • I added link to codesandbox – miuosh May 19 '20 at 14:47
  • You are required to post a [mcve] here, **within your question**, and [not a link](https://meta.stackoverflow.com/questions/254428/something-in-my-web-site-or-project-doesnt-work-can-i-just-paste-a-link-to-it) to any third party site. – Rob May 19 '20 at 14:47
  • @miuosh And why do you additionally need a mask for cropping? Without it, an ellipse gradient is obtained – Alexandr_TT May 19 '20 at 15:31
  • @Alexandr_TT Agree but I want to show only part of ellipse which overlap rectangle. – miuosh May 19 '20 at 16:11

2 Answers2

3

To get the image as in the first screenshot, you need to apply a mask.

The mask is made up of two rectangles: The first rectangle fill ="black" cuts everything
The second rectangle fill ="white" leaves the desired part with an ellipse

<mask  id="mask_ellipse_7" > 
    <rect width="100%" height="100%" fill="black" />
       <rect x="138" y="455" width="355" height="60" stroke="red" fill="white" />
</mask>  

Below is the full code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
  </head>
  <body>
    <svg
      tabindex="0"
      focusable="true"
      shape-rendering="optimizeSpeed"
      viewBox="0 400 640 545"
      style="border: 1px solid blue; width: 100%; height: 100%;"
    >
      <g id="text_7" style="mask:url(#mask_ellipse_7)">
        <rect
          x="138.734375"
          y="455.703125"
          width="355"
          height="60"
    fill="black"
          
        ></rect>
        <ellipse
          cx="292.000183"
          cy="80.999115"
          rx="116.99969500000003"
          ry="51.003084999999984"
          transform="matrix(1,0,0,1,65,400)"
          style="fill:url('#bg-ellipse-gradient_7'); "
        ></ellipse>
        <text font-size="12" transform="matrix(1,0,0,1,65,400)">
          <tspan x="75" y="67" dy="0" fill="#FF0000" fill-opacity="1">
            Lorep ipsum - radial gradient
          </tspan>
        </text>
  </g>
        <defs>
          <radialGradient
            id="bg-radial-gradient_7"
            gradientTransform="matrix(1,0,0,1,65,400)"
            gradientUnits="userSpaceOnUse"
            fx="304"
            fy="49"
            cx="292.000183"
            cy="80.999115"
            r="127.63323747993802"
          >
            <stop
              stop-color="#00FFFF"
              stop-opacity="1"
              offset="0.000000"
            ></stop>
            <stop
              stop-color="#FFFF00"
              stop-opacity="1"
              offset="0.500000"
            ></stop>
            <stop
              stop-color="#000000"
              stop-opacity="1"
              offset="1.000000"
            ></stop>
          </radialGradient>
        </defs>
        <defs>
          <radialGradient
            id="bg-ellipse-gradient_7"
            fx="74.32765053294222%"
            fy="37.120593444654716%"
          >
            <stop
              stop-color="#00FFFF"
              stop-opacity="1"
              offset="0.000000"
            ></stop>
            <stop
              stop-color="#FFFF00"
              stop-opacity="1"
              offset="0.500000"
            ></stop>
            <stop
              stop-color="#000000"
              stop-opacity="1"
              offset="1.000000"
            ></stop>
          </radialGradient>
        </defs>
        <defs>
          <mask
            id="mask_ellipse_7" > 
   <rect width="100%" height="100%" fill="black" />
            <rect x="138" y="455" width="355" height="60" stroke="red" fill="white" />
          </mask>
        </defs>
      
   
    </svg>
  </body>
</html>
Alexandr_TT
  • 13,635
  • 3
  • 27
  • 54
2

You can do this with just the <rect> and a <radialGradient>:

  • Use cx/cy to place the gradient halfway outside the rectangle, and r to set the size of the gradient.
  • The gradient still has the flat shape of the rectangle though, so stretch it with gradientTransform to get the right shape.

<svg width="400" height="200">
    <defs>
        <radialGradient id="bg-ellipse-gradient_7"
                        cx="60%" cy="5%" r="40%"
                        gradientTransform="scale(1, 3)">
            <stop stop-color="#00FFFF" stop-opacity="1" offset="0.0" />
            <stop stop-color="#FFFF00" stop-opacity="1" offset="0.5" />
            <stop stop-color="#000000" stop-opacity="1" offset="1.0" />
        </radialGradient>
    </defs>

    <rect x="50" y="75" width="300" height="50" fill="url(#bg-ellipse-gradient_7)" />
</svg>
Sphinxxx
  • 12,484
  • 4
  • 54
  • 84