Skip to content

[Spec] Brushes #11

@jsuarezruiz

Description

@jsuarezruiz

Brushes

A gradient is the gradual blending from one color to another.

But, hey, why gradients?

Mobile design trends have changed rapidly in recent years, with some things disappearing for a while and then making a gradual comeback. That’s the case with gradients. Gradients are making a comeback.

gradients

API

Next, the Brushes API definition.

NOTE: This API definition is based on WPF Brushes API: https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/wpf-brushes-overview

Brush

Defines objects used to paint graphical objects. Classes that derive from Brush describe how the area is painted.

public abstract class Brush : BindableObject
{

}

SolidColorBrush

A SolidColorBrush paints an area with a solid Color.

public class SolidColorBrush : Brush
{
    public SolidColorBrush() { }

    public SolidColorBrush(Color color)
    {
        Color = color;
    }

    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        nameof(Color), typeof(Color), typeof(SolidColorBrush), Color.Default);

    public Color Color
    {
        get => (Color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }
}

solidcolorbrush

NOTE: For convenience, the Brushes class provides a set of commonly used SolidColorBrush objects, such as Blue and Yellow.

GradientBrush

A gradient brush paints an area with multiple colors that blend into each other along an axis.
The GradientBrush definition:

[ContentProperty(nameof(GradientStops))]
public class GradientBrush : Brush
{
    public static readonly BindableProperty GradientStopsProperty = BindableProperty.Create(
        nameof(GradientStops), typeof(IList<GradientStop>), typeof(GradientBrush), null);

    public IList<GradientStop> GradientStops
    {
        get => (IList<GradientStop>)GetValue(GradientStopsProperty);
        set => SetValue(GradientStopsProperty, value);
    }
}

The GradientStop is the basic building block of a gradient brush. A gradient stop specifies a Color at an Offset along the gradient axis.

public class GradientStop : BindableObject
{
    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        nameof(Color), typeof(Color), typeof(GradientStop), Color.White);

    public Color Color
    {
        get => (Color)GetValue(ColorProperty);
        set => SetValue(ColorProperty, value);
    }

    public static readonly BindableProperty OffsetProperty = BindableProperty.Create(
        nameof(Offset), typeof(float), typeof(GradientStop), 0f);

    public float Offset
    {
        get => (float)GetValue(OffsetProperty);
        set => SetValue(OffsetProperty, value);
    }
}

We will add a new property to IView to define the background using Brushes.

public static readonly BindableProperty BackgroundProperty = 
     BindableProperty.Create("Background", typeof(GradientBrush), typeof(VisualElement), default(GradientBrush));

This would allow gradients to be used as background in any control, although the BackgroundColor property would still exist (deprecated).

LinearGradientBrush

A LinearGradientBrush paints an area with a gradient that's defined along a line. This line is called the gradient axis.
You specify the gradient's colors and their locations along the gradient axis using GradientStop objects. By default, the gradient axis runs from the upper left corner to the lower right corner of the area that the brush paints, resulting in a diagonal shading.

LinearGradientBrush

public class LinearGradientBrush : GradientBrush
{
    public static readonly BindableProperty StartPointProperty = BindableProperty.Create(
        nameof(StartPoint), typeof(Point), typeof(LinearGradientBrush), default(Point));

    public Point StartPoint
    {
        get => (Point)GetValue(StartPointProperty);
        set => SetValue(StartPointProperty, value);
    }

    public static readonly BindableProperty EndPointProperty = BindableProperty.Create(
        nameof(EndPoint), typeof(Point), typeof(LinearGradientBrush), default(Point));

    public Point EndPoint
    {
        get => (Point)GetValue(EndPointProperty);
        set => SetValue(EndPointProperty, value);
    }
}

RadialGradientBrush

A radial gradient brush paints an area with a radial gradient that has a circle, along with a focal point, to define the gradient behavior. The focal point defines the center of the gradient and has default value 0.0.

RadialGradientBrush

public class RadialGradientBrush : GradientBrush
{
    public static readonly BindableProperty CenterProperty = BindableProperty.Create(
        nameof(Center), typeof(Point), typeof(RadialGradientBrush), default(Point));

    public Point Center
    {
        get => (Point)GetValue(CenterProperty);
        set => SetValue(CenterProperty, value);
    }

    public static readonly BindableProperty GradientOriginProperty = BindableProperty.Create(
        nameof(GradientOrigin), typeof(Point), typeof(RadialGradientBrush), default(Point));

    public Point GradientOrigin
    {
        get => (Point)GetValue(GradientOriginProperty);
        set => SetValue(GradientOriginProperty, value);
    }

    public static readonly BindableProperty RadiusXProperty = BindableProperty.Create(
        nameof(RadiusX), typeof(double), typeof(RadialGradientBrush), default(Point));

    public double RadiusX
    {
        get => (double)GetValue(RadiusXProperty);
        set => SetValue(RadiusXProperty, value);
    }

    public static readonly BindableProperty RadiusYProperty = BindableProperty.Create(
        nameof(RadiusY), typeof(double), typeof(RadialGradientBrush), default(Point));

    public double RadiusY
    {
        get => (double)GetValue(RadiusYProperty);
        set => SetValue(RadiusYProperty, value);
    }
}

Scenarios

Let's take a look at a simple sample:

XAML

<Grid>
    <Grid.Background>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="Yellow" Offset="0.0" />
            <GradientStop Color="Red" Offset="0.25" />
            <GradientStop Color="Blue" Offset="0.75" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
        </LinearGradientBrush>
    </Grid.Background>
<Grid>

CSS

(see #7374)

#RootContainer{
    background: linear-gradient(45deg, rgba(218, 64, 244, 0.26) 0%, rgba(218, 64, 244, 0.26) 3%,rgba(184, 81, 207, 0.26) 3%, rgba(184, 81, 207, 0.26) 26%,rgba(149, 97, 169, 0.26) 26%, rgba(149, 97, 169, 0.26) 27%,rgba(115, 114, 132, 0.26) 27%, rgba(115, 114, 132, 0.26) 46%,rgba(80, 130, 94, 0.26) 46%, rgba(80, 130, 94, 0.26) 87%,rgba(46, 147, 57, 0.26) 87%, rgba(46, 147, 57, 0.26) 100%),linear-gradient(0deg, rgba(247, 80, 105, 0.26) 0%, rgba(247, 80, 105, 0.26) 1%,rgba(223, 84, 119, 0.26) 1%, rgba(223, 84, 119, 0.26) 11%,rgba(199, 88, 133, 0.26) 11%, rgba(199, 88, 133, 0.26) 46%,rgba(174, 91, 147, 0.26) 46%, rgba(174, 91, 147, 0.26) 54%,rgba(150, 95, 161, 0.26) 54%, rgba(150, 95, 161, 0.26) 73%,rgba(126, 99, 175, 0.26) 73%, rgba(126, 99, 175, 0.26) 100%),linear-gradient(90deg, rgb(74, 13, 231) 0%, rgb(74, 13, 231) 18%,rgb(96, 13, 230) 18%, rgb(96, 13, 230) 21%,rgb(119, 13, 229) 21%, rgb(119, 13, 229) 26%,rgb(141, 13, 228) 26%, rgb(141, 13, 228) 32%,rgb(163, 12, 226) 32%, rgb(163, 12, 226) 44%,rgb(185, 12, 225) 44%, rgb(185, 12, 225) 56%,rgb(208, 12, 224) 56%, rgb(208, 12, 224) 64%,rgb(230, 12, 223) 64%, rgb(230, 12, 223) 100%)
}

Scope

The Background property will be available in all the views.

Difficulty : Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions