Example #1
0
        private Visual GetVideoRecording(Compositor compositor, float width, float height, Color color)
        {
            // Begin ellipse
            var ellipse = compositor.CreateEllipseGeometry();

            var ellipseSprite = compositor.CreateSpriteShape(ellipse);
            var ellipseBrush  = ellipseSprite.FillBrush = compositor.CreateColorBrush(color);

            ellipseSprite.Offset = new Vector2(width / 2, height / 2);

            // Begin shape
            var shape = compositor.CreateShapeVisual();

            shape.Shapes.Add(ellipseSprite);
            shape.Size  = new Vector2(width, height);
            shape.Scale = new Vector3(2, 2, 0);

            // Begin animation
            var props = compositor.CreatePropertySet();

            props.InsertScalar("animationValue", 0.0f);

            var reference      = props.GetReference();
            var animationValue = reference.GetScalarProperty("animationValue");

            var easing             = compositor.CreateCubicBezierEasingFunction(new Vector2(0.42f, 0), new Vector2(0.58f, 1));
            var animationValueImpl = compositor.CreateScalarKeyFrameAnimation();

            animationValueImpl.InsertKeyFrame(0, 0, easing);
            animationValueImpl.InsertKeyFrame(1, 1, easing);
            animationValueImpl.Duration          = TimeSpan.FromMilliseconds(900);
            animationValueImpl.IterationBehavior = AnimationIterationBehavior.Forever;

            props.StartAnimation("animationValue", animationValueImpl);

            ScalarNode animValue = EF.Conditional(animationValue < 0.5f, animationValue / 0.5f, (1 - animationValue) / 0.5f);

            ScalarNode alpha  = 1.0f - animValue * 0.6f;
            ScalarNode radius = 3.5f - animValue * 0.66f;

            ExpressionNode colorEllipse  = EF.ColorRgb(alpha * 255, color.R, color.G, color.B);
            ExpressionNode radiusEllipse = EF.Vector2(radius, radius);

            ellipseBrush.StartAnimation("Color", colorEllipse);
            ellipse.StartAnimation("Radius", radiusEllipse);

            return(shape);
        }
Example #2
0
        private void OnTilePointerPressed(object sender, PointerRoutedEventArgs e)
        {
            var tileGrid     = (Grid)sender;
            var colorElement = (Rectangle)tileGrid.FindName("ColorElement");

            // Set the CenterPoint of the backing Visual, so the rotation axis will defined from the middle.
            colorElement.Visual().CenterPoint = new Vector3(tileGrid.RenderSize.ToVector2() / 2, 0.0f);

            // Calculate distance from corner of quadrant to Center
            _center = colorElement.Visual().CenterPoint;
            var xSquared = Math.Pow(tileGrid.ActualWidth / 2, 2);
            var ySquared = Math.Pow(tileGrid.ActualHeight / 2, 2);

            _distanceToCenter = (float)Math.Sqrt(xSquared + ySquared);

            // || DEFINE THE EXPRESSION FOR THE ROTATION ANGLE ||
            // We calculate the Rotation Angle such that it increases from 0 to 3 as the cursor position moves away from the center.
            // Combined with animating the Rotation Axis, the image is "push down" on the point at which the cursor is located.
            var pointerPositionProperties = ElementCompositionPreview.GetPointerPositionPropertySet(tileGrid);
            var pointerPosition           = pointerPositionProperties.GetSpecializedReference <PointerPositionPropertySetReferenceNode>().Position;
            var angleExpressionNode       = 3 * (EF.Clamp(EF.Distance(_center, pointerPosition), 0, _distanceToCenter) % _distanceToCenter / _distanceToCenter);

            var rotationAngleAnimation = _compositor.CreateScalarKeyFrameAnimation();

            rotationAngleAnimation.Duration = TimeSpan.FromMilliseconds(600);
            rotationAngleAnimation.InsertExpressionKeyFrame(0.4f, angleExpressionNode);
            rotationAngleAnimation.InsertKeyFrame(1.0f, 0.0f);

            colorElement.Visual().StartAnimation("RotationAngleInDegrees", rotationAngleAnimation);

            // || DEFINE THE EXPRESSION FOR THE ROTATION AXIS ||
            // The RotationAxis will be defined as the axis perpendicular to vector position of the hover pointer (vector from center to hover position).
            // The axis is a vector calculated by first converting the pointer position into the coordinate space where the center point (0, 0) is in the middle.
            // The perpendicular axis is then calculated by transposing the cartesian x, y components and negating one (e.g. Vector3(-y,x,0) )
            var axisAngleExpressionNode = EF.Floor((pointerPosition.X - _center.X) * EF.Conditional(pointerPosition.X == _center.X, 0, 1));

            var rotationAxisAnimation = _compositor.CreateScalarKeyFrameAnimation();

            rotationAxisAnimation.Duration = TimeSpan.FromMilliseconds(600);
            rotationAxisAnimation.InsertExpressionKeyFrame(0.4f, axisAngleExpressionNode);
            rotationAxisAnimation.InsertKeyFrame(1.0f, 0.0f);

            colorElement.Visual().StartAnimation("RotationAxis.Y", rotationAxisAnimation);
        }
