Exemple #1
0
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = Window.Current.Compositor;
            _generator  = _compositor.CreateCompositionGenerator();

            var size = new Vector2(GridWidth, GridHeight);

            _topOffset = -GridHeight / 2f;

            // Create the left image visual
            var leftImageVisual = _compositor.CreateSpriteVisual();

            leftImageVisual.Size = size;

            // Left Image Surface
            var leftImageSurface = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/Image1.jpg"), size.ToSize(), ImageSurfaceOptions.Default);

            // Left Mask Geometry

            _leftGeometry = CanvasGeometry.CreateRectangle(_generator.Device, new Rect(0f, 0f, 2f * (GridWidth * _splitValue) / 100f, 2f * GridHeight));
            var leftOffset = -(GridWidth * _splitValue) / 100f;
            // Left Masked Brush
            var leftMaskedBrush = _compositor.CreateMaskBrush();

            leftMaskedBrush.Source = _compositor.CreateSurfaceBrush(leftImageSurface);
            _leftGaussianSurface   = _generator.CreateGaussianMaskSurface(size.ToSize(), _leftGeometry, new Vector2(leftOffset, _topOffset), _blurRadius);
            leftMaskedBrush.Mask   = _compositor.CreateSurfaceBrush(_leftGaussianSurface);
            leftImageVisual.Brush  = leftMaskedBrush;

            // Create the right image visual
            var rightImageVisual = _compositor.CreateSpriteVisual();

            rightImageVisual.Size = size;

            // Right Image Surface
            var rightImageSurface = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/Image2.jpg"), size.ToSize(), ImageSurfaceOptions.Default);

            // Right Mask Geometry
            _rightGeometry = CanvasGeometry.CreateRectangle(_generator.Device, new Rect(0, 0, 2f * (GridWidth * (100f - _splitValue)) / 100, 2f * GridHeight));

            // Right Masked Brush
            var rightMaskedBrush = _compositor.CreateMaskBrush();

            rightMaskedBrush.Source = _compositor.CreateSurfaceBrush(rightImageSurface);
            _rightGaussianSurface   = _generator.CreateGaussianMaskSurface(size.ToSize(), _rightGeometry, new Vector2(-leftOffset, _topOffset), _blurRadius);
            rightMaskedBrush.Mask   = _compositor.CreateSurfaceBrush(_rightGaussianSurface);
            rightImageVisual.Brush  = rightMaskedBrush;

            var visualContainer = _compositor.CreateContainerVisual();

            visualContainer.Size = size;
            visualContainer.Children.InsertAtTop(leftImageVisual);
            visualContainer.Children.InsertAtTop(rightImageVisual);

            ElementCompositionPreview.SetElementChildVisual(ImageGrid, visualContainer);
        }
        /// <summary>
        /// Initializes the Composition Brush.
        /// </summary>
        protected override void OnConnected()
        {
            base.OnConnected();

            // Delay creating composition resources until they're required.
            if (CompositionBrush == null)
            {
                // Abort if effects aren't supported.
                if (!CompositionCapabilities.GetForCurrentView().AreEffectsSupported())
                {
                    return;
                }

                var size = new Vector2(SurfaceWidth, SurfaceHeight);

                var device   = CanvasDevice.GetSharedDevice();
                var graphics = CanvasComposition.CreateCompositionGraphicsDevice(Window.Current.Compositor, device);

                var surface = graphics.CreateDrawingSurface(size.ToSize(), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);

                using (var session = CanvasComposition.CreateDrawingSession(surface))
                {
                    // Call Implementor to draw on session.
                    if (!OnDraw(device, session, size))
                    {
                        return;
                    }
                }

                _surfaceBrush         = Window.Current.Compositor.CreateSurfaceBrush(surface);
                _surfaceBrush.Stretch = CompositionStretch.Fill;

                CompositionBrush = _surfaceBrush;
            }
        }
Exemple #3
0
        private async void OnPageLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = Window.Current.Compositor;
            _generator  = _compositor.CreateCompositionGenerator();

            var size = new Vector2(GridWidth, GridWidth);
            // Create the image visual
            var imageVisual = _compositor.CreateSpriteVisual();

            imageVisual.Size = size;
            var imageSurface = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/cat.png"),
                                                                        size.ToSize(), ImageSurfaceOptions.Default);

            imageVisual.Brush = _compositor.CreateSurfaceBrush(imageSurface);
            ElementCompositionPreview.SetElementChildVisual(ImageGrid, imageVisual);

            //Create the mask visual
            var maskVisual = _compositor.CreateSpriteVisual();

            maskVisual.Size = size;

            // Create the combined geometry
            var ellipse1 = CanvasGeometry.CreateEllipse(_generator.Device, GridWidth / 2, GridWidth / 2, GridWidth * 0.375f, GridWidth * 0.1875f);
            var ellipse2 = CanvasGeometry.CreateEllipse(_generator.Device, GridWidth / 2, GridWidth / 2, GridWidth * 0.1875f, GridWidth * 0.375f);

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

            // Create SurfaceBrush from MaskSurface

            ElementCompositionPreview.SetElementChildVisual(MaskGrid, maskVisual);

            var outputVisual = _compositor.CreateSpriteVisual();

            outputVisual.Size = size;

            var maskedBrush = _compositor.CreateMaskBrush();

            maskedBrush.Source = imageVisual.Brush;
            _gaussianSurface   = _generator.CreateGaussianMaskSurface(size.ToSize(), _combinedGeometry, Vector2.Zero, 0);
            maskedBrush.Mask   = _compositor.CreateSurfaceBrush(_gaussianSurface);

            maskVisual.Brush   = _compositor.CreateSurfaceBrush(_gaussianSurface);;
            outputVisual.Brush = maskedBrush;

            ElementCompositionPreview.SetElementChildVisual(OutputGrid, outputVisual);
        }
