Example #1
0
        private void SetupImageList()
        {
            // Note: Translation is an additive value to the Offset property when defining the final position of a backed visual of a UIElement

            // This Expression defines an equation that changes the Y Translation of an image based on the scale of its vertical neighbor image.
            // As the scale of an image grows, the images below it will dynamically move down.
            // The equation is built by summing up two different deltas caused by a scale animation:
            //    1) The delta caused by the image directly above the target scaling to a value > 1 (should have no effect if scale == 1)
            //    2) Any additional delta caused by if the image above has translated down because the image above it (or higher up) has scaled up
            //        [Will either be a large scale from Click, or medium scale if on hover]
            // Note: 120 represents the height of the images + the gap between them

            var visualPlaceHolder = EV.Reference.CreateVisualReference("visual");
            var factor            = EV.Constant.CreateConstantScalar("factor");

            _translationDeltaExp = ((visualPlaceHolder.Scale.Y - 1) * (float)image.Height) +
                                   EF.Conditional(
                ((visualPlaceHolder.Translation.Y / (120 * factor)) > 1),
                (EV.Constant.CreateConstantScalar("largeScaleDiff")),
                visualPlaceHolder.Translation.Y % (120 * factor)
                );

            // Activate Translation property for Visuals backing a UIElement
            TranslationSetup(image);
            TranslationSetup(image2);
            TranslationSetup(image3);
            TranslationSetup(image4);

            // Setup the Expression on the Y Translation property for images 2 - 4.
            // Pass in the target image that the Expression gets applied to, the image above it for reference and images indexed position
            // Note: Since the first image does not have an image above it, do not need to apply the Expression to it
            StartAnimationHelper(image2, image, 1);
            StartAnimationHelper(image3, image2, 2);
            StartAnimationHelper(image4, image3, 3);
        }
