Example #1
0
        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));
        }
Example #2
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));
        }
Example #3
0
        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));
        }