Exemple #4
0
        public void Vector2ToSizeTest()
        {
            Vector2 vector = new Vector2(23, 42);

            Windows.Foundation.Size result = vector.ToSize();

            Assert.AreEqual(23.0, result.Width);
            Assert.AreEqual(42.0, result.Height);
        }
Exemple #5
0
        public PaintCore(Compositor compositor)
        {
            var canvasSize = new Vector2(400, 400);

            _currentImage = new Image(null, canvasSize.ToSize());

            InitComposition(compositor);
            InitWin2D(canvasSize);
        }
Exemple #6
0
 private void Draw(bool IsFill, Color color)
 {
     _surface = _graphicsDevice.CreateDrawingSurface(Size.ToSize(), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied);
     using (var dc = CanvasComposition.CreateDrawingSession(_surface))
     {
         dc.Clear(Colors.Transparent);
         if (IsFill)
         {
             dc.FillCircle(Size / 2, Size.X / 2, color);
         }
         else
         {
             dc.DrawCircle(Size / 2, Size.X / 2 - 2, color, 2f);
         }
         dc.Flush();
     }
     _brush        = _compositor.CreateSurfaceBrush(_surface);
     _visual.Brush = _brush;
 }
Exemple #7
0
 public void NewImage(Vector2 size)
 {
     _currentImage.AssignNewFile(null);
     _currentImage.Size = size.ToSize();
     _canvas.Reset(size);
 }
        private void CreateTextAndBlendEffect(Vector2 sizeLightBounds)
        {
            //
            // Crete the effect graph, doing a hard light blend of the text over the 
            // content already drawn into the backbuffer
            //

            IGraphicsEffect graphicsEffect = new BlendEffect()
            {
                Mode = BlendEffectMode.HardLight,
                Foreground = new CompositionEffectSourceParameter("Text"),
                Background = new CompositionEffectSourceParameter("Destination"),
            };

            CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory(graphicsEffect, null);
            CompositionEffectBrush brush = effectFactory.CreateBrush();

            // Bind the destination brush
            brush.SetSourceParameter("Destination", _compositor.CreateBackdropBrush());


            //
            // Create the text surface which we'll scroll over the image with the lighting effect
            //

            // Pick a nice size font depending on target size
            const float maxFontSize = 72;
            const float scaleFactor = 12;
            float fontSize = Math.Min(sizeLightBounds.X / scaleFactor, maxFontSize);

            // Create the text format description, then the surface
            CanvasTextFormat textFormat = new CanvasTextFormat
                    {
                        FontFamily = "Segoe UI",
                        FontSize = fontSize,
                        FontWeight = FontWeights.Bold,
                        WordWrapping = CanvasWordWrapping.WholeWord,
                        HorizontalAlignment = CanvasHorizontalAlignment.Center,
                        VerticalAlignment = CanvasVerticalAlignment.Center
                    };

            string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec efficitur, eros sit amet laoreet scelerisque, " +
                          "nunc odio ultricies metus, ut consectetur nulla massa eu nibh.Phasellus in lorem id nunc euismod tempus.Phasellus et nulla non turpis tempor blandit ut eget turpis." +
                          "Phasellus ac ornare elit, ut scelerisque dolor. Nam vel finibus lorem. Aenean malesuada pulvinar eros id ornare. Fusce blandit ante eget dolor efficitur suscipit." +
                          "Phasellus ac lacus nibh. Aenean eget blandit risus, in lacinia mi. Proin fermentum ante eros, non sollicitudin mi pretium eu. Curabitur suscipit lectus arcu, eget" +
                          "pretium quam sagittis non. Mauris purus mauris, condimentum nec laoreet sit amet, imperdiet sit amet nisi. Sed interdum, urna et aliquam porta, elit velit tincidunt orci," +
                          "vitae vestibulum risus lacus at nulla.Phasellus sapien ipsum, pellentesque varius enim nec, iaculis aliquet enim. Nulla id dapibus ante. Sed hendrerit sagittis leo, commodo" +
                          "fringilla ligula rutrum ut. Nullam sodales, ex ut pellentesque scelerisque, sapien nulla mattis lectus, vel ullamcorper leo enim ac mi.Sed consectetur vitae velit in consequat." +
                          "Pellentesque ac condimentum justo, at feugiat nulla. Sed ut congue neque. Nam gravida quam ac urna porttitor, ut bibendum ante mattis.Cras viverra cursus sapien, et sollicitudin" +
                          "risus fringilla eget. Nulla facilisi. Duis pellentesque scelerisque nisi, facilisis malesuada massa gravida et. Vestibulum ac leo sed orci tincidunt feugiat.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc id leo vestibulum, vulputate ipsum sit amet, scelerisque velit. Curabitur imperdiet justo et tortor dignissim, sit amet volutpat sem ullamcorper. Nam mollis ullamcorper tellus vitae convallis. Aliquam eleifend elit nec tincidunt pharetra. Aliquam turpis eros, mollis et nunc quis, porta molestie justo. Etiam ultrices sem non turpis imperdiet dictum.Aliquam molestie elit in urna sodales, nec luctus dui laoreet.Curabitur molestie risus vel ligula efficitur, non fringilla urna iaculis.Curabitur neque tortor, facilisis quis dictum facilisis, facilisis et ante. Sed nisl erat, semper vitae efficitur ut, congue vitae quam. Ut auctor lacus sit amet varius placerat.Sed ac tellus tempus, ultricies est quis, tempor felis.Nulla vel faucibus elit, eu tincidunt eros. Nulla blandit id nisl ut porta. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam suscipit tellus a mattis pulvinar. Sed et libero vel ligula elementum suscipit.Ut elementum libero at sagittis pharetra. Fusce ultrices odio sapien, a posuere est consectetur ut.";

            // Make the surface twice the height to give us room to scroll
            Vector2 surfaceSize = new Vector2(sizeLightBounds.X, 2f * sizeLightBounds.Y);
            CompositionDrawingSurface textSurface = SurfaceLoader.LoadText(text, surfaceSize.ToSize(),
                                                                           textFormat, Colors.White, Colors.Transparent);
            brush.SetSourceParameter("Text", _compositor.CreateSurfaceBrush(textSurface));

            // Create the sprite and parent it to the panel with the clip
            _textSprite = _compositor.CreateSpriteVisual();
            _textSprite.Size = surfaceSize;
            _textSprite.Brush = brush;

            ElementCompositionPreview.SetElementChildVisual(MyPanel, _textSprite);

            // Lastly, setup the slow scrolling animation of the text
            LinearEasingFunction linear = _compositor.CreateLinearEasingFunction();
            Vector3KeyFrameAnimation offsetAnimation = _compositor.CreateVector3KeyFrameAnimation();
            offsetAnimation.InsertKeyFrame(0f, new Vector3(0, 0, 0), linear);
            offsetAnimation.InsertKeyFrame(1f, new Vector3(0, -_textSprite.Size.Y * .5f, 0), linear);
            offsetAnimation.Duration = TimeSpan.FromMilliseconds(30000);
            offsetAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
            _textSprite.StartAnimation("Offset", offsetAnimation);
        }
