Beispiel #1
0
        private void InitComposition()
        {
            _compositor = Window.Current.Compositor;
            _generator  = _compositor.CreateCompositionGenerator();

            _angle  = 0f;
            _width  = 300f;
            _height = 300f;
            // Create the combined geometry
            var ellipse1 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.45f * _width, 0.225f * _height);
            var ellipse2 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.225f * _width, 0.45f * _height);

            _geometry = ellipse1.CombineWith(ellipse2, Matrix3x2.Identity, CanvasGeometryCombine.Union);

            _visual1        = _compositor.CreateSpriteVisual();
            _visual1.Size   = new Vector2(_width, _height);
            _visual1.Offset = new Vector3(((RenderGrid.ActualWidth - _width) / 2).ToSingle(),
                                          ((RenderGrid.ActualHeight - _height) / 2).ToSingle(), 0);

            _geometrySurface = _generator.CreateGeometrySurface(_visual1.Size.ToSize(), _geometry, Color.FromArgb(255, 192, 0, 0));
            _visual1.Brush   = _compositor.CreateSurfaceBrush(_geometrySurface);

            ElementCompositionPreview.SetElementChildVisual(RenderGrid, _visual1);

            _visual2        = _compositor.CreateSpriteVisual();
            _visual2.Size   = new Vector2(_width, _height);
            _visual2.Offset = new Vector3(((AnimatedGrid.ActualWidth - _width) / 2).ToSingle(),
                                          ((AnimatedGrid.ActualHeight - _height) / 2).ToSingle(), 0);

            var ellipse3 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.45f * _width, 0.225f * _height);
            var ellipse4 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.225f * _width, 0.45f * _height);

            _animatedGeometry = ellipse3.CombineWith(ellipse4, Matrix3x2.Identity, CanvasGeometryCombine.Xor);

            _animatedGeometrySurface = _generator.CreateGeometrySurface(_visual1.Size.ToSize(), _animatedGeometry, Color.FromArgb(255, 192, 0, 0));
            _visual2.Brush           = _compositor.CreateSurfaceBrush(_animatedGeometrySurface);

            ElementCompositionPreview.SetElementChildVisual(AnimatedGrid, _visual2);
        }
        /// <summary>
        /// Handles the Arrange layout phase
        /// </summary>
        /// <param name="finalSize">Final Size of the control</param>
        /// <returns>Size</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if ((_compositor == null) || (_generator == null))
            {
                return(base.ArrangeOverride(finalSize));
            }

            if (Double.IsInfinity(finalSize.Width) || Double.IsInfinity(finalSize.Height) ||
                Double.IsNaN(finalSize.Width) || Double.IsNaN(finalSize.Height))
            {
                return(base.ArrangeOverride(finalSize));
            }

            // Stop the animations and dispose the previous nodes
            // and their animations
            if (_isAnimationStarted)
            {
                for (var i = 0; i < _nodes.Count; i++)
                {
                    _nodes[i].StopAnimation(AnimatedProperty);
                    _animations[i].Dispose();
                    _animations[i] = null;
                    _nodes[i].Dispose();
                    _nodes[i] = null;
                }

                _container.StopAnimation(AnimatedProperty);
                _containerAnimation.Dispose();
                _containerAnimation = null;
                _container.Dispose();
                _container = null;

                _animations.Clear();
                _nodes.Clear();

                _isAnimationStarted = false;
            }

            // Validate MaxNodes and ActiveNodes
            if ((MaxNodes <= 0) || (ActiveNodes <= 0))
            {
                return(finalSize);
            }

            // Coerce ActiveNodes to MaxNodes if ActiveNodes > MaxNodes
            if (ActiveNodes > MaxNodes)
            {
                ActiveNodes = MaxNodes;
            }

            // Take the smallest of the width or height
            var sideLength = (float)Math.Min(finalSize.Width, finalSize.Height);

            // Size of the progress ring displayed
            _ringSize = new Vector2(sideLength, sideLength);
            var sideHalf = sideLength / 2f;

            // Radius of each node
            _nodeRadius = (float)NodeSizeFactor * sideHalf;
            // Size of each node
            _nodeSize = new Vector2(_nodeRadius * 2f, _nodeRadius * 2f);
            // Radius of the node
            _ringRadius = sideHalf - _nodeRadius;

            // Each animation will consist of '_maxFrameBlocks' number of
            // FrameBlocks. Each FrameBlock will consist of keyframes which allow
            // the element being animated to move to the next slot and wait
            // at that slot until all other elements have moved to their next slot.
            // Each FrameBlock (except the last one) will have '_maxFramesPerBlock'
            // number of keyframes. The last keyframe in the last FrameBlock
            // will always be (1f, "this.StartingValue + 360")

            // Total number of FrameBlocks in each animation
            _maxFrameBlocks = ActiveNodes;
            // Total keyframes in each FrameBlock
            _maxFramesPerBlock = ActiveNodes + 1;
            // Total keyframes in each animation
            _maxKeyFrames = _maxFrameBlocks * _maxFramesPerBlock;
            // Normalized Progress Key unit value for each keyframe
            _keyFrameSlice = 1f / _maxKeyFrames;

            // ========================================================================
            // NOTE:
            // gamma * maxNodes = 360
            // gamma = alpha + beta
            // beta = 2 * Asin(nodeRadius / ringRadius) * (180 / Math.PI)
            // invisibleNodes = MaxNodes - ActiveNodes
            // phi = (invisibleNodes * gamma)
            // theta = phi - beta
            // ========================================================================

            // gamma is the angle between adjacent nodes when maxNodes number of nodes are arranged in a circle
            _gamma = 360f / MaxNodes;
            // beta is the angle a node must travel after hitting the adjacent node
            _beta = 2f * (float)(Math.Asin(_nodeRadius / _ringRadius) * (180f / Math.PI));
            // alpha is the smallest angle a node must travel before hitting the adjacent node
            _alpha = _gamma - _beta;
            // phi is the angle occupied by (MaxNodes - ActiveNodes) number of nodes
            _phi = (MaxNodes - ActiveNodes + 1) * _gamma;
            // theta is the largest angle a node must travel before hitting the adjacent node
            _theta = _phi - _beta;

            // Create the Animations
            _animations = CreateAnimations();

            // Create the Container
            _container        = _compositor.CreateContainerVisual();
            _container.Size   = _ringSize;
            _container.Offset = new Vector3(((float)finalSize.Width - sideLength) / 2f,
                                            ((float)finalSize.Height - sideLength) / 2f,
                                            0f);
            _container.CenterPoint = new Vector3(_ringSize.X / 2f, _ringSize.Y / 2f, 0f);

            // Create the Nodes
            var offset      = new Vector3(_nodeRadius, _ringSize.Y / 2f, 0);
            var centerPoint = new Vector3(_ringSize.X / 2f - _nodeRadius, 0, 0);

            _nodes = new List <SpriteVisual>();
            var geometry = CanvasGeometry.CreateCircle(_generator.Device, new Vector2(_nodeRadius, _nodeRadius), _nodeRadius);
            // Create/Update the nodeMask
            var color = NodeColor;

            if (_nodeMask == null)
            {
                //Task.Run(async () =>
                //        {
                _nodeMask = _generator.CreateGeometrySurface(_nodeSize.ToSize(), geometry, color);
                //    })
                //.Wait();
            }
            else
            {
                //Task.Run(async () =>
                //        {
                _nodeMask.Redraw(_nodeSize.ToSize(), geometry, color);
                //    })
                //.Wait();
            }

            // Create the SurfaceBrush for the nodes
            var brush = _compositor.CreateSurfaceBrush(_nodeMask.Surface);

            var baseAngle = 0f;

            // Create the visuals for the nodes
            for (var i = 0; i < _maxFramesPerBlock; i++)
            {
                var node = _compositor.CreateSpriteVisual();
                node.Size                   = _nodeSize;
                node.AnchorPoint            = new Vector2(0.5f);
                node.Offset                 = offset;
                node.CenterPoint            = centerPoint;
                node.Brush                  = brush;
                node.RotationAngleInDegrees = baseAngle;
                if (i == 0)
                {
                    baseAngle += _phi;
                }
                else if (i == _maxFramesPerBlock - 2)
                {
                    baseAngle = -_beta;
                }
                else
                {
                    baseAngle += _gamma;
                }

                _nodes.Add(node);
                // Add the visual to the container
                _container.Children.InsertAtTop(node);
            }

            // Add the container to the Visual Tree
            ElementCompositionPreview.SetElementChildVisual(this, _container);

            // Start Node animations
            for (var i = 0; i < _maxFramesPerBlock; i++)
            {
                _nodes[i].StartAnimation(AnimatedProperty, _animations[i]);
            }

            // Start container animation
            _containerAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _containerAnimation.InsertExpressionKeyFrame(1f, "this.StartingValue + 360f", _compositor.CreateLinearEasingFunction());
            _containerAnimation.Duration          = RingDuration;
            _containerAnimation.IterationBehavior = AnimationIterationBehavior.Forever;

            _container.StartAnimation(AnimatedProperty, _containerAnimation);

            _isAnimationStarted = true;

            return(finalSize);
        }