Example #2
0
        private void ConfigureTemplateAnimations()
        {
            var propSetProgress = _props.GetReference().GetScalarProperty("progress");
            var trackerNode     = _tracker.GetReference();

            foreach (var itemRendered in itemsRendered.Items)
            {
                var template = itemRendered.Item2;

                template.GetVisual().StopAnimation("offset.x");
                template.GetVisual().StopAnimation("Scale");

                template.GetVisual().StartAnimation("offset.x", _props.GetReference().GetScalarProperty("position") + itemRendered.Item1 * _itemWidth);

                float positionCenter = (itemRendered.Item1 * _itemWidth);
                float position       = (itemRendered.Item1 * _itemWidth) - _itemWidth / 2;
                float positionEnd    = (itemRendered.Item1 * _itemWidth) + _itemWidth / 2;

                template.GetVisual()
                .StartAnimation("Scale",
                                EF.Vector3(1, 1, 1) * EF.Conditional(trackerNode.Position.X > position & trackerNode.Position.X < positionEnd
                                                                     , EF.Lerp(1.2f, 1, EF.Abs(positionCenter - trackerNode.Position.X) / (_itemWidth / 2))
                                                                     , 1));


                template.BackgroundPanel
                .StartAnimation("Scale",
                                EF.Vector3(1, 1, 1) * EF.Conditional(trackerNode.Position.X > position & trackerNode.Position.X < positionEnd
                                                                     , EF.Lerp(1.1f, 1, EF.Abs(positionCenter - trackerNode.Position.X) / (_itemWidth / 2))
                                                                     , 1));

                template.Shadow
                .StartAnimation("opacity",
                                EF.Conditional(trackerNode.Position.X > position & trackerNode.Position.X < positionEnd
                                               , EF.Lerp(1, 0, EF.Abs(positionCenter - trackerNode.Position.X) / (_itemWidth / 2))
                                               , 0));

                template.ContentPanel
                .StartAnimation("opacity",
                                EF.Conditional(trackerNode.Position.X > position & trackerNode.Position.X < positionEnd
                                               , EF.Lerp(1, 0, EF.Abs(positionCenter - trackerNode.Position.X) / (_itemWidth / 2))
                                               , 0));

                template.OverlayPanel
                .StartAnimation("opacity",
                                EF.Conditional(trackerNode.Position.X > position & trackerNode.Position.X < positionEnd
                                               , EF.Lerp(0, 0.6f, EF.Abs(positionCenter - trackerNode.Position.X) / (_itemWidth / 2))
                                               , 0.6f));
            }
        }
        /// <summary>
        /// Create the _frontVisual and the animations that drive it.
        /// </summary>
        /// <param name="scrollProperties">A property set who has Translation.Y specified - typically the return from ElementCompositionPreview.GetScrollViewerManipulationPropertySet(...).</param>
        /// <param name="maskedBrush">This is the brush that will be set on _frontVisual</param>
        private void InitializeFrontVisual(CompositionPropertySet scrollProperties, CompositionEffectBrush maskedBrush)
        {
            //
            // Create  the _frontVisual, set the brush on it, and attach it to the scrollViewer.  Setting it as the
            // child visual on scrollviewer will put it in front of all the scrollViewer content.
            //
            _frontVisual       = _compositor.CreateSpriteVisual();
            _frontVisual.Brush = maskedBrush;
            ElementCompositionPreview.SetElementChildVisual(MainGrid, _frontVisual);

            //
            // "Terms" in the following expression:
            //
            //      (CrossoverTranslation + scrollingProperties.Translation.Y)/CrossoverTranslation
            //
            //              Since scrollingProperties.Translation.Y is negative.  This creates a normalized value that goes from
            //              0 to 1 between no scrolling and the CrossoverTranslation.
            //

            var scrollPropSet        = scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>();
            var crossoverTranslation = ExpressionValues.Constant.CreateConstantScalar("CrossoverTranslation");

            _frontPropertiesScaleExpression = EF.Lerp(
                _finalScaleAmount,
                _initialScaleAmount,
                EF.Clamp((crossoverTranslation + scrollPropSet.Translation.Y) / crossoverTranslation, 0, 1));

            //
            // The previous equation calculates a scalar which is later bound to ScalarScale in FrontVisual's Properties.
            // This equation uses that scalar to construct a new vector3 to set to animate the scale of the visual itself.
            //

            _frontVisual.Properties.InsertScalar("ScalarScale", 1);
            var frontScalarScale    = _frontVisual.GetReference().GetScalarProperty("ScalarScale");
            var vec3ScaleExpression = EF.Vector3(frontScalarScale, frontScalarScale, 1);

            _frontVisual.StartAnimation("Scale", vec3ScaleExpression);

            //
            // This equation controls whether or not the FrontVisual is visibile via opacity.  It uses a simple ternary operator
            // to pick between 100% and 0% opacity based on the position being before the crossover point.
            //

            _frontVisibilityExpression = EF.Conditional(-scrollPropSet.Translation.Y <= crossoverTranslation, 1, 0);

            var baseOffset = ExpressionValues.Constant.CreateConstantScalar("BaseOffset");

            _frontTranslationExpression = EF.Conditional(scrollPropSet.Translation.Y > 0, baseOffset, baseOffset - scrollPropSet.Translation.Y);
        }
        /// <summary>
        /// Create the Visual that will host the profile background image and setup
        /// the animations that will drive it.
        /// </summary>
        /// /// <param name="scrollProperties">A property set who has Translation.Y specified - typically the return from ElementCompositionPreview.GetScrollViewerManipulationPropertySet(...).</param>
        private void InitializeBackgroundImageVisual(CompositionPropertySet scrollProperties)
        {
            //
            // Get the visual for the background image, and let it parallax up until the BackgroundPeekSize.
            // BackgroundPeekSize is later defined as the amount of the image to leave showing.
            //
            _backgroundVisual = ElementCompositionPreview.GetElementVisual(ParallaxingImage);

            //
            // If the scrolling is positive (i.e., bouncing), don't translate at all.  Then check to see if
            // we have parallaxed as far as we should go.  If we haven't, keep parallaxing otherwise use
            // the scrolling translation to keep the background stuck with the background peeking out.
            //

            var scrollPropSet      = scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>();
            var baseOffsetParam    = ExpressionValues.Constant.CreateConstantScalar("BaseOffset");
            var backgroundPeekSize = ExpressionValues.Constant.CreateConstantScalar("BackgroundPeekSize");

            _backgroundTranslateExpression = baseOffsetParam +
                                             EF.Conditional(scrollPropSet.Translation.Y > 0,
                                                            0,
                                                            EF.Conditional(((1 - _parallaxRatio) * -scrollPropSet.Translation.Y) < backgroundPeekSize,
                                                                           (_parallaxRatio * -scrollPropSet.Translation.Y),
                                                                           -backgroundPeekSize - scrollPropSet.Translation.Y));

            _backgroundScaleExpression = EF.Lerp(1, 1 + _backgroundScaleAmount, EF.Clamp(scrollPropSet.Translation.Y / 50, 0, 1));

            _backgroundBlurExpression = EF.Clamp(-scrollPropSet.Translation.Y / (backgroundPeekSize * 0.5f), 0, 1);

            _backgroundInverseBlurExpression = 1 - EF.Clamp(-scrollPropSet.Translation.Y / (backgroundPeekSize * 0.5f), 0, 1);

            //
            // We want to keep the Name/Title text in the middle of the background image.  To start with,
            // we add the centerpoint - since we move the anchor point to (.5,/5) which XAML layout doesn't
            // expect - and the background offset offset to keep the element positioned with the background.
            // we then lerp between its existing position and its final position based on parallaxed distance
            // traveled.
            //
            _profileContentVisual = ElementCompositionPreview.GetElementVisual(ProfileContent);

            var background = _backgroundVisual.GetReference();

            _profileTranslationExpression = (-scrollPropSet.Translation.Y + background.Offset.Y + background.Size.Y / 2) / 2;

            _profileScaleExpression = EF.Lerp(
                1,
                _contentShrinkRatio,
                EF.Clamp((background.Offset.Y - background.Size.Y / 2) / (background.Size.Y - backgroundPeekSize), 0, 1));
        }