Exemple #9
0
        public void Vector2ToSizeTest()
        {
            Vector2 vector = new Vector2(23, 42);

            Windows.Foundation.Size result = vector.ToSize();

            Assert.AreEqual(23.0, result.Width);
            Assert.AreEqual(42.0, result.Height);
        }
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
            _generator = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            var distance = 4f;
            var visualSize = new Vector2(225, 150);
            var vRefHeight = visualSize.Y + (visualSize.Y * 0.7f) + distance;
            var hRefWidth = visualSize.X + (visualSize.X * 0.7f) + distance;

            var vRefLeft = (float)(CompositionGrid1.ActualWidth - visualSize.X) / 2f;
            var vRefTop = (float)(CompositionGrid1.ActualHeight - vRefHeight) / 2f;
            var hRefLeft = (float)(CompositionGrid1.ActualWidth - hRefWidth) / 2f;
            var hRefTop = (float)(CompositionGrid1.ActualHeight - visualSize.Y) / 2f;

            var surfaceImage = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/Car.jpg"),
                visualSize.ToSize(), ImageSurfaceOptions.Default);
            var surfaceBrush = _compositor.CreateSurfaceBrush(surfaceImage.Surface);

            var visual1 = _compositor.CreateSpriteVisual();
            visual1.Size = visualSize;
            visual1.Offset = new Vector3(vRefLeft, vRefTop, 0);
            visual1.Brush = surfaceBrush;

            _generator.CreateReflection(visual1, distance);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid1, visual1);

            var invertEffect = new InvertEffect()
            {
                Source = new CompositionEffectSourceParameter("source")
            };

            var invertEffectFactory = _compositor.CreateEffectFactory(invertEffect);
            var invertBrush = invertEffectFactory.CreateBrush();
            invertBrush.SetSourceParameter("source", surfaceBrush);

            var visual2 = _compositor.CreateSpriteVisual();
            visual2.Size = visualSize;
            visual2.Offset = new Vector3(hRefLeft, hRefTop, 0);
            visual2.Brush = invertBrush;

            _generator.CreateReflection(visual2, distance, 0.7f, ReflectionLocation.Right);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid2, visual2);

            var visual3 = _compositor.CreateSpriteVisual();
            visual3.Size = visualSize;
            visual3.Offset = new Vector3(vRefLeft, vRefTop, 0);
            visual3.Brush = surfaceBrush;

            var inVisual = _compositor.CreateSpriteVisual();
            inVisual.Size = new Vector2(80, 80);
            inVisual.Offset = new Vector3(20, 10, 0);
            inVisual.Brush = _compositor.CreateColorBrush(Colors.Yellow);

            var inVisual2 = _compositor.CreateSpriteVisual();
            inVisual2.Size = new Vector2(80, 80);
            inVisual2.Offset = new Vector3(60, 60, 0);
            inVisual2.Brush = _compositor.CreateColorBrush(Colors.Blue);
            visual3.Children.InsertAtTop(inVisual2);
            visual3.Children.InsertAtTop(inVisual);

            _generator.CreateReflection(visual3, distance, 0.7f, ReflectionLocation.Bottom);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid3, visual3);

            var visual4 = _compositor.CreateSpriteVisual();
            visual4.Size = visualSize;
            visual4.Offset = new Vector3(hRefLeft, hRefTop, 0);
            visual4.Brush = surfaceBrush;

            var inVisual3 = _compositor.CreateSpriteVisual();
            inVisual3.Size = new Vector2(80, 80);
            inVisual3.Offset = new Vector3(20, 10, 0);
            inVisual3.Brush = _compositor.CreateColorBrush(Colors.Yellow);

            var inVisual4 = _compositor.CreateSpriteVisual();
            inVisual4.Size = new Vector2(80, 80);
            inVisual4.Offset = new Vector3(60, 40, 0);
            inVisual4.Brush = _compositor.CreateColorBrush(Colors.Blue);
            visual4.Children.InsertAtTop(inVisual3);
            visual4.Children.InsertAtTop(inVisual4);


            _generator.CreateReflection(visual4, distance, 0.7f, ReflectionLocation.Right);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid4, visual4);

        }
