The image to the left shows a specific kind of radial gradient – rather than the bounds of the gradient being circular, the width and height are different resulting in an shape to the gradient which starts at white, and transitions to green. In some graphic design tools it is possible to create these gradients, and I was able to create one in Sketch. The gradient tool in Sketch perfectly shows this shape:

If I export this to an SVG we can open it in Chrome and the elliptical gradient is still there:

If I now import this in to Android Studio using Vector Studio, then even in the preview of the VectorDrawable before we complete the import we can see that the elliptical shape has been lost and we revert to a standard circular radial gradient:

The reason for this may seem obvious to those familiar with RadialGradient in Android which is used when rendering gradients directly to a Canvas, and is the basis for the radial gradient in VectorDrawable. RadialGradient only permits us to specify a single value as the radius of the gradient meaning that it will only render circular gradients.

We can also apply this same principle to VectorDrawable to get an asymmetric radial gradient by applying the scale by using a group. To understand how to do this, let’s first take a look at the VectorDrawable which I imported from SVG (which lost the elliptical gradient):

I should mention that I slightly tweaked the path datafrom what was imported because it will hopefully make what follows a little easier to follow. The original path was `M50,50m-45,0a45,45 0,1 1,90 0a45,45 0,1 1,-90 0` and I converted it to a single arc rather than two semicircular arcs: `M50,5 a45,45 0 1 0 0.1,0 z`

Anyone familiar with using radial gradients within VectorDrawable should have an idea of how this will look, and that it will have a symmetrical, circular radial gradient – which ties in with the preview:

We now wrap this inside a group with `scaleY="2"` and then tweak the centreY and gradientRadius attributes by halving each of them to compensate for the Y scaling added to the group:

This now looks like this:

So we now have an elliptical gradient, but we have also distorted the circular outline, which is not what we wanted. One solution would be to change the path itself to fill a rectangle, and then apply a `clip-path` before, and outside of the group:

At a first glance this looks fine:

However, if you look carefully at the edges of the circle they are quite jagged. This is because `clip-path` renders at pixel level meaning that it controls whether a given pixel can be painted or not. A path on the other hand, renders at a sub-pixel level meaning that for a pixel on the perimeter of the circle, the actual colour that it is painted will be determined by the proportion of that pixel which falls inside the circle. This is known as anti-aliasing and results in edges which appear much smoother to the human eye. It’s the lack of this anti-aliasing (which we lose with clip-path) which causes these jaggies.

In order to get rid of the jaggies, a better solution is to actually tweak the path data of the circle to account for the change to the Y scaling. In this case the Y component of the move command needs halving from `M50,`5 to `M50,`2.5 and the radius of the arc needs halving from `a45,`45 `0 1 0 0.1,0` to `a45,`22.5 `0 1 0 0.1,0`:

It now looks like this:

So we now have an elliptical gradient, inside a symmetrical circle, with no jaggies!

So we can manually implement an asymmetric radial gradient by using an asymmetrical scaling in a group,. and then manually tweaking the gradient and path data parameters to compensate for that scaling.

Once again, my thanks to Olga Zhernova for asking the question which prompted this post.