Example #5
0
        private void AlbumList_Loaded(object sender, RoutedEventArgs e)
        {
            var scrollviewer         = AlbumList.GetScrollViewer();
            var _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            var _compositor          = _scrollerPropertySet.Compositor;

            // Get references to our property sets for use with ExpressionNodes
            var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>();

            var headerHeight  = (float)(HeaderGroup.ActualHeight - (0f + HeaderGroup.Margin.Bottom));
            var toolbarHeight = (float)Toolbar.ActualHeight;


            var progressAnimation = EF.Conditional(-scrollingProperties.Translation.Y > headerHeight, EF.Conditional(-scrollingProperties.Translation.Y > headerHeight + toolbarHeight, 0, -scrollingProperties.Translation.Y - headerHeight - toolbarHeight), -toolbarHeight);

            // 0~1
            progressAnimation = (progressAnimation + toolbarHeight) / toolbarHeight;

            var toolbarVisual = ElementCompositionPreview.GetElementVisual(Toolbar);


            toolbarVisual.StartAnimation("Offset.Y", progressAnimation * 16 - 16);

            var bgVisual = ElementCompositionPreview.GetElementVisual(TitleBG);

            bgVisual.StartAnimation("Opacity", progressAnimation);
            toolbarVisual.StartAnimation("Opacity", progressAnimation);


            var moving = 80f;

            var movingAnimation = EF.Conditional(-scrollingProperties.Translation.Y > moving, 0f, moving + scrollingProperties.Translation.Y);

            var scaleAnimation = EF.Clamp(-scrollingProperties.Translation.Y / moving, 0, 1);

            scaleAnimation = EF.Lerp(1, (float)(ToolbarTitle.ActualHeight / TitleText.ActualHeight), scaleAnimation);

            var titleVisual = ElementCompositionPreview.GetElementVisual(Title);

            titleVisual.StartAnimation("Offset.Y", movingAnimation);

            var titleTextVisual = ElementCompositionPreview.GetElementVisual(TitleText);

            titleTextVisual.CenterPoint = new Vector3(0, (float)TitleText.ActualHeight / 2, 0);
            titleTextVisual.StartAnimation("Scale.X", scaleAnimation);
            titleTextVisual.StartAnimation("Scale.Y", scaleAnimation);
        }