Exemple #11
0
 public static Rect ToRect(this Vector2 topLeft, Vector2 bottomRight)
 {
     return(new Rect(topLeft.ToPoint(), bottomRight.ToSize()));
 }
        private async Task<CompositionMaskBrush> CreateMask(Color color, CanvasGeometry geometry, Vector2 size)
        {
            var compositionMask = await generator.CreateMaskAsync(size.ToSize(), geometry);

            var mask = compositor.CreateSurfaceBrush(compositionMask.Surface);
            var source = compositor.CreateColorBrush(color);

            var maskBrush = compositor.CreateMaskBrush();
            maskBrush.Mask = mask;
            maskBrush.Source = source;

            return maskBrush;
        }
Exemple #13
0
 public static Rect Add(this Rect target, Vector2 source)
 {
     return(target.Add(source.ToSize()));
 }
Exemple #14
0
        async void Redraw(bool recreateSurface = true)
        {
            if (_compositor == null)
            {
                _compositor = Window.Current.Compositor;
                _generator  = _compositor.CreateCompositionGenerator();

                _defaultSize = new Vector2(GridWidth, GridWidth);
                // Create the original output image visual
                _originalImageVisual      = _compositor.CreateSpriteVisual();
                _originalImageVisual.Size = _defaultSize;
                _imageSurface             = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/cat.png"), _defaultSize.ToSize(), ImageSurfaceOptions.Default);

                _originalImageVisual.Brush = _compositor.CreateSurfaceBrush(_imageSurface);
                ElementCompositionPreview.SetElementChildVisual(OriginalOutputGrid, _originalImageVisual);

                // Create the source image visual
                _sourceImageVisual      = _compositor.CreateSpriteVisual();
                _sourceImageVisual.Size = _defaultSize;
                ElementCompositionPreview.SetElementChildVisual(ImageGrid, _sourceImageVisual);

                //Create the mask visual
                _maskVisual      = _compositor.CreateSpriteVisual();
                _maskVisual.Size = _defaultSize;
                ElementCompositionPreview.SetElementChildVisual(MaskGrid, _maskVisual);

                // Create the output visual
                _outputVisual      = _compositor.CreateSpriteVisual();
                _outputVisual.Size = _defaultSize;
                ElementCompositionPreview.SetElementChildVisual(OutputGrid, _outputVisual);
            }

            var selIndex = ImageList.SelectedIndex;

            if (selIndex == -1)
            {
                return;
            }

            var uri = _images.Values.ElementAt(selIndex);

            if (uri == null)
            {
                return;
            }

            var offset = OffsetSlider.Value.ToSingle();

            var padding = new Thickness(offset);

            if (recreateSurface)
            {
                _sourceImageSurface =
                    await _generator.CreateImageSurfaceAsync(uri, _defaultSize.ToSize(), ImageSurfaceOptions.Default);

                _imageMaskSurface = _generator.CreateImageMaskSurface(_sourceImageSurface, _defaultSize.ToSize(),
                                                                      padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(_blurRadius));
            }
            else
            {
                _imageMaskSurface.Resize(_defaultSize.ToSize(), padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(_blurRadius));
            }

            _sourceImageVisual.Brush = _compositor.CreateSurfaceBrush(_sourceImageSurface);
            _maskVisual.Brush        = _compositor.CreateSurfaceBrush(_imageMaskSurface);
            var maskedBrush = _compositor.CreateMaskBrush();

            maskedBrush.Source = _originalImageVisual.Brush;
            maskedBrush.Mask   = _compositor.CreateSurfaceBrush(_imageMaskSurface);

            _outputVisual.Brush = maskedBrush;
        }
