200 lines
7.6 KiB
C#
200 lines
7.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Windows.UI.Composition;
|
|
using Windows.UI.Xaml;
|
|
using Windows.UI.Xaml.Hosting;
|
|
|
|
namespace Wino.Extensions;
|
|
|
|
public static partial class CompositionExtensions
|
|
{
|
|
public static void EnableFluidVisibilityAnimation(this UIElement element, AnimationAxis? axis = null,
|
|
float showFromOffset = 0.0f, float hideToOffset = 0.0f, Vector3? centerPoint = null,
|
|
float showFromScale = 1.0f, float hideToScale = 1.0f, float showDuration = 800.0f, float hideDuration = 800.0f,
|
|
int showDelay = 0, int hideDelay = 0, bool animateOpacity = true)
|
|
{
|
|
var elementVisual = element.Visual();
|
|
var compositor = elementVisual.Compositor;
|
|
ElementCompositionPreview.SetIsTranslationEnabled(element, true);
|
|
|
|
ScalarKeyFrameAnimation hideOpacityAnimation = null;
|
|
ScalarKeyFrameAnimation showOpacityAnimation = null;
|
|
ScalarKeyFrameAnimation hideOffsetAnimation = null;
|
|
ScalarKeyFrameAnimation showOffsetAnimation = null;
|
|
Vector2KeyFrameAnimation hideScaleAnimation = null;
|
|
Vector2KeyFrameAnimation showeScaleAnimation = null;
|
|
|
|
if (animateOpacity)
|
|
{
|
|
hideOpacityAnimation = compositor.CreateScalarKeyFrameAnimation();
|
|
hideOpacityAnimation.InsertKeyFrame(1.0f, 0.0f);
|
|
hideOpacityAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
|
|
hideOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
|
|
hideOpacityAnimation.Target = "Opacity";
|
|
}
|
|
|
|
if (!hideToOffset.Equals(0.0f))
|
|
{
|
|
hideOffsetAnimation = compositor.CreateScalarKeyFrameAnimation();
|
|
hideOffsetAnimation.InsertKeyFrame(1.0f, hideToOffset);
|
|
hideOffsetAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
|
|
hideOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
|
|
hideOffsetAnimation.Target = $"Translation.{axis}";
|
|
}
|
|
|
|
if (centerPoint.HasValue)
|
|
{
|
|
elementVisual.CenterPoint = centerPoint.Value;
|
|
}
|
|
|
|
if (!hideToScale.Equals(1.0f))
|
|
{
|
|
hideScaleAnimation = compositor.CreateVector2KeyFrameAnimation();
|
|
hideScaleAnimation.InsertKeyFrame(1.0f, new Vector2(hideToScale));
|
|
hideScaleAnimation.Duration = TimeSpan.FromMilliseconds(hideDuration);
|
|
hideScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(hideDelay);
|
|
hideScaleAnimation.Target = "Scale.XY";
|
|
}
|
|
|
|
var hideAnimationGroup = compositor.CreateAnimationGroup();
|
|
if (hideOpacityAnimation != null)
|
|
{
|
|
hideAnimationGroup.Add(hideOpacityAnimation);
|
|
}
|
|
if (hideOffsetAnimation != null)
|
|
{
|
|
hideAnimationGroup.Add(hideOffsetAnimation);
|
|
}
|
|
if (hideScaleAnimation != null)
|
|
{
|
|
hideAnimationGroup.Add(hideScaleAnimation);
|
|
}
|
|
|
|
ElementCompositionPreview.SetImplicitHideAnimation(element, hideAnimationGroup);
|
|
|
|
if (animateOpacity)
|
|
{
|
|
showOpacityAnimation = compositor.CreateScalarKeyFrameAnimation();
|
|
showOpacityAnimation.InsertKeyFrame(1.0f, 1.0f);
|
|
showOpacityAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
|
|
showOpacityAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
|
|
showOpacityAnimation.Target = "Opacity";
|
|
}
|
|
|
|
if (!showFromOffset.Equals(0.0f))
|
|
{
|
|
showOffsetAnimation = compositor.CreateScalarKeyFrameAnimation();
|
|
showOffsetAnimation.InsertKeyFrame(0.0f, showFromOffset);
|
|
showOffsetAnimation.InsertKeyFrame(1.0f, 0.0f);
|
|
showOffsetAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
|
|
showOffsetAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
|
|
showOffsetAnimation.Target = $"Translation.{axis}";
|
|
}
|
|
|
|
if (!showFromScale.Equals(1.0f))
|
|
{
|
|
showeScaleAnimation = compositor.CreateVector2KeyFrameAnimation();
|
|
showeScaleAnimation.InsertKeyFrame(0.0f, new Vector2(showFromScale));
|
|
showeScaleAnimation.InsertKeyFrame(1.0f, Vector2.One);
|
|
showeScaleAnimation.Duration = TimeSpan.FromMilliseconds(showDuration);
|
|
showeScaleAnimation.DelayTime = TimeSpan.FromMilliseconds(showDelay);
|
|
showeScaleAnimation.Target = "Scale.XY";
|
|
}
|
|
|
|
var showAnimationGroup = compositor.CreateAnimationGroup();
|
|
if (showOpacityAnimation != null)
|
|
{
|
|
showAnimationGroup.Add(showOpacityAnimation);
|
|
}
|
|
if (showOffsetAnimation != null)
|
|
{
|
|
showAnimationGroup.Add(showOffsetAnimation);
|
|
}
|
|
if (showeScaleAnimation != null)
|
|
{
|
|
showAnimationGroup.Add(showeScaleAnimation);
|
|
}
|
|
|
|
ElementCompositionPreview.SetImplicitShowAnimation(element, showAnimationGroup);
|
|
}
|
|
|
|
public static void EnableImplicitAnimation(this UIElement element, VisualPropertyType typeToAnimate,
|
|
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
|
|
{
|
|
var visual = element.Visual();
|
|
var compositor = visual.Compositor;
|
|
|
|
var animationCollection = compositor.CreateImplicitAnimationCollection();
|
|
|
|
foreach (var type in UtilExtensions.GetValues<VisualPropertyType>())
|
|
{
|
|
if (!typeToAnimate.HasFlag(type)) continue;
|
|
|
|
var animation = CreateAnimationByType(compositor, type, duration, delay, easing);
|
|
|
|
if (animation != null)
|
|
{
|
|
animationCollection[type.ToString()] = animation;
|
|
}
|
|
}
|
|
|
|
visual.ImplicitAnimations = animationCollection;
|
|
}
|
|
|
|
public static void EnableImplicitAnimation(this Visual visual, VisualPropertyType typeToAnimate,
|
|
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
|
|
{
|
|
var compositor = visual.Compositor;
|
|
|
|
var animationCollection = compositor.CreateImplicitAnimationCollection();
|
|
|
|
foreach (var type in UtilExtensions.GetValues<VisualPropertyType>())
|
|
{
|
|
if (!typeToAnimate.HasFlag(type)) continue;
|
|
|
|
var animation = CreateAnimationByType(compositor, type, duration, delay, easing);
|
|
|
|
if (animation != null)
|
|
{
|
|
animationCollection[type.ToString()] = animation;
|
|
}
|
|
}
|
|
|
|
visual.ImplicitAnimations = animationCollection;
|
|
}
|
|
|
|
private static KeyFrameAnimation CreateAnimationByType(Compositor compositor, VisualPropertyType type,
|
|
double duration = 800, double delay = 0, CompositionEasingFunction easing = null)
|
|
{
|
|
KeyFrameAnimation animation;
|
|
|
|
switch (type)
|
|
{
|
|
case VisualPropertyType.Offset:
|
|
case VisualPropertyType.Scale:
|
|
animation = compositor.CreateVector3KeyFrameAnimation();
|
|
break;
|
|
case VisualPropertyType.Size:
|
|
animation = compositor.CreateVector2KeyFrameAnimation();
|
|
break;
|
|
case VisualPropertyType.Opacity:
|
|
case VisualPropertyType.RotationAngleInDegrees:
|
|
animation = compositor.CreateScalarKeyFrameAnimation();
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
animation.InsertExpressionKeyFrame(1.0f, "this.FinalValue", easing);
|
|
animation.Duration = TimeSpan.FromMilliseconds(duration);
|
|
animation.DelayTime = TimeSpan.FromMilliseconds(delay);
|
|
animation.Target = type.ToString();
|
|
|
|
return animation;
|
|
}
|
|
}
|