Example #6
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);
        }
        /// <summary>
        /// Create the _backVisual and the animations that drive it.
        /// </summary>
        /// <param name="scrollProperties">A property set who has Translation.Y specified - typically the return from ElementCompositionPreview.GetScrollViewerManipulationPropertySet(...).</param>
        /// <param name="maskedBrush">This is the brush that will be set on _frontVisual</param>
        private void InitializeBehindVisual(CompositionPropertySet scrollProperties, CompositionEffectBrush maskedBrush)
        {
            //
            // Create  the _backVisual, set the brush on it, and attach it to the BackGrid.  BackGrid is an empty grid
            // that is visually behind the profile background (the waves). Therefore, setting it as the
            // child visual on the BackGrid will put it behind all the scrollViewer content.
            //
            _backVisual       = _compositor.CreateSpriteVisual();
            _backVisual.Brush = maskedBrush;
            ElementCompositionPreview.SetElementChildVisual(BackGrid, _backVisual);

            //
            // This equation controls whether or not the FrontVisual is visibile via opacity.  It uses a simple ternary operator
            // to pick between 100% and 0% opacity based on the position being after the crossover point.
            //
            _backVisual.Scale = new Vector3(_finalScaleAmount, _finalScaleAmount, 1);

            var scrollPropSet        = scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>();
            var crossoverTranslation = ExpressionValues.Constant.CreateConstantScalar("CrossoverTranslation");

            _behindOpacityExpression = EF.Conditional(-scrollPropSet.Translation.Y <= crossoverTranslation, 0, 1);

            //
            // "Terms" and explanation of the following expression:
            //
            //      (initialOffset - scrollingProperties.Translation.Y)
            //
            //              Since _backVisual is a child of the scroller, the initial position minus the scrolling offset keeps the content
            //              in its original location.
            //
            //      2 * (CrossoverTranslation + scrollingProperties.Translation.Y)
            //
            //              Since scrollingProperties.Translation.Y is negative when this expression is visibile, this term calculates the
            //              distance past the crossover point and scales it.  The scale causes the content to move faster than the scrolling.
            //              Since this term evaluates to zero at the crossover point and the term above keeps the content from moving, when
            //              the visibility swaps between frontVisual and backVisual, they are perfectly aligned.
            //

            var baseOffset = ExpressionValues.Constant.CreateConstantScalar("BaseOffset");

            _behindTranslationExpression = (baseOffset - scrollPropSet.Translation.Y) + 2 * (crossoverTranslation + scrollPropSet.Translation.Y);
        }