Exemple #15
0
 private void OnCanvasSizeChanged(object sender, Vector2 e)
 {
     _visual.Size       = e;
     _currentImage.Size = e.ToSize();
     SizeChanged?.Invoke(this, e);
 }
Exemple #16
0
        private void CreateTextAndBlendEffect(Vector2 sizeLightBounds)
        {
            //
            // Crete the effect graph, doing a hard light blend of the text over the
            // content already drawn into the backbuffer
            //

            IGraphicsEffect graphicsEffect = new BlendEffect()
            {
                Mode       = BlendEffectMode.HardLight,
                Foreground = new CompositionEffectSourceParameter("Text"),
                Background = new CompositionEffectSourceParameter("Destination"),
            };

            CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory(graphicsEffect, null);
            CompositionEffectBrush   brush         = effectFactory.CreateBrush();

            // Bind the destination brush
            brush.SetSourceParameter("Destination", _compositor.CreateBackdropBrush());


            //
            // Create the text surface which we'll scroll over the image with the lighting effect
            //

            // Pick a nice size font depending on target size
            const float maxFontSize = 72;
            const float scaleFactor = 12;
            float       fontSize    = Math.Min(sizeLightBounds.X / scaleFactor, maxFontSize);

            // Create the text format description, then the surface
            CanvasTextFormat textFormat = new CanvasTextFormat
            {
                FontFamily          = "Segoe UI",
                FontSize            = fontSize,
                FontWeight          = FontWeights.Bold,
                WordWrapping        = CanvasWordWrapping.WholeWord,
                HorizontalAlignment = CanvasHorizontalAlignment.Center,
                VerticalAlignment   = CanvasVerticalAlignment.Center
            };

            string text = "Ein bisschen Frieden, ein bisschen Sonne\n" +
                          "für diese Erde, auf der wir wohnen\n" +
                          "Ein bisschen Frieden, ein bisschen Freude\n" +
                          "ein bisschen Wärme, das wünsch' ich mir\n" +
                          "Ein bisschen Frieden, ein bisschen Träumen\n" +
                          "und dass die Menschen nicht so oft weinen\n" +
                          "Ein bisschen Frieden, ein bisschen Liebe\n" +
                          "dass ich die Hoffnung nie mehr verlier";

            // Make the surface twice the height to give us room to scroll
            Vector2        surfaceSize = new Vector2(sizeLightBounds.X, 2f * sizeLightBounds.Y);
            ManagedSurface textSurface = ImageLoader.Instance.LoadText(text, surfaceSize.ToSize(),
                                                                       textFormat, Colors.White, Colors.Transparent);

            brush.SetSourceParameter("Text", textSurface.Brush);

            // Create the sprite and parent it to the panel with the clip
            _textSprite       = _compositor.CreateSpriteVisual();
            _textSprite.Size  = surfaceSize;
            _textSprite.Brush = brush;

            ElementCompositionPreview.SetElementChildVisual(MyPanel, _textSprite);

            // Lastly, setup the slow scrolling animation of the text
            LinearEasingFunction     linear          = _compositor.CreateLinearEasingFunction();
            Vector3KeyFrameAnimation offsetAnimation = _compositor.CreateVector3KeyFrameAnimation();

            offsetAnimation.InsertKeyFrame(0f, new Vector3(0, 0, 0), linear);
            offsetAnimation.InsertKeyFrame(1f, new Vector3(0, -_textSprite.Size.Y * .5f, 0), linear);
            offsetAnimation.Duration          = TimeSpan.FromMilliseconds(30000);
            offsetAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
            _textSprite.StartAnimation("Offset", offsetAnimation);
        }
        /// <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;
        }
        /// <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 async void OnLoaded(object sender, RoutedEventArgs e)
        {
            _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
            _generator  = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            var distance   = 4f;
            var visualSize = new Vector2(225, 150);
            var vRefHeight = visualSize.Y + (visualSize.Y * 0.7f) + distance;
            var hRefWidth  = visualSize.X + (visualSize.X * 0.7f) + distance;

            var vRefLeft = (float)(CompositionGrid1.ActualWidth - visualSize.X) / 2f;
            var vRefTop  = (float)(CompositionGrid1.ActualHeight - vRefHeight) / 2f;
            var hRefLeft = (float)(CompositionGrid1.ActualWidth - hRefWidth) / 2f;
            var hRefTop  = (float)(CompositionGrid1.ActualHeight - visualSize.Y) / 2f;

            var surfaceImage = await _generator.CreateImageSurfaceAsync(new Uri("ms-appx:///Assets/Images/Car.jpg"),
                                                                        visualSize.ToSize(), ImageSurfaceOptions.Default);

            var surfaceBrush = _compositor.CreateSurfaceBrush(surfaceImage.Surface);

            var visual1 = _compositor.CreateSpriteVisual();

            visual1.Size   = visualSize;
            visual1.Offset = new Vector3(vRefLeft, vRefTop, 0);
            visual1.Brush  = surfaceBrush;

            _generator.CreateReflection(visual1, distance);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid1, visual1);

            var invertEffect = new InvertEffect()
            {
                Source = new CompositionEffectSourceParameter("source")
            };

            var invertEffectFactory = _compositor.CreateEffectFactory(invertEffect);
            var invertBrush         = invertEffectFactory.CreateBrush();

            invertBrush.SetSourceParameter("source", surfaceBrush);

            var visual2 = _compositor.CreateSpriteVisual();

            visual2.Size   = visualSize;
            visual2.Offset = new Vector3(hRefLeft, hRefTop, 0);
            visual2.Brush  = invertBrush;

            _generator.CreateReflection(visual2, distance, 0.7f, ReflectionLocation.Right);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid2, visual2);

            var visual3 = _compositor.CreateSpriteVisual();

            visual3.Size   = visualSize;
            visual3.Offset = new Vector3(vRefLeft, vRefTop, 0);
            visual3.Brush  = surfaceBrush;

            var inVisual = _compositor.CreateSpriteVisual();

            inVisual.Size   = new Vector2(80, 80);
            inVisual.Offset = new Vector3(20, 10, 0);
            inVisual.Brush  = _compositor.CreateColorBrush(Colors.Yellow);

            var inVisual2 = _compositor.CreateSpriteVisual();

            inVisual2.Size   = new Vector2(80, 80);
            inVisual2.Offset = new Vector3(60, 60, 0);
            inVisual2.Brush  = _compositor.CreateColorBrush(Colors.Blue);
            visual3.Children.InsertAtTop(inVisual2);
            visual3.Children.InsertAtTop(inVisual);

            _generator.CreateReflection(visual3, distance, 0.7f, ReflectionLocation.Bottom);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid3, visual3);

            var visual4 = _compositor.CreateSpriteVisual();

            visual4.Size   = visualSize;
            visual4.Offset = new Vector3(hRefLeft, hRefTop, 0);
            visual4.Brush  = surfaceBrush;

            var inVisual3 = _compositor.CreateSpriteVisual();

            inVisual3.Size   = new Vector2(80, 80);
            inVisual3.Offset = new Vector3(20, 10, 0);
            inVisual3.Brush  = _compositor.CreateColorBrush(Colors.Yellow);

            var inVisual4 = _compositor.CreateSpriteVisual();

            inVisual4.Size   = new Vector2(80, 80);
            inVisual4.Offset = new Vector3(60, 40, 0);
            inVisual4.Brush  = _compositor.CreateColorBrush(Colors.Blue);
            visual4.Children.InsertAtTop(inVisual3);
            visual4.Children.InsertAtTop(inVisual4);


            _generator.CreateReflection(visual4, distance, 0.7f, ReflectionLocation.Right);

            ElementCompositionPreview.SetElementChildVisual(CompositionGrid4, visual4);
        }
