nope, image backs are cropped correctly with border radius (almost perfect except some white outline on corners (idk what’s that)
The only problem is vector graphics package gives me such weird result on gradients when i try to import them as vector images, details under spoiler
svg importer
on both importers same 2x2 gradient vector image from FFFF(up) to 888F(down)
using directly vector data is not possible yet for gradients, also for radial gradients larger texture need to be generated on svg import
in any case i used vectors in project as sources and assigned them through styles so import type change will not affect any UXML or USS code.
I also think gradient backgrounds would be a nice feature to have natively.
Alternatively I agree that the SVG vector background on a Visual Elements (VE) is a good alternative solution.
I noticed that the border radius is ignored on the VE that has the background SVG, but if I add it to a container and give that the border radius with overflow:none; then it manages to make rounded corners and hide the background on the child. Is this the right way to do it?
This functionality needs to be here. Or can we get an update when it might be available? As a front-end dev I want UI Toolkit for Runtime to be my default UI solution… But when it doesn’t have basic functionality like this I just get discouraged.
Day 4 of using UI Toolkit and finding half a decade old request for basic functionality that requires hacks to make it work.
Day 1: No media queries
Day 2: No z index
Day 3: No aspect ratio
And now Day 4: No gradients
Anyway, thanks @nawash for the code. Here’s an updated version that adds one layer of wrapping so that you can use border on the gradient element.
I had it working with border without wrapping, but it didn’t work with border radius as it’s not trivial to calculate the rounded gradient.
So this one layer of wrapping fixes it and it’s working nicely.
public enum GradientDirection
{
Horizontal,
Vertical
}
[UxmlElement]
public partial class GradientElement : VisualElement
{
static readonly Vertex[] _vertices = new Vertex[4];
static readonly ushort[] _indices = { 0, 1, 2, 2, 3, 0 };
private VisualElement gradient;
[UxmlAttribute]
public GradientDirection GradientDirection { get; set; } = GradientDirection.Horizontal;
[UxmlAttribute]
public Color GradientFrom { get; set; }
[UxmlAttribute]
public Color GradientTo { get; set; }
public GradientElement()
{
this.style.overflow = Overflow.Hidden;
gradient = new VisualElement();
gradient.name = "Gradient";
gradient.style.width = new StyleLength(new Length(100, LengthUnit.Percent));
gradient.style.height = new StyleLength(new Length(100, LengthUnit.Percent));
gradient.generateVisualContent += GenerateVisualContent;
hierarchy.Add(gradient);
}
void GenerateVisualContent(MeshGenerationContext meshGenerationContext)
{
var rect = gradient.contentRect;
if (rect.width < 0.1f || rect.height < 0.1f)
{
return;
}
UpdateVerticesTint();
UpdateVerticesPosition(rect);
var meshWriteData = meshGenerationContext.Allocate(_vertices.Length, _indices.Length);
meshWriteData.SetAllVertices(_vertices);
meshWriteData.SetAllIndices(_indices);
}
static void UpdateVerticesPosition(Rect rect)
{
const float left = 0f;
var right = rect.width;
const float top = 0f;
var bottom = rect.height;
_vertices[0].position = new Vector3(left, bottom, Vertex.nearZ);
_vertices[1].position = new Vector3(left, top, Vertex.nearZ);
_vertices[2].position = new Vector3(right, top, Vertex.nearZ);
_vertices[3].position = new Vector3(right, bottom, Vertex.nearZ);
}
void UpdateVerticesTint()
{
if (GradientDirection is GradientDirection.Horizontal)
{
_vertices[0].tint = GradientFrom;
_vertices[1].tint = GradientFrom;
_vertices[2].tint = GradientTo;
_vertices[3].tint = GradientTo;
}
else
{
_vertices[0].tint = GradientTo;
_vertices[1].tint = GradientFrom;
_vertices[2].tint = GradientFrom;
_vertices[3].tint = GradientTo;
}
}
}
Edit: I realized I removed the custom USS as I don’t use it, haven’t tested that myself. If you need it I guess should be ok to add it back and propagate it.