Example #8
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);
        }
        private Visual AddImage(CompositionSurfaceBrush imageBrush, NodeInfo nodeInfo, float defaultOpacity = 1.0f, bool applyDistanceEffects = true)
        {
            var sprite = _compositor.CreateSpriteVisual();

            var size = ((CompositionDrawingSurface)imageBrush.Surface).Size;

            size.Width  *= nodeInfo.Scale;
            size.Height *= nodeInfo.Scale;

            sprite.Size        = new Vector2((float)size.Width, (float)size.Height);
            sprite.AnchorPoint = new Vector2(0.5f, 0.5f);
            sprite.Offset      = nodeInfo.Offset;
            _worldContainer.Children.InsertAtTop(sprite);


            if (applyDistanceEffects)
            {
                //
                // Use an ExpressionAnimation to fade the image out when it goes too close or
                // too far away from the camera.
                //

                if (_opacityExpression == null)
                {
                    var visualTarget = ExpressionValues.Target.CreateVisualTarget();
                    var world        = _worldContainer.GetReference();
                    _opacityExpression = EF.Conditional(
                        defaultOpacity * (visualTarget.Offset.Z + world.Offset.Z) > -200,
                        1 - EF.Clamp(visualTarget.Offset.Z + world.Offset.Z, 0, 300) / 300,
                        EF.Clamp(visualTarget.Offset.Z + world.Offset.Z + 1300, 0, 300) / 300);
                }

                sprite.StartAnimation("Opacity", _opacityExpression);
            }
            sprite.Brush = imageBrush;

            return(sprite);
        }
        private void AlbumList_Loaded(object sender, RoutedEventArgs e)
        {
            var ani = ConnectedAnimationService.GetForCurrentView().GetAnimation(Consts.ArtistPageInAnimation);

            if (ani != null)
            {
                ani.TryStart(Title, new UIElement[] { HeaderBG, Details });
            }

            var scrollviewer = AlbumList.GetScrollViewer();

            _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            _compositor          = _scrollerPropertySet.Compositor;

            _props = _compositor.CreatePropertySet();
            _props.InsertScalar("progress", 0);
            _props.InsertScalar("clampSize", (float)Title.ActualHeight + 64);
            _props.InsertScalar("scaleFactor", 0.5f);

            // 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 and start an ExpressionAnimation to track scroll progress over the desired distance
            ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / ((float)Header.Height - clampSizeNode), 0, 1);

            _props.StartAnimation("progress", progressAnimation);

            // 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, scrollingProperties.Translation.Y, -(float)Header.Height + (float)Title.ActualHeight + 64);

            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);

            var titleVisual       = ElementCompositionPreview.GetElementVisual(Title);
            var titleshrinkVisual = ElementCompositionPreview.GetElementVisual(TitleShrink);
            var fixAnimation      = EF.Conditional(progressNode < 1, -scrollingProperties.Translation.Y, (float)Header.Height - ((float)Title.ActualHeight + 64));

            titleVisual.StartAnimation("Offset.Y", fixAnimation);
            titleshrinkVisual.StartAnimation("Offset.Y", fixAnimation);
            var detailsVisual    = ElementCompositionPreview.GetElementVisual(Details);
            var opacityAnimation = EF.Clamp(1 - (progressNode * 8), 0, 1);

            detailsVisual.StartAnimation("Opacity", opacityAnimation);

            var headerbgVisual         = ElementCompositionPreview.GetElementVisual(HeaderBG);
            var headerbgOverlayVisual  = ElementCompositionPreview.GetElementVisual(HeaderBGOverlay);
            var bgBlurVisual           = ElementCompositionPreview.GetElementVisual(BGBlur);
            var bgOpacityAnimation     = EF.Clamp(1 - progressNode, 0, 1);
            var bgblurOpacityAnimation = EF.Clamp(progressNode, 0, 1);

            titleshrinkVisual.StartAnimation("Opacity", bgblurOpacityAnimation);
            titleVisual.StartAnimation("Opacity", bgOpacityAnimation);
            headerbgVisual.StartAnimation("Opacity", bgOpacityAnimation);
            headerbgOverlayVisual.StartAnimation("Opacity", bgOpacityAnimation);
            bgBlurVisual.StartAnimation("Opacity", bgblurOpacityAnimation);
        }
        private void SamplePage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // Get the PropertySet that contains the scroll values from MyScrollViewer
            _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MyScrollviewer);
            _compositor          = _scrollerPropertySet.Compositor;
            Model = new LocalDataSource();

            gridView.ItemsSource = Model.AggregateDataSources(new ObservableCollection <Thumbnail>[] { Model.Landscapes, Model.Nature, Model.Abstract });

            // 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);
        }