Example #3
0
        private void TiltUIElement()
        {
            // Grab the backing Visual for the UIElement image
            _tiltVisual = ElementCompositionPreview.GetElementVisual(tiltImage);

            // Set the CenterPoint of the backing Visual, so the rotation axis will defined from the middle
            _tiltVisual.CenterPoint = new Vector3((float)tiltImage.Width / 2, (float)tiltImage.Height / 2, 0f);

            // Grab the PropertySet containing the hover pointer data that will be used to drive the rotations
            // Note: We have a second UIElement we will grab the pointer data against and the other we will animate
            _hoverPositionPropertySet = ElementCompositionPreview.GetPointerPositionPropertySet(HitTestRect);

            // Calculate distance from corner of quadrant to Center
            var center           = new Vector3((float)tiltImage.Width / 2, (float)tiltImage.Height / 2, 0);
            var xSquared         = Math.Pow(tiltImage.Width / 2, 2);
            var ySquared         = Math.Pow(tiltImage.Height / 2, 2);
            var distanceToCenter = (float)Math.Sqrt(xSquared + ySquared);

            // || DEFINE THE EXPRESSION FOR THE ROTATION ANGLE ||
            // We calculate the Rotation Angle such that it increases from 0 to 35 as the cursor position moves away from the center.
            // Combined with animating the Rotation Axis, the image is "push down" on the point at which the cursor is located.
            // Note: We special case when the hover position is (0,0,0) as this is the starting hover position and and we want the image to be flat (rotationAngle = 0) at startup.
            var hoverPosition       = _hoverPositionPropertySet.GetSpecializedReference <PointerPositionPropertySetReferenceNode>().Position;
            var angleExpressionNode =
                EF.Conditional(
                    hoverPosition == new Vector3(0, 0, 0),
                    ExpressionValues.CurrentValue.CreateScalarCurrentValue(),
                    35 * ((EF.Clamp(EF.Distance(center, hoverPosition), 0, distanceToCenter) % distanceToCenter) / distanceToCenter));

            _tiltVisual.StartAnimation("RotationAngleInDegrees", angleExpressionNode);

            // || DEFINE THE EXPRESSION FOR THE ROTATION AXIS ||
            // The RotationAxis will be defined as the axis perpendicular to vector position of the hover pointer (vector from center to hover position).
            // The axis is a vector calculated by first converting the pointer position into the coordinate space where the center point (0, 0) is in the middle.
            // The perpendicular axis is then calculated by transposing the cartesian x, y components and negating one (e.g. Vector3(-y,x,0) )
            var axisAngleExpressionNode = EF.Vector3(
                -(hoverPosition.Y - center.Y) * EF.Conditional(hoverPosition.Y == center.Y, 0, 1),
                (hoverPosition.X - center.X) * EF.Conditional(hoverPosition.X == center.X, 0, 1),
                0);

            _tiltVisual.StartAnimation("RotationAxis", axisAngleExpressionNode);
        }
