Files
Wino-Mail/Wino.Core.UWP/Extensions/CompositionExtensions.Implicit.cs
2025-02-16 11:54:23 +01:00

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;
}
}