Exemple #20
0
        private void CreateTextAndBlendEffect(Vector2 sizeLightBounds)
        {
            //
            // Crete the effect graph, doing a hard light blend of the text over the
            // content already drawn into the backbuffer
            //

            IGraphicsEffect graphicsEffect = new BlendEffect()
            {
                Mode       = BlendEffectMode.HardLight,
                Foreground = new CompositionEffectSourceParameter("Text"),
                Background = new CompositionEffectSourceParameter("Destination"),
            };

            CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory(graphicsEffect, null);
            CompositionEffectBrush   brush         = effectFactory.CreateBrush();

            // Bind the destination brush
            brush.SetSourceParameter("Destination", _compositor.CreateBackdropBrush());


            //
            // Create the text surface which we'll scroll over the image with the lighting effect
            //

            // Pick a nice size font depending on target size
            const float maxFontSize = 72;
            const float scaleFactor = 12;
            float       fontSize    = Math.Min(sizeLightBounds.X / scaleFactor, maxFontSize);

            // Create the text format description, then the surface
            CanvasTextFormat textFormat = new CanvasTextFormat
            {
                FontFamily          = "Segoe UI",
                FontSize            = fontSize,
                FontWeight          = FontWeights.Bold,
                WordWrapping        = CanvasWordWrapping.WholeWord,
                HorizontalAlignment = CanvasHorizontalAlignment.Center,
                VerticalAlignment   = CanvasVerticalAlignment.Center
            };

            string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec efficitur, eros sit amet laoreet scelerisque, " +
                          "nunc odio ultricies metus, ut consectetur nulla massa eu nibh.Phasellus in lorem id nunc euismod tempus.Phasellus et nulla non turpis tempor blandit ut eget turpis." +
                          "Phasellus ac ornare elit, ut scelerisque dolor. Nam vel finibus lorem. Aenean malesuada pulvinar eros id ornare. Fusce blandit ante eget dolor efficitur suscipit." +
                          "Phasellus ac lacus nibh. Aenean eget blandit risus, in lacinia mi. Proin fermentum ante eros, non sollicitudin mi pretium eu. Curabitur suscipit lectus arcu, eget" +
                          "pretium quam sagittis non. Mauris purus mauris, condimentum nec laoreet sit amet, imperdiet sit amet nisi. Sed interdum, urna et aliquam porta, elit velit tincidunt orci," +
                          "vitae vestibulum risus lacus at nulla.Phasellus sapien ipsum, pellentesque varius enim nec, iaculis aliquet enim. Nulla id dapibus ante. Sed hendrerit sagittis leo, commodo" +
                          "fringilla ligula rutrum ut. Nullam sodales, ex ut pellentesque scelerisque, sapien nulla mattis lectus, vel ullamcorper leo enim ac mi.Sed consectetur vitae velit in consequat." +
                          "Pellentesque ac condimentum justo, at feugiat nulla. Sed ut congue neque. Nam gravida quam ac urna porttitor, ut bibendum ante mattis.Cras viverra cursus sapien, et sollicitudin" +
                          "risus fringilla eget. Nulla facilisi. Duis pellentesque scelerisque nisi, facilisis malesuada massa gravida et. Vestibulum ac leo sed orci tincidunt feugiat.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc id leo vestibulum, vulputate ipsum sit amet, scelerisque velit. Curabitur imperdiet justo et tortor dignissim, sit amet volutpat sem ullamcorper. Nam mollis ullamcorper tellus vitae convallis. Aliquam eleifend elit nec tincidunt pharetra. Aliquam turpis eros, mollis et nunc quis, porta molestie justo. Etiam ultrices sem non turpis imperdiet dictum.Aliquam molestie elit in urna sodales, nec luctus dui laoreet.Curabitur molestie risus vel ligula efficitur, non fringilla urna iaculis.Curabitur neque tortor, facilisis quis dictum facilisis, facilisis et ante. Sed nisl erat, semper vitae efficitur ut, congue vitae quam. Ut auctor lacus sit amet varius placerat.Sed ac tellus tempus, ultricies est quis, tempor felis.Nulla vel faucibus elit, eu tincidunt eros. Nulla blandit id nisl ut porta. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam suscipit tellus a mattis pulvinar. Sed et libero vel ligula elementum suscipit.Ut elementum libero at sagittis pharetra. Fusce ultrices odio sapien, a posuere est consectetur ut.";

            // Make the surface twice the height to give us room to scroll
            Vector2 surfaceSize = new Vector2(sizeLightBounds.X, 2f * sizeLightBounds.Y);
            CompositionDrawingSurface textSurface = SurfaceLoader.LoadText(text, surfaceSize.ToSize(),
                                                                           textFormat, Colors.White, Colors.Transparent);

            brush.SetSourceParameter("Text", _compositor.CreateSurfaceBrush(textSurface));

            // Create the sprite and parent it to the panel with the clip
            _textSprite       = _compositor.CreateSpriteVisual();
            _textSprite.Size  = surfaceSize;
            _textSprite.Brush = brush;

            ElementCompositionPreview.SetElementChildVisual(MyPanel, _textSprite);

            // Lastly, setup the slow scrolling animation of the text
            LinearEasingFunction     linear          = _compositor.CreateLinearEasingFunction();
            Vector3KeyFrameAnimation offsetAnimation = _compositor.CreateVector3KeyFrameAnimation();

            offsetAnimation.InsertKeyFrame(0f, new Vector3(0, 0, 0), linear);
            offsetAnimation.InsertKeyFrame(1f, new Vector3(0, -_textSprite.Size.Y * .5f, 0), linear);
            offsetAnimation.Duration          = TimeSpan.FromMilliseconds(30000);
            offsetAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
            _textSprite.StartAnimation("Offset", offsetAnimation);
        }
        /// <summary>
        /// Handles the Arrange pass during Layout
        /// </summary>
        /// <param name="finalSize">Final Size of the control</param>
        /// <returns>Total size occupied by the Children</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Taking into account the BorderThickness and Padding
            var borders = BorderThickness;
            var padding = Padding;
            var corners = CornerRadius;
            var borderSize = borders.CollapseThickness();
            var paddingSize = padding.CollapseThickness();

            // Calculate the Offset for the frameVisual
            var left = (borders.Left + padding.Left).Single();
            var top = (borders.Top + padding.Top).Single();

            // Calculate the Dimensions of the frameVisual
            var width = Math.Max(0, finalSize.Width - borderSize.Width - paddingSize.Width).Single();
            var height = Math.Max(0, finalSize.Height - borderSize.Height - paddingSize.Height).Single();

            // Set the Size and Offset of visuals in the ImageFrame
            var frameSize = new Vector2(width, height);
            _rootContainer.Size = frameSize;
            _frameLayer.Size = frameSize;
            _frameBackgroundVisual.Size = frameSize;
            _frameContentVisual.Size = frameSize;
            _placeholderContentVisual.Size = frameSize;
            _placeholderBackgroundVisual.Size = frameSize;
            _shadowVisual.Size = frameSize;
            _nextVisualContent.Size = frameSize;
            _rootContainer.Offset = new Vector3(left, top, 0);

            // Update the frameLayerMask in case the CornerRadius or 
            // BorderThickness or Padding has changed
            var pathInfo = new CompositionPathInfo(corners, borders, padding, false);
            using (var geometry =
                CompositionGenerator.GenerateGeometry(_generator.Device, frameSize.ToSize(),
                    pathInfo, Vector2.Zero))
            {
                _frameLayerMask.Redraw(_frameLayer.Size.ToSize(), geometry);
            }

            // If the FrameBackground has changed since the last time it was
            // applied to the frameBackgroundVisual, then animate the brush's
            // color to the new color.
            var brush = _frameBackgroundVisual.Brush as CompositionColorBrush;
            if (brush != null)
            {
                if (!brush.Color.Equals(FrameBackground))
                {
                    // If we are rendering fast, then no need to animate.
                    // Just set the final value.
                    if (RenderFast)
                    {
                        brush.Color = FrameBackground;
                    }
                    else
                    {
                        _colorAnimation.InsertKeyFrame(1f, FrameBackground);
                        brush.StartAnimation("Color", _colorAnimation);
                    }
                }
            }

            // If the PlaceholderBackground has changed since the last time it was
            // applied to the _placeholderBackgroundVisual, then update the brush's
            // color to the new color.
            brush = _placeholderBackgroundVisual.Brush as CompositionColorBrush;
            if (brush != null)
            {
                if (!brush.Color.Equals(PlaceholderBackground))
                {
                    brush.Color = PlaceholderBackground;
                }
            }

            // Redraw the placeholder content with the latest placeholder color
            _placeholderContentMask.Redraw(PlaceholderColor, PlaceholderBackground);

            // Set the stretch property of placeholder content's brush according to its size
            if ((width > PlaceholderSize.Width) && (height > PlaceholderSize.Height))
            {
                _placeholderContentBrush.Stretch = CompositionStretch.None;
            }
            else
            {
                _placeholderContentBrush.Stretch = CompositionStretch.Uniform;
            }

            // Update the imageOptions
            _imageOptions.Stretch = Stretch;
            _imageOptions.HorizontalAlignment = AlignX;
            _imageOptions.VerticalAlignment = AlignY;
            _imageOptions.Interpolation = Interpolation;
            _imageOptions.SurfaceBackgroundColor = Colors.Transparent;
            _imageOptions.AutoResize = !RenderOptimized;

            // If Source is valid then try loading/refreshing the ImageSurface
            if (Source != null)
            {
                if (_imageSurface != null)
                {
                    // Resize the ImageSurface to the new size
                    _imageSurface.Resize(frameSize.ToSize(), _imageOptions);
                    // Update the surface brush based on the Stretch and Alignment options
                    if (RenderFast)
                    {
                        // Use no animations to update alignment if we are rendering fast
                        (_frameContentVisual.Brush as CompositionSurfaceBrush)?.UpdateSurfaceBrushOptions(Stretch,
                            AlignX, AlignY);
                    }
                    else
                    {
                        // Update stretch and alignment using animation
                        (_frameContentVisual.Brush as CompositionSurfaceBrush)?.UpdateSurfaceBrushOptions(Stretch,
                            AlignX, AlignY, _alignXAnimation, _alignYAnimation);
                    }
                }
                else
                {
                    // Load the Source to the ImageSurface
                    ScheduleNextLoad();
                }
            }
            else
            {
                // If the frameContentVisual had any previous brush, fade it out
                if (_imageSurface == null)
                {
                    // Make the frameVisualContent transparent
                    _frameContentVisual.Brush = _compositor.CreateColorBrush(Colors.Transparent);
                    DisplayPlaceHolder();
                    _engineState = ImageEngineState.Idle;
                }
            }

            // Handle shadow
            if (DisplayShadow)
            {
                // If OptimizeShadow is True then use the sharedShadow otherwise use the instance shadow
                var shadow = OptimizeShadow
                             ? ShadowProvider.GetSharedShadow(_compositor) 
                             : (_shadow ?? (_shadow = _compositor.CreateDropShadow()));

                shadow.BlurRadius = ShadowBlurRadius.Single();
                shadow.Color = ShadowColor;
                shadow.Offset = new Vector3(ShadowOffsetX.Single(), ShadowOffsetY.Single(), 0);
                shadow.Opacity = ShadowOpacity.Single();
                shadow.Mask = _layerEffectBrush.GetSourceParameter("mask");

                _shadowVisual.Shadow = shadow;
            }
            else
            {
                _shadowVisual.Shadow = null;
            }

            return base.ArrangeOverride(finalSize);
        }