FadeThroughTransition.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using Avalonia;
  6. using Avalonia.Animation;
  7. using Avalonia.Animation.Easings;
  8. using Avalonia.Media;
  9. using Avalonia.Styling;
  10. namespace ControlCatalog.Pages
  11. {
  12. /// <summary>
  13. /// Example custom IPageTransition: a "fade through" with scale.
  14. /// The outgoing page fades out while scaling down; the incoming page fades in while
  15. /// scaling up, producing a smooth depth-aware transition.
  16. /// </summary>
  17. public class FadeThroughTransition : IPageTransition
  18. {
  19. public FadeThroughTransition() { }
  20. public FadeThroughTransition(TimeSpan duration)
  21. {
  22. Duration = duration;
  23. }
  24. public TimeSpan Duration { get; set; } = TimeSpan.FromMilliseconds(300);
  25. public Easing FadeEasing { get; set; } = new CubicEaseOut();
  26. public async Task Start(Visual? from, Visual? to, bool forward, CancellationToken cancellationToken)
  27. {
  28. if (cancellationToken.IsCancellationRequested)
  29. return;
  30. var tasks = new List<Task>();
  31. if (from != null)
  32. {
  33. from.RenderTransformOrigin = RelativePoint.Center;
  34. from.RenderTransform = new ScaleTransform(1, 1);
  35. }
  36. if (to != null)
  37. {
  38. to.RenderTransformOrigin = RelativePoint.Center;
  39. to.RenderTransform = new ScaleTransform(1, 1);
  40. to.Opacity = 0;
  41. }
  42. if (from != null)
  43. {
  44. var outAnim = new Avalonia.Animation.Animation
  45. {
  46. FillMode = FillMode.Forward,
  47. Easing = FadeEasing,
  48. Duration = Duration,
  49. Children =
  50. {
  51. new KeyFrame
  52. {
  53. Cue = new Cue(0d),
  54. Setters =
  55. {
  56. new Setter(Visual.OpacityProperty, 1d),
  57. new Setter(ScaleTransform.ScaleXProperty, 1d),
  58. new Setter(ScaleTransform.ScaleYProperty, 1d)
  59. }
  60. },
  61. new KeyFrame
  62. {
  63. Cue = new Cue(1d),
  64. Setters =
  65. {
  66. new Setter(Visual.OpacityProperty, 0d),
  67. new Setter(ScaleTransform.ScaleXProperty, forward ? 0.92 : 1.08),
  68. new Setter(ScaleTransform.ScaleYProperty, forward ? 0.92 : 1.08)
  69. }
  70. }
  71. }
  72. };
  73. tasks.Add(outAnim.RunAsync(from, cancellationToken));
  74. }
  75. if (to != null)
  76. {
  77. to.IsVisible = true;
  78. var inAnim = new Avalonia.Animation.Animation
  79. {
  80. FillMode = FillMode.Forward,
  81. Easing = FadeEasing,
  82. Duration = Duration,
  83. Children =
  84. {
  85. new KeyFrame
  86. {
  87. Cue = new Cue(0d),
  88. Setters =
  89. {
  90. new Setter(Visual.OpacityProperty, 0d),
  91. new Setter(ScaleTransform.ScaleXProperty, forward ? 1.08 : 0.92),
  92. new Setter(ScaleTransform.ScaleYProperty, forward ? 1.08 : 0.92)
  93. }
  94. },
  95. new KeyFrame
  96. {
  97. Cue = new Cue(1d),
  98. Setters =
  99. {
  100. new Setter(Visual.OpacityProperty, 1d),
  101. new Setter(ScaleTransform.ScaleXProperty, 1d),
  102. new Setter(ScaleTransform.ScaleYProperty, 1d)
  103. }
  104. }
  105. }
  106. };
  107. tasks.Add(inAnim.RunAsync(to, cancellationToken));
  108. }
  109. await Task.WhenAll(tasks);
  110. if (to != null && !cancellationToken.IsCancellationRequested)
  111. {
  112. to.Opacity = 1;
  113. to.RenderTransform = null;
  114. }
  115. if (from != null)
  116. {
  117. if (!cancellationToken.IsCancellationRequested)
  118. from.IsVisible = false;
  119. from.Opacity = 1;
  120. from.RenderTransform = null;
  121. }
  122. }
  123. }
  124. }