Example #12
0
        private void SongsList_Loaded(object sender, RoutedEventArgs e)
        {
            var scrollviewer         = Root;
            var _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            var _compositor          = _scrollerPropertySet.Compositor;

            // Get references to our property sets for use with ExpressionNodes
            var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>();

            var headerHeight = (float)(HeaderGroup.ActualHeight);
            var finalHeight  = (float)TitleBG.ActualHeight;


            var progressAnimation = EF.Conditional(-scrollingProperties.Translation.Y > headerHeight, EF.Conditional(-scrollingProperties.Translation.Y > headerHeight + finalHeight, 0, -scrollingProperties.Translation.Y - headerHeight - finalHeight), -finalHeight);

            // 0~1
            progressAnimation = (progressAnimation + finalHeight) / finalHeight;

            var toolbarVisual = ElementCompositionPreview.GetElementVisual(Toolbar);


            toolbarVisual.StartAnimation("Offset.Y", progressAnimation * 16 - 16);

            var offset = toolbarVisual.GetReference().GetScalarProperty("Offset.Y");

            toolbarVisual.StartAnimation("Opacity", progressAnimation);

            var moving = 80f;

            var movingAnimation = EF.Conditional(-scrollingProperties.Translation.Y > moving, 0f, moving + scrollingProperties.Translation.Y);

            var horiMovingAni = EF.Clamp(-scrollingProperties.Translation.Y / moving, 0, 1);

            horiMovingAni = EF.Lerp(0, (float)(80f - ImageGrid.Height), horiMovingAni);

            var scaleAnimation     = EF.Clamp(-scrollingProperties.Translation.Y / moving, 0, 1);
            var textScaleAnimation = EF.Lerp(1, (float)(ToolbarTitle.ActualHeight / TitleText.ActualHeight), scaleAnimation);

            var titleVisual = ElementCompositionPreview.GetElementVisual(Title);

            titleVisual.StartAnimation("Offset.Y", movingAnimation);
            titleVisual.StartAnimation("Offset.X", horiMovingAni);


            var titleTextVisual = ElementCompositionPreview.GetElementVisual(TitleText);

            titleTextVisual.CenterPoint = new Vector3(32f, (float)TitleText.ActualHeight / 2, 0);
            titleTextVisual.StartAnimation("Scale.X", textScaleAnimation);
            titleTextVisual.StartAnimation("Scale.Y", textScaleAnimation);

            var bgVisual = ElementCompositionPreview.GetElementVisual(TitleBG);

            bgVisual.StartAnimation("Opacity", scaleAnimation);

            var marginTop = (float)((TitleBG.ActualHeight - 80f) / 2);

            var imgMovingAnimation = EF.Conditional(-scrollingProperties.Translation.Y > (moving - marginTop), marginTop, moving + scrollingProperties.Translation.Y);

            var imageScaleAnimation = EF.Lerp(1, (float)(80f / ImageGrid.Height), scaleAnimation);

            var imageVisual = ElementCompositionPreview.GetElementVisual(ImageGrid);

            imageVisual.CenterPoint = new Vector3(32f, 0, 0);
            imageVisual.StartAnimation("Scale.X", imageScaleAnimation);
            imageVisual.StartAnimation("Scale.Y", imageScaleAnimation);

            imageVisual.StartAnimation("Offset.Y", imgMovingAnimation);
        }
Example #13
0
        private void ActivateGravityForce()
        {
            //
            // Setup the gravity+bounce inertia modifier.
            //

            var target = ExpressionValues.Target.CreateInteractionTrackerTarget();
            var posY   = target.Position.Y;
            var velY   = target.PositionVelocityInPixelsPerSecond.Y;

            //
            // Gravity Force
            //

            // Adding a factor of 100 since -9.8 pixels / second ^2 is not very fast.
            var gravity = -9.8f * 100;

            //
            // Floor Force
            //
            // This is the force that resists gravity and causes the bouncing. It's defined as:
            // 1. Zero if above the floor,
            // 2. Equal and opposite to gravity if "on" the floor (1 pixel above floor or below),
            // 3. The effects of 2., plus a reflective force if the direction of motion is still downward and the tracker is below the floor.
            //        This force is at its strongest (-1.8 * 100 * V) if the tracker is 5 or more
            //        pixels below floor, and weakest (-1.0 * 100 * V) if the tracker is "at" the
            //        floor.
            //

            // The amount the tracker is below the floor, capped to at most 5 below.

            var belowFloor = EF.Clamp(0, 0 - posY, 5);

            // The time slice our force engine uses.
            float dt = .01f;

            //
            // Defining bounce constants.
            // -2 would cause perfectly inellastic reflection, bouncing as high as it fell from.
            // -1 would cause perfectly ellastic reflection, freezing motion.
            // We want some bounce, but we also want the bouncing to decay, so choose
            // bounce factors between -1 and -2.
            //
            // Also, divide by the time slice width to make this reflective force apply entirely
            // all at once.
            //
            var weakestBounce   = -1.1f / dt;
            var strongestBounce = -1.8f / dt;

            var floorForceExpression = EF.Conditional(posY < 1,
                                                      -gravity,
                                                      0) +
                                       EF.Conditional(EF.And(velY < 0f, posY < 0f),
                                                      EF.Lerp(weakestBounce, strongestBounce, belowFloor / 5) * velY,
                                                      0);

            //
            // Apply the forces to the modifier
            //
            var modifier = InteractionTrackerInertiaMotion.Create(_compositor);

            modifier.SetCondition((BooleanNode)true);
            modifier.SetMotion(gravity + floorForceExpression);
            _tracker.ConfigurePositionYInertiaModifiers(new InteractionTrackerInertiaModifier[] { modifier });
        }