Beispiel #3
0
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
            _generator  = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            _width  = 300f;
            _height = 300f;
            // Create the combined geometry
            var ellipse1 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.45f * _width, 0.225f * _height);
            var ellipse2 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.225f * _width, 0.45f * _height);

            _combinedGeometry = ellipse1.CombineWith(ellipse2, Matrix3x2.Identity, CanvasGeometryCombine.Union);

            // Create custom shaped visual using CompositionMaskBrush
            _visual1        = _compositor.CreateSpriteVisual();
            _visual1.Size   = new Vector2(_width, _height);
            _visual1.Offset = new Vector3(((CompositionGrid1.ActualWidth - _width) / 2).Single(),
                                          ((CompositionGrid1.ActualHeight - _height) / 2).Single(), 0);

            var visualChild = _compositor.CreateSpriteVisual();

            visualChild.Size   = new Vector2(_width * 0.75f, _height * 0.75f);
            visualChild.Offset = new Vector3(_width * 0.125f, _height * 0.125f, 0);

            _visual1.Children.InsertAtTop(visualChild);

            // Create the CompositionMask
            var compositionMask = _generator.CreateMaskSurface(_visual1.Size.ToSize(), _combinedGeometry);
            // Create SurfaceBrush from CompositionMask
            var mask   = _compositor.CreateSurfaceBrush(compositionMask.Surface);
            var source = _compositor.CreateColorBrush(Color.FromArgb(255, 0, 173, 239));
            // Create mask brush
            var maskBrush = _compositor.CreateMaskBrush();

            maskBrush.Mask   = mask;
            maskBrush.Source = source;
            _visual1.Brush   = maskBrush;

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid1, _visual1);

            // Create custom shaped visual using CompositionMaskBrush
            _visual2        = _compositor.CreateSpriteVisual();
            _visual2.Size   = new Vector2(_width, _height);
            _visual2.Offset = new Vector3(((CompositionGrid2.ActualWidth - _width) / 2).Single(),
                                          ((CompositionGrid2.ActualHeight - _height) / 2).Single(), 0);

            // Create the CompositionMask filled with color
            var compositionMask2 =
                _generator.CreateGeometrySurface(_visual2.Size.ToSize(), _combinedGeometry, Color.FromArgb(192, 192, 0, 0));
            // Create SurfaceBrush from CompositionMask
            var surfaceBrush = _compositor.CreateSurfaceBrush(compositionMask2.Surface);

            _visual2.Brush = surfaceBrush;

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid2, _visual2);

            // Initialize the visuals for the Animated Canvas
            // Create the container to host the visuals
            var container = _compositor.CreateContainerVisual();

            container.Size = new Vector2(CompositionGrid3.ActualWidth.Single(), CompositionGrid3.ActualHeight.Single());

            // Background Visual
            _bgVisual        = _compositor.CreateSpriteVisual();
            _bgVisual.Size   = new Vector2(_width, _height);
            _bgVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).Single(),
                                           ((CompositionGrid3.ActualHeight - _height) / 2).Single(), 0);

            var radians    = ((45f * Math.PI) / 180).Single();
            var bgGeometry = _combinedGeometry.Transform(Matrix3x2.CreateRotation(radians, new Vector2(_width / 2, _height / 2)));
            var bgMask     = _generator.CreateGeometrySurface(_bgVisual.Size.ToSize(), bgGeometry, Color.FromArgb(255, 0, 173, 239));
            var bgBrush    = _compositor.CreateSurfaceBrush(bgMask.Surface);

            _bgVisual.Brush = bgBrush;

            container.Children.InsertAtBottom(_bgVisual);

            // Animated Visual
            _animatedVisual        = _compositor.CreateSpriteVisual();
            _animatedVisual.Size   = new Vector2(_width, _height);
            _animatedVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).Single(),
                                                 ((CompositionGrid3.ActualHeight - _height) / 2).Single(), 0);
            // Create the Excluded geometry
            _outerGeometry = CanvasGeometry.CreateRectangle(_generator.Device, 0, 0, _width, _height);
            var excludedGeometry = _outerGeometry.CombineWith(_combinedGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Exclude);

            // Create the CompositionMask
            _animatedMaskSurface = _generator.CreateGeometrySurface(_animatedVisual.Size.ToSize(), excludedGeometry, Color.FromArgb(192, 192, 0, 0));
            var animBrush = _compositor.CreateSurfaceBrush(_animatedMaskSurface.Surface);

            _animatedVisual.Brush = animBrush;

            container.Children.InsertAtTop(_animatedVisual);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid3, container);
        }
        /// <summary>
        /// Handles the Arrange layout phase
        /// </summary>
        /// <param name="finalSize">Final Size of the control</param>
        /// <returns>Size</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if ((_compositor == null) || (_generator == null))
                return base.ArrangeOverride(finalSize);

            if (Double.IsInfinity(finalSize.Width) || Double.IsInfinity(finalSize.Height) ||
                Double.IsNaN(finalSize.Width) || Double.IsNaN(finalSize.Height))
                return base.ArrangeOverride(finalSize);

            // Stop the animations and dispose the previous nodes
            // and their animations
            if (_isAnimationStarted)
            {
                for (var i = 0; i < _nodes.Count; i++)
                {
                    _nodes[i].StopAnimation(AnimatedProperty);
                    _animations[i].Dispose();
                    _animations[i] = null;
                    _nodes[i].Dispose();
                    _nodes[i] = null;
                }

                _container.StopAnimation(AnimatedProperty);
                _containerAnimation.Dispose();
                _containerAnimation = null;
                _container.Dispose();
                _container = null;

                _animations.Clear();
                _nodes.Clear();

                _isAnimationStarted = false;
            }

            // Validate MaxNodes and ActiveNodes
            if ((MaxNodes <= 0) || (ActiveNodes <= 0))
                return finalSize;

            // Coerce ActiveNodes to MaxNodes if ActiveNodes > MaxNodes
            if (ActiveNodes > MaxNodes)
                ActiveNodes = MaxNodes;

            // Take the smallest of the width or height
            var sideLength = (float)Math.Min(finalSize.Width, finalSize.Height);
            // Size of the progress ring displayed
            _ringSize = new Vector2(sideLength, sideLength);
            var sideHalf = sideLength / 2f;
            // Radius of each node
            _nodeRadius = (float)NodeSizeFactor * sideHalf;
            // Size of each node
            _nodeSize = new Vector2(_nodeRadius * 2f, _nodeRadius * 2f);
            // Radius of the node
            _ringRadius = sideHalf - _nodeRadius;

            // Each animation will consist of '_maxFrameBlocks' number of
            // FrameBlocks. Each FrameBlock will consist of keyframes which allow
            // the element being animated to move to the next slot and wait
            // at that slot until all other elements have moved to their next slot.
            // Each FrameBlock (except the last one) will have '_maxFramesPerBlock'
            // number of keyframes. The last keyframe in the last FrameBlock
            // will always be (1f, "this.StartingValue + 360")

            // Total number of FrameBlocks in each animation
            _maxFrameBlocks = ActiveNodes;
            // Total keyframes in each FrameBlock
            _maxFramesPerBlock = ActiveNodes + 1;
            // Total keyframes in each animation
            _maxKeyFrames = _maxFrameBlocks * _maxFramesPerBlock;
            // Normalized Progress Key unit value for each keyframe
            _keyFrameSlice = 1f / _maxKeyFrames;

            // ========================================================================
            // NOTE:
            // gamma * maxNodes = 360
            // gamma = alpha + beta
            // beta = 2 * Asin(nodeRadius / ringRadius) * (180 / Math.PI)
            // invisibleNodes = MaxNodes - ActiveNodes
            // phi = (invisibleNodes * gamma)
            // theta = phi - beta
            // ========================================================================

            // gamma is the angle between adjacent nodes when maxNodes number of nodes are arranged in a circle
            _gamma = 360f / MaxNodes;
            // beta is the angle a node must travel after hitting the adjacent node
            _beta = 2f * (float)(Math.Asin(_nodeRadius / _ringRadius) * (180f / Math.PI));
            // alpha is the smallest angle a node must travel before hitting the adjacent node
            _alpha = _gamma - _beta;
            // phi is the angle occupied by (MaxNodes - ActiveNodes) number of nodes
            _phi = (MaxNodes - ActiveNodes + 1) * _gamma;
            // theta is the largest angle a node must travel before hitting the adjacent node
            _theta = _phi - _beta;

            // Create the Animations
            _animations = CreateAnimations();

            // Create the Container
            _container = _compositor.CreateContainerVisual();
            _container.Size = _ringSize;
            _container.Offset = new Vector3(((float)finalSize.Width - sideLength) / 2f,
                                            ((float)finalSize.Height - sideLength) / 2f,
                                            0f);
            _container.CenterPoint = new Vector3(_ringSize.X / 2f, _ringSize.Y / 2f, 0f);

            // Create the Nodes
            var offset = new Vector3(_nodeRadius, _ringSize.Y / 2f, 0);
            var centerPoint = new Vector3(_ringSize.X / 2f - _nodeRadius, 0, 0);
            _nodes = new List<SpriteVisual>();
            var geometry = CanvasGeometry.CreateCircle(_generator.Device, new Vector2(_nodeRadius, _nodeRadius), _nodeRadius);
            // Create/Update the nodeMask
            var color = NodeColor;
            if (_nodeMask == null)
            {
                //Task.Run(async () =>
                //        {
                            _nodeMask = _generator.CreateGeometrySurface(_nodeSize.ToSize(), geometry, color);
                    //    })
                    //.Wait();
            }
            else
            {
                //Task.Run(async () =>
                //        {
                             _nodeMask.Redraw(_nodeSize.ToSize(), geometry, color);
                    //    })
                    //.Wait();
            }

            // Create the SurfaceBrush for the nodes
            var brush = _compositor.CreateSurfaceBrush(_nodeMask.Surface);

            var baseAngle = 0f;

            // Create the visuals for the nodes
            for (var i = 0; i < _maxFramesPerBlock; i++)
            {
                var node = _compositor.CreateSpriteVisual();
                node.Size = _nodeSize;
                node.AnchorPoint = new Vector2(0.5f);
                node.Offset = offset;
                node.CenterPoint = centerPoint;
                node.Brush = brush;
                node.RotationAngleInDegrees = baseAngle;
                if (i == 0)
                {
                    baseAngle += _phi;
                }
                else if (i == _maxFramesPerBlock - 2)
                {
                    baseAngle = -_beta;
                }
                else
                {
                    baseAngle += _gamma;
                }

                _nodes.Add(node);
                // Add the visual to the container
                _container.Children.InsertAtTop(node);
            }

            // Add the container to the Visual Tree
            ElementCompositionPreview.SetElementChildVisual(this, _container);

            // Start Node animations
            for (var i = 0; i < _maxFramesPerBlock; i++)
            {
                _nodes[i].StartAnimation(AnimatedProperty, _animations[i]);
            }

            // Start container animation
            _containerAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _containerAnimation.InsertExpressionKeyFrame(1f, "this.StartingValue + 360f", _compositor.CreateLinearEasingFunction());
            _containerAnimation.Duration = RingDuration;
            _containerAnimation.IterationBehavior = AnimationIterationBehavior.Forever;

            _container.StartAnimation(AnimatedProperty, _containerAnimation);

            _isAnimationStarted = true;

            return finalSize;
        }
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
            _generator = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            _width = 300f;
            _height = 300f;
            // Create the combined geometry
            var ellipse1 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.45f * _width, 0.225f * _height);
            var ellipse2 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.225f * _width, 0.45f * _height);
            _combinedGeometry = ellipse1.CombineWith(ellipse2, Matrix3x2.Identity, CanvasGeometryCombine.Union);

            // Create custom shaped visual using CompositionMaskBrush
            _visual1 = _compositor.CreateSpriteVisual();
            _visual1.Size = new Vector2(_width, _height);
            _visual1.Offset = new Vector3(((CompositionGrid1.ActualWidth - _width) / 2).Single(),
                                         ((CompositionGrid1.ActualHeight - _height) / 2).Single(), 0);

            var visualChild = _compositor.CreateSpriteVisual();
            visualChild.Size = new Vector2(_width * 0.75f, _height * 0.75f);
            visualChild.Offset = new Vector3(_width*0.125f, _height*0.125f, 0);

            _visual1.Children.InsertAtTop(visualChild);

            // Create the CompositionMask
            var compositionMask = _generator.CreateMaskSurface(_visual1.Size.ToSize(), _combinedGeometry);
            // Create SurfaceBrush from CompositionMask
            var mask = _compositor.CreateSurfaceBrush(compositionMask.Surface);
            var source = _compositor.CreateColorBrush(Color.FromArgb(255, 0, 173, 239));
            // Create mask brush
            var maskBrush = _compositor.CreateMaskBrush();
            maskBrush.Mask = mask;
            maskBrush.Source = source;
            _visual1.Brush = maskBrush;

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid1, _visual1);

            // Create custom shaped visual using CompositionMaskBrush
            _visual2 = _compositor.CreateSpriteVisual();
            _visual2.Size = new Vector2(_width, _height);
            _visual2.Offset = new Vector3(((CompositionGrid2.ActualWidth - _width) / 2).Single(),
                                         ((CompositionGrid2.ActualHeight - _height) / 2).Single(), 0);

            // Create the CompositionMask filled with color
            var compositionMask2 =
                _generator.CreateGeometrySurface(_visual2.Size.ToSize(), _combinedGeometry, Color.FromArgb(192, 192, 0, 0));
            // Create SurfaceBrush from CompositionMask
            var surfaceBrush = _compositor.CreateSurfaceBrush(compositionMask2.Surface);
            _visual2.Brush = surfaceBrush;

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid2, _visual2);

            // Initialize the visuals for the Animated Canvas
            // Create the container to host the visuals
            var container = _compositor.CreateContainerVisual();
            container.Size = new Vector2(CompositionGrid3.ActualWidth.Single(), CompositionGrid3.ActualHeight.Single());

            // Background Visual
            _bgVisual = _compositor.CreateSpriteVisual();
            _bgVisual.Size = new Vector2(_width, _height);
            _bgVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).Single(),
                                         ((CompositionGrid3.ActualHeight - _height) / 2).Single(), 0);

            var radians = ((45f*Math.PI)/180).Single();
            var bgGeometry = _combinedGeometry.Transform(Matrix3x2.CreateRotation(radians, new Vector2(_width/2, _height/2)));
            var bgMask = _generator.CreateGeometrySurface(_bgVisual.Size.ToSize(), bgGeometry, Color.FromArgb(255, 0, 173, 239));
            var bgBrush = _compositor.CreateSurfaceBrush(bgMask.Surface);
            _bgVisual.Brush = bgBrush;

            container.Children.InsertAtBottom(_bgVisual);

            // Animated Visual
            _animatedVisual = _compositor.CreateSpriteVisual();
            _animatedVisual.Size = new Vector2(_width, _height);
            _animatedVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).Single(),
                                                ((CompositionGrid3.ActualHeight - _height) / 2).Single(), 0);
            // Create the Excluded geometry
            _outerGeometry = CanvasGeometry.CreateRectangle(_generator.Device, 0, 0, _width, _height);
            var excludedGeometry = _outerGeometry.CombineWith(_combinedGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Exclude);
            // Create the CompositionMask
            _animatedMaskSurface = _generator.CreateGeometrySurface(_animatedVisual.Size.ToSize(), excludedGeometry, Color.FromArgb(192, 192, 0, 0));
            var animBrush = _compositor.CreateSurfaceBrush(_animatedMaskSurface.Surface);
            _animatedVisual.Brush = animBrush;

            container.Children.InsertAtTop(_animatedVisual);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid3, container);
        }
        private void SquirclePage_Loaded(object sender, RoutedEventArgs e)
        {
            _compositor = Window.Current.Compositor;
            _generator  = _compositor.CreateCompositionGenerator();

            // Create Squircle shaped visual using CompositionSurfaceBrush
            _roundedRectangleVisual        = _compositor.CreateSpriteVisual();
            _roundedRectangleVisual.Size   = new Vector2(_width, _height);
            _roundedRectangleVisual.Offset = new Vector3(((RoundedRectangleGrid.ActualWidth - _width) / 2).ToSingle(),
                                                         ((RoundedRectangleGrid.ActualHeight - _height) / 2).ToSingle(), 0);

            // Create the geometry surface for squircle filled with red color
            var roundedRectGeometry = CanvasGeometry.CreateRoundedRectangle(_generator.Device, 0, 0, _width, _height, _radius, _radius);

            _roundedRectangleSurface = _generator.CreateGeometrySurface(_roundedRectangleVisual.Size.ToSize(), roundedRectGeometry, Color.FromArgb(255, 192, 0, 0));
            // Create SurfaceBrush from CompositionMask
            var rectSurfaceBrush = _compositor.CreateSurfaceBrush(_roundedRectangleSurface.Surface);

            _roundedRectangleVisual.Brush = rectSurfaceBrush;

            ElementCompositionPreview.SetElementChildVisual(RoundedRectangleGrid, _roundedRectangleVisual);

            // Create Squircle shaped visual using CompositionSurfaceBrush
            _squircleVisual        = _compositor.CreateSpriteVisual();
            _squircleVisual.Size   = new Vector2(_width, _height);
            _squircleVisual.Offset = new Vector3(((SquircleGrid.ActualWidth - _width) / 2).ToSingle(),
                                                 ((SquircleGrid.ActualHeight - _height) / 2).ToSingle(), 0);

            // Create the geometry surface for squircle filled with red color
            var squircleGeometry = CanvasObject.CreateSquircle(_generator.Device, 0, 0, _width, _height, _radius, _radius);

            _squircleSurface = _generator.CreateGeometrySurface(_squircleVisual.Size.ToSize(), squircleGeometry, Color.FromArgb(255, 192, 0, 0));
            // Create SurfaceBrush from CompositionMask
            var surfaceBrush = _compositor.CreateSurfaceBrush(_squircleSurface);

            _squircleVisual.Brush = surfaceBrush;

            ElementCompositionPreview.SetElementChildVisual(SquircleGrid, _squircleVisual);

            // Create visual showing difference between the two geometries
            _differenceVisual      = _compositor.CreateSpriteVisual();
            _differenceVisual.Size = new Vector2(_width, _height);


            // Create the geometry surface for squircle filled with red color
            var differenceGeometry =
                roundedRectGeometry.CombineWith(squircleGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Exclude);

            _differenceSurface = _generator.CreateGeometrySurface(_differenceVisual.Size.ToSize(), differenceGeometry, Color.FromArgb(255, 192, 192, 0));
            // Create SurfaceBrush from CompositionMask
            _differenceVisual.Brush = _compositor.CreateSurfaceBrush(_differenceSurface);

            _xorVisual        = _compositor.CreateSpriteVisual();
            _xorVisual.Size   = _differenceVisual.Size;
            _xorVisual.Offset = new Vector3(((DifferenceGrid.ActualWidth - _width) / 2).ToSingle(),
                                            ((DifferenceGrid.ActualHeight - _height) / 2).ToSingle(), 0);

            var xorGeometry =
                roundedRectGeometry.CombineWith(squircleGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Xor);

            _xorSurface = _generator.CreateGeometrySurface(_xorVisual.Size.ToSize(), xorGeometry, Color.FromArgb(255, 192, 0, 0));
            // Create SurfaceBrush from CompositionMask
            _xorVisual.Brush = _compositor.CreateSurfaceBrush(_xorSurface);
            _xorVisual.Children.InsertAtTop(_differenceVisual);

            ElementCompositionPreview.SetElementChildVisual(DifferenceGrid, _xorVisual);
        }
        /// <summary>
        /// Initializes the Composition elements
        /// </summary>
        private void InitComposition()
        {
            // Compositor
            _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
            // CompositionGenerator
            _generator = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);
            
            // Fade Out Animation
            _fadeOutAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _fadeOutAnimation.InsertKeyFrame(1f, 0);
            _fadeOutAnimation.Duration = TransitionDuration;
            // Fade In Animation
            _fadeInAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _fadeInAnimation.InsertKeyFrame(1f, 1);
            _fadeInAnimation.Duration = TransitionDuration;
            // Color Animation
            _colorAnimation = _compositor.CreateColorKeyFrameAnimation();
            _colorAnimation.Duration = TransitionDuration;
            // Offset Animation
            _offsetAnimation = _compositor.CreateVector3KeyFrameAnimation();
            _offsetAnimation.Target = "Offset";
            _offsetAnimation.Duration = TransitionDuration;
            _offsetAnimation.InsertKeyFrame(1f, Vector3.Zero);
            // Alignment animations
            _alignXAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _alignXAnimation.Duration = AlignmentTransitionDuration;
            _alignYAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _alignYAnimation.Duration = AlignmentTransitionDuration;

            // ZoomIn Animation Group
            _scaleAnimation = _compositor.CreateVector3KeyFrameAnimation();
            _scaleAnimation.Target = "Scale";
            _scaleAnimation.InsertKeyFrame(1f, Vector3.One);
            _scaleAnimation.Duration = TransitionDuration;
            _zoomInAnimationGroup = _compositor.CreateAnimationGroup();
            _zoomInAnimationGroup.Add(_scaleAnimation);
            _zoomInAnimationGroup.Add(_offsetAnimation);

            // Visuals
            _rootContainer = _compositor.CreateContainerVisual();
            _frameLayer = _compositor.CreateLayerVisual();
            _frameBackgroundVisual = _compositor.CreateSpriteVisual();
            _frameContentVisual = _compositor.CreateSpriteVisual();
            _placeholderContentVisual = _compositor.CreateSpriteVisual();
            _placeholderBackgroundVisual = _compositor.CreateSpriteVisual();
            _nextVisualContent = _compositor.CreateSpriteVisual();

            _frameLayer.Children.InsertAtTop(_frameBackgroundVisual);
            _frameLayer.Children.InsertAtTop(_frameContentVisual);
            _frameLayer.Children.InsertAtTop(_placeholderBackgroundVisual);
            _frameLayer.Children.InsertAtTop(_placeholderContentVisual);
            _frameLayer.Children.InsertAtTop(_nextVisualContent);

            // Placeholder content
            _placeholderContentMask = _generator.CreateGeometrySurface(PlaceholderSize, GetPlaceHolderGeometry(),
                PlaceholderColor, PlaceholderBackground);
            _placeholderContentBrush = _compositor.CreateSurfaceBrush(_placeholderContentMask.Surface);
            _placeholderContentVisual.Brush = _placeholderContentBrush;
            // Placeholder background
            _placeholderBackgroundVisual.Brush = _compositor.CreateColorBrush(PlaceholderBackground);

            // By default placeholder visual will not be visible
            HidePlaceholder();

            // Shadow visual
            _shadowVisual = _compositor.CreateSpriteVisual();

            _rootContainer.Children.InsertAtBottom(_shadowVisual);
            _rootContainer.Children.InsertAtTop(_frameLayer);

            _frameBackgroundVisual.Brush = _compositor.CreateColorBrush(FrameBackground);

            // Create the effect to create the opacity mask
            var layerEffect = 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 layerEffectFactory = _compositor.CreateEffectFactory(layerEffect);
            _layerEffectBrush = layerEffectFactory.CreateBrush();

            // The mask for the imageFrame
            _frameLayerMask = _generator.CreateMaskSurface(new Size(0, 0), null);
            _layerEffectBrush.SetSourceParameter("mask", _compositor.CreateSurfaceBrush(_frameLayerMask.Surface));
            // Apply the mask effect to the frameLayer
            _frameLayer.Effect = _layerEffectBrush;

            ElementCompositionPreview.SetElementChildVisual(this, _rootContainer);
        }
        /// <summary>
        /// Disposes the resources
        /// </summary>
        public void Dispose()
        {
            // Clean up resources
            _compositor = null;
            Source = null;
            DataContext = null;
            Foreground = null;
            Background = null;
            _scheduledObject = null;
            _currentObject = null;

            // Clean up Composition Objects
            _imageSurface?.Dispose();
            _imageSurface = null;
            _nextImageSurface?.Dispose();
            _nextImageSurface = null;
            _frameLayerMask?.Dispose();
            _frameLayerMask = null;
            _placeholderContentMask?.Dispose();
            _placeholderContentMask = null;
            _placeholderContentBrush?.Dispose();
            _placeholderContentBrush = null;
            _nextSurfaceBrush?.Dispose();
            _nextSurfaceBrush = null;
            _rootContainer?.Dispose();
            _rootContainer = null;
            _shadowVisual?.Dispose();
            _shadowVisual = null;
            _frameLayer?.Dispose();
            _frameLayer = null;
            _frameBackgroundVisual?.Dispose();
            _frameBackgroundVisual = null;
            _placeholderBackgroundVisual?.Dispose();
            _placeholderBackgroundVisual = null;
            _placeholderContentVisual?.Dispose();
            _placeholderContentVisual = null;
            _frameContentVisual?.Dispose();
            _frameContentVisual = null;
            _nextVisualContent?.Dispose();
            _nextVisualContent = null;
            _shadow?.Dispose();
            _shadow = null;
            _layerEffectBrush?.Dispose();
            _layerEffectBrush = null;
            _imageOptions = null;
            _zoomInAnimationGroup?.Dispose();
            _zoomInAnimationGroup = null;
            _fadeOutAnimation?.Dispose();
            _fadeOutAnimation = null;
            _fadeInAnimation?.Dispose();
            _fadeInAnimation = null;
            _colorAnimation?.Dispose();
            _colorAnimation = null;
            _alignXAnimation?.Dispose();
            _alignXAnimation = null;
            _alignYAnimation?.Dispose();
            _alignYAnimation = null;
            _offsetAnimation?.Dispose();
            _offsetAnimation = null;
            _scaleAnimation?.Dispose();
            _scaleAnimation = null;

            // Dispose the generator at the end to allow the 
            // dependant composition objects to unsubscribe from
            // generator events
            _generator?.Dispose();
            _generator = null;
        }