Example #4
0
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            // Retrieve the ScrollViewer that the GridView is using internally
            var scrollViewer = gridView.GetFirstDescendantOfType <ScrollViewer>();

            // Update the ZIndex of the header container so that the header is above the items when scrolling
            var headerPresenter = (UIElement)VisualTreeHelper.GetParent((UIElement)gridView.Header);
            var headerContainer = (UIElement)VisualTreeHelper.GetParent(headerPresenter);

            Canvas.SetZIndex((UIElement)headerContainer, 1);

            // Get the PropertySet that contains the scroll values from the ScrollViewer
            _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
            _compositor          = _scrollerPropertySet.Compositor;

            // Create a PropertySet that has values to be referenced in the ExpressionAnimations below
            _props = _compositor.CreatePropertySet();
            _props.InsertScalar("progress", 0);
            _props.InsertScalar("clampSize", 150);
            _props.InsertScalar("scaleFactor", 0.7f);

            // Get references to our property sets for use with ExpressionNodes
            var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>();
            var props           = _props.GetReference();
            var progressNode    = props.GetScalarProperty("progress");
            var clampSizeNode   = props.GetScalarProperty("clampSize");
            var scaleFactorNode = props.GetScalarProperty("scaleFactor");

            // Create a blur effect to be animated based on scroll position
            var blurEffect = new GaussianBlurEffect()
            {
                Name         = "blur",
                BlurAmount   = 0.0f,
                BorderMode   = EffectBorderMode.Hard,
                Optimization = EffectOptimization.Balanced,
                Source       = new CompositionEffectSourceParameter("source")
            };

            var blurBrush = _compositor.CreateEffectFactory(
                blurEffect,
                new[] { "blur.BlurAmount" })
                            .CreateBrush();

            blurBrush.SetSourceParameter("source", _compositor.CreateBackdropBrush());

            // Create a Visual for applying the blur effect
            _blurredBackgroundImageVisual       = _compositor.CreateSpriteVisual();
            _blurredBackgroundImageVisual.Brush = blurBrush;
            _blurredBackgroundImageVisual.Size  = new Vector2((float)OverlayRectangle.ActualWidth, (float)OverlayRectangle.ActualHeight);

            // Insert the blur visual at the right point in the Visual Tree
            ElementCompositionPreview.SetElementChildVisual(OverlayRectangle, _blurredBackgroundImageVisual);

            // Create and start an ExpressionAnimation to track scroll progress over the desired distance
            ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);

            _props.StartAnimation("progress", progressAnimation);

            // Create and start an ExpressionAnimation to animate blur radius between 0 and 15 based on progress
            ExpressionNode blurAnimation = EF.Lerp(0, 15, progressNode);

            _blurredBackgroundImageVisual.Brush.Properties.StartAnimation("blur.BlurAmount", blurAnimation);

            // Get the backing visual for the header so that its properties can be animated
            Visual headerVisual = ElementCompositionPreview.GetElementVisual(Header);

            // Create and start an ExpressionAnimation to clamp the header's offset to keep it onscreen
            ExpressionNode headerTranslationAnimation = EF.Conditional(progressNode < 1, 0, -scrollingProperties.Translation.Y - clampSizeNode);

            headerVisual.StartAnimation("Offset.Y", headerTranslationAnimation);

            // Create and start an ExpressionAnimation to scale the header during overpan
            ExpressionNode headerScaleAnimation = EF.Lerp(1, 1.25f, EF.Clamp(scrollingProperties.Translation.Y / 50, 0, 1));

            headerVisual.StartAnimation("Scale.X", headerScaleAnimation);
            headerVisual.StartAnimation("Scale.Y", headerScaleAnimation);

            //Set the header's CenterPoint to ensure the overpan scale looks as desired
            headerVisual.CenterPoint = new Vector3((float)(Header.ActualWidth / 2), (float)Header.ActualHeight, 0);

            // Get the backing visual for the photo in the header so that its properties can be animated
            Visual photoVisual = ElementCompositionPreview.GetElementVisual(BackgroundRectangle);

            // Create and start an ExpressionAnimation to opacity fade out the image behind the header
            ExpressionNode imageOpacityAnimation = 1 - progressNode;

            photoVisual.StartAnimation("opacity", imageOpacityAnimation);

            // Get the backing visual for the profile picture visual so that its properties can be animated
            Visual profileVisual = ElementCompositionPreview.GetElementVisual(ProfileImage);

            // Create and start an ExpressionAnimation to scale the profile image with scroll position
            ExpressionNode scaleAnimation = EF.Lerp(1, scaleFactorNode, progressNode);

            profileVisual.StartAnimation("Scale.X", scaleAnimation);
            profileVisual.StartAnimation("Scale.Y", scaleAnimation);

            // Get backing visuals for the text blocks so that their properties can be animated
            Visual blurbVisual    = ElementCompositionPreview.GetElementVisual(Blurb);
            Visual subtitleVisual = ElementCompositionPreview.GetElementVisual(SubtitleBlock);
            Visual moreVisual     = ElementCompositionPreview.GetElementVisual(MoreText);

            // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for text block opacity
            ExpressionNode textOpacityAnimation = EF.Clamp(1 - (progressNode * 2), 0, 1);

            // Start opacity and scale animations on the text block visuals
            blurbVisual.StartAnimation("Opacity", textOpacityAnimation);
            blurbVisual.StartAnimation("Scale.X", scaleAnimation);
            blurbVisual.StartAnimation("Scale.Y", scaleAnimation);

            subtitleVisual.StartAnimation("Opacity", textOpacityAnimation);
            subtitleVisual.StartAnimation("Scale.X", scaleAnimation);
            subtitleVisual.StartAnimation("Scale.Y", scaleAnimation);

            moreVisual.StartAnimation("Opacity", textOpacityAnimation);
            moreVisual.StartAnimation("Scale.X", scaleAnimation);
            moreVisual.StartAnimation("Scale.Y", scaleAnimation);

            // Get the backing visuals for the text and button containers so that their properites can be animated
            Visual textVisual   = ElementCompositionPreview.GetElementVisual(TextContainer);
            Visual buttonVisual = ElementCompositionPreview.GetElementVisual(ButtonPanel);

            // When the header stops scrolling it is 150 pixels offscreen.  We want the text header to end up with 50 pixels of its content
            // offscreen which means it needs to go from offset 0 to 100 as we traverse through the scrollable region
            ExpressionNode contentOffsetAnimation = progressNode * 100;

            textVisual.StartAnimation("Offset.Y", contentOffsetAnimation);

            ExpressionNode buttonOffsetAnimation = progressNode * -100;

            buttonVisual.StartAnimation("Offset.Y", buttonOffsetAnimation);
        }