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"> <Style Selector="Border.Rect10">
<Setter Property="Transitions"> <Setter Property="Transitions">
<Transitions> <Transitions>
<ISolidColorBrushTransition Property="Background" Duration="0:0:0.5" /> <BrushTransition Property="Background" Duration="0:0:0.5" />
</Transitions> </Transitions>
</Setter> </Setter>
<Setter Property="Background" Value="Red" /> <Setter Property="Background" Value="Red" />
@ -154,6 +154,26 @@
<Style Selector="Border.Rect10:pointerover"> <Style Selector="Border.Rect10:pointerover">
<Setter Property="Background" Value="Orange" /> <Setter Property="Background" Value="Orange" />
</Style> </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> </Styles>
</UserControl.Styles> </UserControl.Styles>
@ -181,6 +201,7 @@
<Border Classes="Test Shadow" CornerRadius="0 30 60 0" Child="{x:Null}" /> <Border Classes="Test Shadow" CornerRadius="0 30 60 0" Child="{x:Null}" />
<Border Classes="Test Rect10" /> <Border Classes="Test Rect10" />
<Border Classes="Test Rect11" />
</WrapPanel> </WrapPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>

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

@ -1,29 +1,67 @@
using System; using System;
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
using Avalonia.Animation.Easings;
using Avalonia.Media; using Avalonia.Media;
#nullable enable
namespace Avalonia.Animation namespace Avalonia.Animation
{ {
/// <summary> /// <summary>
/// Transition class that handles <see cref="AvaloniaProperty"/> with <see cref="IBrush"/> type. /// 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> /// </summary>
public class ISolidColorBrushTransition : Transition<IBrush> public class BrushTransition : Transition<IBrush?>
{ {
private static readonly ISolidColorBrushAnimator s_animator = new ISolidColorBrushAnimator(); 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); if (brush is null)
var newSolidBrush = AsImmutable(newValue); {
return Brushes.Transparent;
}
return new AnimatorTransitionObservable<ISolidColorBrush, ISolidColorBrushAnimator>( return brush as ISolidColorBrush;
s_animator, progress, Easing, oldSolidBrush, newSolidBrush);
} }
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