Browse Source

Unify brush transition. Handle brush type mismatch in a nicer way.

pull/6029/head
Dariusz Komosinski 5 years ago
parent
commit
c48a516ec6
  1. 23
      samples/RenderDemo/Pages/TransitionsPage.xaml
  2. 56
      src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs

23
samples/RenderDemo/Pages/TransitionsPage.xaml

@ -145,7 +145,7 @@
<Style Selector="Border.Rect10">
<Setter Property="Transitions">
<Transitions>
<ISolidColorBrushTransition Property="Background" Duration="0:0:0.5" />
<BrushTransition Property="Background" Duration="0:0:0.5" />
</Transitions>
</Setter>
<Setter Property="Background" Value="Red" />
@ -154,6 +154,26 @@
<Style Selector="Border.Rect10:pointerover">
<Setter Property="Background" Value="Orange" />
</Style>
<Style Selector="Border.Rect11">
<Setter Property="Transitions">
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.5" />
</Transitions>
</Setter>
<Setter Property="Background" Value="Red" />
</Style>
<Style Selector="Border.Rect11:pointerover">
<Setter Property="Background" >
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="Red"/>
<GradientStop Offset="1" Color="Blue"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter>
</Style>
</Styles>
</UserControl.Styles>
@ -181,6 +201,7 @@
<Border Classes="Test Shadow" CornerRadius="0 30 60 0" Child="{x:Null}" />
<Border Classes="Test Rect10" />
<Border Classes="Test Rect11" />
</WrapPanel>
</StackPanel>
</Grid>

56
src/Avalonia.Visuals/Animation/Transitions/BrushTransition.cs

@ -1,29 +1,67 @@
using System;
using Avalonia.Animation.Animators;
using Avalonia.Animation.Easings;
using Avalonia.Media;
#nullable enable
namespace Avalonia.Animation
{
/// <summary>
/// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="IBrush"/> type.
/// Only values of <see cref="ISolidColorBrush"/> will correctly transition.
/// Only values of <see cref="ISolidColorBrush"/> will transition correctly at the moment.
/// </summary>
public class ISolidColorBrushTransition : Transition<IBrush>
public class BrushTransition : Transition<IBrush?>
{
private static readonly ISolidColorBrushAnimator s_animator = new ISolidColorBrushAnimator();
public override IObservable<IBrush> DoTransition(IObservable<double> progress, IBrush oldValue, IBrush newValue)
public override IObservable<IBrush?> DoTransition(IObservable<double> progress, IBrush? oldValue, IBrush? newValue)
{
var oldSolidColorBrush = TryGetSolidColorBrush(oldValue);
var newSolidColorBrush = TryGetSolidColorBrush(newValue);
if (oldSolidColorBrush != null && newSolidColorBrush != null)
{
EnsureImmutable(ref oldSolidColorBrush);
EnsureImmutable(ref newSolidColorBrush);
return new AnimatorTransitionObservable<ISolidColorBrush, ISolidColorBrushAnimator>(
s_animator, progress, Easing, oldSolidColorBrush, newSolidColorBrush);
}
return new IncompatibleTransitionObservable(progress, Easing, oldValue, newValue);
}
private static void EnsureImmutable(ref ISolidColorBrush brush)
{
brush = (ISolidColorBrush)brush.ToImmutable();
}
private static ISolidColorBrush? TryGetSolidColorBrush(IBrush? brush)
{
var oldSolidBrush = AsImmutable(oldValue);
var newSolidBrush = AsImmutable(newValue);
if (brush is null)
{
return Brushes.Transparent;
}
return new AnimatorTransitionObservable<ISolidColorBrush, ISolidColorBrushAnimator>(
s_animator, progress, Easing, oldSolidBrush, newSolidBrush);
return brush as ISolidColorBrush;
}
private static ISolidColorBrush AsImmutable(IBrush brush)
private class IncompatibleTransitionObservable : TransitionObservableBase<IBrush?>
{
return (ISolidColorBrush)(brush as ISolidColorBrush)?.ToImmutable();
private readonly IBrush? _from;
private readonly IBrush? _to;
public IncompatibleTransitionObservable(IObservable<double> progress, Easing easing, IBrush? from, IBrush? to) : base(progress, easing)
{
_from = @from;
_to = to;
}
protected override IBrush? ProduceValue(double progress)
{
return progress < 0.5 ? _from : _to;
}
}
}
}

Loading…
Cancel
Save