public static async Task <AttachedAnimatableCompositionEffect <T> > AttachCompositionAnimatableInAppCustomAcrylicEffectAsync <TSource, T>( [NotNull] this TSource element, [NotNull] T target, float on, float off, bool initiallyVisible, Color color, float colorMix, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri, int timeThreshold = 1000, bool reload = false, bool disposeOnUnload = false) where TSource : FrameworkElement where T : FrameworkElement { // Get the compositor Visual visual = await DispatcherHelper.GetFromUIThreadAsync(element.GetVisual); Compositor compositor = visual.Compositor; // Create the blur effect and the effect factory CompositionBackdropBrush backdropBrush = compositor.CreateBackdropBrush(); GaussianBlurEffect blurEffect = new GaussianBlurEffect { Name = "Blur", BlurAmount = 0f, BorderMode = EffectBorderMode.Hard, Optimization = EffectOptimization.Balanced, Source = new CompositionEffectSourceParameter(nameof(backdropBrush)) }; const String animationPropertyName = "Blur.BlurAmount"; // Prepare the dictionary with the parameters to add IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush> { { nameof(backdropBrush), backdropBrush } }; // Get the noise brush using Win2D IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor, blurEffect, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload); // Make sure the Win2D brush was loaded correctly CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(source, new[] { animationPropertyName }); // Create the effect factory and apply the final effect CompositionEffectBrush effectBrush = effectFactory.CreateBrush(); foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters) { effectBrush.SetSourceParameter(pair.Key, pair.Value); } // Assign the effect to a brush and display it SpriteVisual sprite = compositor.CreateSpriteVisual(); sprite.Brush = effectBrush; await AddToTreeAndBindSizeAsync(target.GetVisual(), target, sprite); if (initiallyVisible) { await DispatcherHelper.RunOnUIThreadAsync(() => element.Opacity = 1); } return(new AttachedAnimatableCompositionEffect <T>(target, sprite, new CompositionAnimationParameters(animationPropertyName, on, off), disposeOnUnload)); }
public static async Task <AttachedStaticCompositionEffect <T> > AttachCompositionInAppCustomAcrylicEffectAsync <TSource, T>( [NotNull] this TSource element, [NotNull] T target, float blur, int ms, Color color, float colorMix, float?saturation, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri, int timeThreshold = 1000, bool reload = false, bool fadeIn = false, bool disposeOnUnload = false) where TSource : FrameworkElement where T : FrameworkElement { // Percentage check if (saturation < 0 || saturation > 1) { throw new ArgumentOutOfRangeException("The input saturation value must be in the [0,1] range"); } if (colorMix <= 0 || colorMix >= 1) { throw new ArgumentOutOfRangeException("The mix factors must be in the [0,1] range"); } if (timeThreshold <= 0) { throw new ArgumentOutOfRangeException("The time threshold must be a positive number"); } // Setup the compositor Visual visual = ElementCompositionPreview.GetElementVisual(element); Compositor compositor = visual.Compositor; // Prepare a luminosity to alpha effect to adjust the background contrast CompositionBackdropBrush backdropBrush = compositor.CreateBackdropBrush(); const String blurName = "Blur", blurParameterName = "Blur.BlurAmount"; GaussianBlurEffect blurEffect = new GaussianBlurEffect { Name = blurName, BlurAmount = 0f, BorderMode = EffectBorderMode.Hard, Optimization = EffectOptimization.Balanced, Source = new CompositionEffectSourceParameter(nameof(backdropBrush)) }; // Background with blur and tint overlay IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush> { { nameof(backdropBrush), backdropBrush } }; // Get the noise brush using Win2D IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor, blurEffect, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload); // Add the final saturation effect if needed if (saturation != null) { SaturationEffect saturationEffect = new SaturationEffect { Saturation = saturation.Value, Source = source }; source = saturationEffect; } // Make sure the Win2D brush was loaded correctly CompositionEffectFactory factory = compositor.CreateEffectFactory(source, new[] { blurParameterName }); // Create the effect factory and apply the final effect CompositionEffectBrush effectBrush = factory.CreateBrush(); foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters) { effectBrush.SetSourceParameter(pair.Key, pair.Value); } // Create the sprite to display and add it to the visual tree SpriteVisual sprite = compositor.CreateSpriteVisual(); sprite.Brush = effectBrush; // Assign the visual if (fadeIn) { sprite.StopAnimation("Opacity"); sprite.Opacity = 0; } await AddToTreeAndBindSizeAsync(target.GetVisual(), target, sprite); if (fadeIn) { // Fade the effect in ScalarKeyFrameAnimation opacityAnimation = sprite.Compositor.CreateScalarKeyFrameAnimation(1, 0, TimeSpan.FromMilliseconds(ms), null, sprite.GetEasingFunction(EasingFunctionNames.Linear)); sprite.StartAnimation("Opacity", opacityAnimation); } // Animate the blur and return the result effectBrush.StartAnimationAsync(blurParameterName, blur, TimeSpan.FromMilliseconds(ms)).Forget(); return(new AttachedStaticCompositionEffect <T>(target, sprite, disposeOnUnload)); }
public static async Task <AttachedStaticCompositionEffect <T> > AttachCompositionCustomAcrylicEffectAsync <T>( [NotNull] this T element, Color color, float colorMix, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri, int timeThreshold = 1000, bool reload = false, bool disposeOnUnload = false) where T : FrameworkElement { // Percentage check if (colorMix <= 0 || colorMix >= 1) { throw new ArgumentOutOfRangeException("The mix factors must be in the [0,1] range"); } if (timeThreshold <= 0) { throw new ArgumentOutOfRangeException("The time threshold must be a positive number"); } // Setup the compositor Visual visual = ElementCompositionPreview.GetElementVisual(element); Compositor compositor = visual.Compositor; // Prepare a luminosity to alpha effect to adjust the background contrast CompositionBackdropBrush hostBackdropBrush = compositor.CreateHostBackdropBrush(); CompositionEffectSourceParameter backgroundParameter = new CompositionEffectSourceParameter(nameof(hostBackdropBrush)); LuminanceToAlphaEffect alphaEffect = new LuminanceToAlphaEffect { Source = backgroundParameter }; OpacityEffect opacityEffect = new OpacityEffect { Source = alphaEffect, Opacity = 0.4f // Reduce the amount of the effect to avoid making bright areas completely black }; // Layer [0,1,3] - Desktop background with blur and tint overlay BlendEffect alphaBlend = new BlendEffect { Background = backgroundParameter, Foreground = opacityEffect, Mode = BlendEffectMode.Overlay }; IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush> { { nameof(hostBackdropBrush), hostBackdropBrush } }; // Get the noise brush using Win2D IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor, alphaBlend, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload); // Make sure the Win2D brush was loaded correctly CompositionEffectFactory factory = compositor.CreateEffectFactory(source); // Create the effect factory and apply the final effect CompositionEffectBrush effectBrush = factory.CreateBrush(); foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters) { effectBrush.SetSourceParameter(pair.Key, pair.Value); } // Create the sprite to display and add it to the visual tree SpriteVisual sprite = compositor.CreateSpriteVisual(); sprite.Brush = effectBrush; await AddToTreeAndBindSizeAsync(visual, element, sprite); return(new AttachedStaticCompositionEffect <T>(element, sprite, disposeOnUnload)); }