Exemplo n.º 1
0
        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));
        }