Example #14
0
        private void SongsList_Loaded(object sender, RoutedEventArgs e)
        {
            var scrollviewer         = Root;
            var _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            var _compositor          = _scrollerPropertySet.Compositor;

            // Get references to our property sets for use with ExpressionNodes
            var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>();

            var headerHeight = (float)(HeaderGroup.ActualHeight);
            var finalHeight  = (float)TitleBG.ActualHeight;


            var progressAnimation = EF.Conditional(-scrollingProperties.Translation.Y > headerHeight, EF.Conditional(-scrollingProperties.Translation.Y > headerHeight + finalHeight, 0, -scrollingProperties.Translation.Y - headerHeight - finalHeight), -finalHeight);

            // 0~1
            progressAnimation = (progressAnimation + finalHeight) / finalHeight;

            var toolbarVisual = ElementCompositionPreview.GetElementVisual(Toolbar);


            toolbarVisual.StartAnimation("Offset.Y", progressAnimation * 16 - 16);

            var offset = toolbarVisual.GetReference().GetScalarProperty("Offset.Y");

            toolbarVisual.StartAnimation("Opacity", progressAnimation);

            var moving = 80f;

            var movingAnimation = EF.Conditional(-scrollingProperties.Translation.Y > moving, 0f, moving + scrollingProperties.Translation.Y);

            var horiMovingAni = EF.Clamp(-scrollingProperties.Translation.Y / moving, 0, 1);

            horiMovingAni = EF.Lerp(0, (float)(80f - ImageGrid.Height), horiMovingAni);

            var scaleAnimation     = EF.Clamp(-scrollingProperties.Translation.Y / moving, 0, 1);
            var textScaleAnimation = EF.Lerp(1, (float)(ToolbarTitle.ActualHeight / TitleText.ActualHeight), scaleAnimation);

            var titleVisual = ElementCompositionPreview.GetElementVisual(Title);

            titleVisual.StartAnimation("Offset.Y", movingAnimation);
            titleVisual.StartAnimation("Offset.X", horiMovingAni);


            var titleTextVisual = ElementCompositionPreview.GetElementVisual(TitleText);

            titleTextVisual.CenterPoint = new Vector3(32f, (float)TitleText.ActualHeight / 2, 0);
            titleTextVisual.StartAnimation("Scale.X", textScaleAnimation);
            titleTextVisual.StartAnimation("Scale.Y", textScaleAnimation);

            var bgVisual = ElementCompositionPreview.GetElementVisual(TitleBG);

            bgVisual.StartAnimation("Opacity", scaleAnimation);

            var marginTop = (float)((TitleBG.ActualHeight - 80f) / 2);

            var imgMovingAnimation = EF.Conditional(-scrollingProperties.Translation.Y > (moving - marginTop), marginTop, moving + scrollingProperties.Translation.Y);

            var imageScaleAnimation = EF.Lerp(1, (float)(80f / ImageGrid.Height), scaleAnimation);

            var imageVisual = ElementCompositionPreview.GetElementVisual(ImageGrid);

            imageVisual.CenterPoint = new Vector3(32f, 0, 0);
            imageVisual.StartAnimation("Scale.X", imageScaleAnimation);
            imageVisual.StartAnimation("Scale.Y", imageScaleAnimation);

            imageVisual.StartAnimation("Offset.Y", imgMovingAnimation);

            Task.Run(async() =>
            {
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
                {
                    var ani = ConnectedAnimationService.GetForCurrentView().GetAnimation(Consts.ArtistPageInAnimation + "_1");
                    if (ani != null)
                    {
                        ani.TryStart(TitleText, new UIElement[] { Details });
                    }
                    ani = ConnectedAnimationService.GetForCurrentView().GetAnimation(Consts.ArtistPageInAnimation + "_2");
                    if (ani != null)
                    {
                        ani.TryStart(Image);
                    }
                });
            });
        }