Ejemplo n.º 1
0
        /// <summary>
        /// Creates a reflection of the given Visual
        /// </summary>
        /// <param name="visual">Visual whose reflection has to be created</param>
        /// <param name="reflectionDistance">Distance of the reflection from the visual</param>
        /// <param name="reflectionLength">Normalized Length of the reflected visual that will be visible.</param>
        /// <param name="location"> <see cref="ReflectionLocation"/> - Location of the reflection with respect
        /// to the Visual - Bottom, Top, Left or Right</param>
        public void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f,
                                     float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom)
        {
            // Create the visual layer that will contained the visual's reflection
            var reflectionLayer = _compositor.CreateLayerVisual();

            reflectionLayer.Size        = visual.Size;
            reflectionLayer.CenterPoint = new Vector3(visual.Size * 0.5f, 0);

            // Create the effect to create the opacity mask
            var effect = new CompositeEffect
            {
                // CanvasComposite.DestinationIn - Intersection of source and mask.
                // Equation: O = MA * S
                // where O - Output pixel, MA - Mask Alpha, S - Source pixel.
                Mode    = CanvasComposite.DestinationIn,
                Sources =
                {
                    new CompositionEffectSourceParameter("source"),
                    new CompositionEffectSourceParameter("mask")
                }
            };

            var effectFactory = _compositor.CreateEffectFactory(effect);
            var effectBrush   = effectFactory.CreateBrush();

            // Create the gradient brush for the effect
            CanvasLinearGradientBrush gradientBrush = new CanvasLinearGradientBrush(_canvasDevice,
                                                                                    Colors.White, Colors.Transparent);

            // Based on the reflection location,
            // Set the Offset, RotationAxis and RotationAngleInDegrees of the reflectionLayer and
            // set the StartPoint and EndPoint of the gradientBrush
            switch (location)
            {
            case ReflectionLocation.Bottom:
                reflectionLayer.RotationAxis           = new Vector3(1, 0, 0);
                reflectionLayer.RotationAngleInDegrees = 180;
                reflectionLayer.Offset   = new Vector3(0, visual.Size.Y + reflectionDistance, 0);
                gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, 0);
                gradientBrush.EndPoint   = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * reflectionLength);
                break;

            case ReflectionLocation.Top:
                reflectionLayer.RotationAxis           = new Vector3(1, 0, 0);
                reflectionLayer.RotationAngleInDegrees = -180;
                reflectionLayer.Offset   = new Vector3(0, -visual.Size.Y - reflectionDistance, 0);
                gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y);
                gradientBrush.EndPoint   = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * (1f - reflectionLength));
                break;

            case ReflectionLocation.Left:
                reflectionLayer.RotationAxis           = new Vector3(0, 1, 0);
                reflectionLayer.RotationAngleInDegrees = -180;
                reflectionLayer.Offset   = new Vector3(-visual.Size.X - reflectionDistance, 0, 0);
                gradientBrush.StartPoint = new Vector2(visual.Size.X, visual.Size.Y * 0.5f);
                gradientBrush.EndPoint   = new Vector2(visual.Size.X * (1f - reflectionLength), visual.Size.Y * 0.5f);
                break;

            case ReflectionLocation.Right:
                reflectionLayer.RotationAxis           = new Vector3(0, 1, 0);
                reflectionLayer.RotationAngleInDegrees = 180;
                reflectionLayer.Offset   = new Vector3(visual.Size.X + reflectionDistance, 0, 0);
                gradientBrush.StartPoint = new Vector2(0, visual.Size.Y * 0.5f);
                gradientBrush.EndPoint   = new Vector2(visual.Size.X * reflectionLength, visual.Size.Y * 0.5f);
                break;
            }

            // Create a mask filled with gradientBrush
            var mask = CreateMask(visual.Size.ToSize(), null, gradientBrush);

            // Set the 'mask' parameter of the effectBrush
            effectBrush.SetSourceParameter("mask", _compositor.CreateSurfaceBrush(mask.Surface));

            // Set the effect for the reflection layer
            reflectionLayer.Effect = effectBrush;

            // Now we need to duplicate the visual tree of the visual
            ArrangeVisualReflection(visual, reflectionLayer, true);

            visual.Children.InsertAtTop(reflectionLayer);
        }
        /// <summary>
        /// Creates a reflection of the given Visual
        /// </summary>
        /// <param name="visual">Visual whose reflection has to be created</param>
        /// <param name="reflectionDistance">Distance of the reflection from the visual</param>
        /// <param name="reflectionLength">Normalized Length of the reflected visual that will be visible.</param>
        /// <param name="location"> <see cref="ReflectionLocation"/> - Location of the reflection with respect 
        /// to the Visual - Bottom, Top, Left or Right</param>
        public void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f,
            float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom)
        {
            // Create the visual layer that will contained the visual's reflection
            var reflectionLayer = _compositor.CreateLayerVisual();
            reflectionLayer.Size = visual.Size;
            reflectionLayer.CenterPoint = new Vector3(visual.Size * 0.5f, 0);

            // Create the effect to create the opacity mask
            var effect = new CompositeEffect
            {
                // CanvasComposite.DestinationIn - Intersection of source and mask. 
                // Equation: O = MA * S
                // where O - Output pixel, MA - Mask Alpha, S - Source pixel.
                Mode = CanvasComposite.DestinationIn,
                Sources =
                        {
                            new CompositionEffectSourceParameter("source"),
                            new CompositionEffectSourceParameter("mask")
                        }
            };

            var effectFactory = _compositor.CreateEffectFactory(effect);
            var effectBrush = effectFactory.CreateBrush();

            // Create the gradient brush for the effect
            var gradientBrush = new CanvasLinearGradientBrush(_canvasDevice,
                                                                Colors.White, Colors.Transparent);

            // Based on the reflection location,
            // Set the Offset, RotationAxis and RotationAngleInDegrees of the reflectionLayer and
            // set the StartPoint and EndPoint of the gradientBrush
            switch (location)
            {
                case ReflectionLocation.Bottom:
                    reflectionLayer.RotationAxis = new Vector3(1, 0, 0);
                    reflectionLayer.RotationAngleInDegrees = 180;
                    reflectionLayer.Offset = new Vector3(0, visual.Size.Y + reflectionDistance, 0);
                    gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, 0);
                    gradientBrush.EndPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * reflectionLength);
                    break;
                case ReflectionLocation.Top:
                    reflectionLayer.RotationAxis = new Vector3(1, 0, 0);
                    reflectionLayer.RotationAngleInDegrees = -180;
                    reflectionLayer.Offset = new Vector3(0, -visual.Size.Y - reflectionDistance, 0);
                    gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y);
                    gradientBrush.EndPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * (1f - reflectionLength));
                    break;
                case ReflectionLocation.Left:
                    reflectionLayer.RotationAxis = new Vector3(0, 1, 0);
                    reflectionLayer.RotationAngleInDegrees = -180;
                    reflectionLayer.Offset = new Vector3(-visual.Size.X - reflectionDistance, 0, 0);
                    gradientBrush.StartPoint = new Vector2(visual.Size.X, visual.Size.Y * 0.5f);
                    gradientBrush.EndPoint = new Vector2(visual.Size.X * (1f - reflectionLength), visual.Size.Y * 0.5f);
                    break;
                case ReflectionLocation.Right:
                    reflectionLayer.RotationAxis = new Vector3(0, 1, 0);
                    reflectionLayer.RotationAngleInDegrees = 180;
                    reflectionLayer.Offset = new Vector3(visual.Size.X + reflectionDistance, 0, 0);
                    gradientBrush.StartPoint = new Vector2(0, visual.Size.Y * 0.5f);
                    gradientBrush.EndPoint = new Vector2(visual.Size.X * reflectionLength, visual.Size.Y * 0.5f);
                    break;
            }

            // Create a mask filled with gradientBrush
            var mask = CreateGeometrySurface(visual.Size.ToSize(), null, Colors.Transparent, gradientBrush);

            // Set the 'mask' parameter of the effectBrush
            effectBrush.SetSourceParameter("mask", _compositor.CreateSurfaceBrush(mask.Surface));

            // Set the effect for the reflection layer
            reflectionLayer.Effect = effectBrush;

            // Now we need to duplicate the visual tree of the visual
            ArrangeVisualReflection(visual, reflectionLayer, true);

            visual.Children.InsertAtTop(reflectionLayer);
        }