private void Image_ImageOpened(object sender, RoutedEventArgs e)
        {
            TitleGridMargin.X   = Image.ActualWidth + 48;
            Col1.Width          = new GridLength(Image.ActualWidth);
            ToolbarTitle.Margin = new Thickness(Image.ActualWidth * 80 / 200 + 32, 8, 0, 8);

            var scrollviewer         = SongList.GetScrollViewer();
            var _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            var _compositor          = _scrollerPropertySet.Compositor;
            var moving = 80f;

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

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

            horiMovingAni = EF.Lerp(0, (float)((80f / ImageGrid.ActualHeight * ImageGrid.ActualWidth) - ImageGrid.ActualWidth), 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.StopAnimation("offset.X");
            titleVisual.StartAnimation("Offset.X", horiMovingAni);
        }
Example #2
0
        private void ConfigureAnimations(Visual photoVisual, Visual infoVisual, SpriteVisual shadowVisual)
        {
            // Create a drop shadow to be animated by the manipulation
            var shadow = _compositor.CreateDropShadow();

            shadowVisual.Shadow = shadow;
            _props.InsertScalar("progress", 0);

            // Create an animation that tracks the progress of the manipulation and stores it in a the PropertySet _props
            var trackerNode = _tracker.GetReference();

            _props.StartAnimation("progress", trackerNode.Position.Y / trackerNode.MaxPosition.Y);

            // Create an animation that scales up the infoVisual based on the manipulation progress
            var propSetProgress = _props.GetReference().GetScalarProperty("progress");

            infoVisual.StartAnimation("Scale", EF.Vector3(1, 1, 1) * EF.Lerp(1, 1.2f, propSetProgress));

            // Create an animation that changes the offset of the photoVisual and shadowVisual based on the manipulation progress
            var photoOffsetExp = -120f * _props.GetReference().GetScalarProperty("Progress");

            photoVisual.StartAnimation("offset.y", photoOffsetExp);
            shadowVisual.StartAnimation("offset.y", photoOffsetExp);

            // Create an animation that fades in the info visual based on the manipulation progress
            infoVisual.StartAnimation("opacity", EF.Lerp(0, 1, _props.GetReference().GetScalarProperty("Progress")));
            shadow.StartAnimation("blurradius", EF.Lerp(1, 50, _props.GetReference().GetScalarProperty("Progress")));
        }
Example #3
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 #4
0
        private void Header_Loaded(object sender, RoutedEventArgs e)
        {
            var scrollviewer = MainScroller;

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

            _props = _compositor.CreatePropertySet();
            _props.InsertScalar("progress", 0);

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

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

            _props.StartAnimation("progress", progressAnimation);

            var headerbgVisual         = ElementCompositionPreview.GetElementVisual(HeaderBG);
            var bgblurOpacityAnimation = EF.Clamp(progressNode, 0, 1);

            headerbgVisual.StartAnimation("Opacity", bgblurOpacityAnimation);
        }
Example #5
0
        private void ConfigureRestingPoints()
        {
            // Setup a possible inertia endpoint (snap point) for the InteractionTracker's minimum position
            var endpoint1 = InteractionTrackerInertiaRestingValue.Create(_compositor);

            // Use this endpoint when the natural resting position of the interaction is less than the halfway point
            var trackerTarget = ExpressionValues.Target.CreateInteractionTrackerTarget();

            endpoint1.SetCondition(EF.Abs(trackerTarget.NaturalRestingPosition.X - (itemsRendered.SelectedIndex * _itemWidth)) < p * _itemWidth);
            endpoint1.SetRestingValue(trackerTarget.MinPosition.X + _itemWidth);

            // Setup a possible inertia endpoint (snap point) for the InteractionTracker's maximum position
            var endpoint2 = InteractionTrackerInertiaRestingValue.Create(_compositor);

            endpoint2.SetCondition(trackerTarget.NaturalRestingPosition.X - (itemsRendered.SelectedIndex * _itemWidth) >= p * _itemWidth);
            endpoint2.SetRestingValue(trackerTarget.MaxPosition.X);

            // Setup a possible inertia endpoint (snap point) for the InteractionTracker's maximum position
            var endpoint3 = InteractionTrackerInertiaRestingValue.Create(_compositor);

            endpoint3.SetCondition(trackerTarget.NaturalRestingPosition.X - (itemsRendered.SelectedIndex * _itemWidth) <= -(p * _itemWidth));
            endpoint3.SetRestingValue(trackerTarget.MinPosition.X);

            _tracker.ConfigurePositionXInertiaModifiers(new InteractionTrackerInertiaModifier[] { endpoint1, endpoint2, endpoint3 });
        }
        public override async Task <CompositionDrawingSurface> LoadResources()
        {
            var graphicsEffect = new ArithmeticCompositeEffect
            {
                Name          = "Arithmetic",
                Source1       = new CompositionEffectSourceParameter("ImageSource"),
                Source1Amount = .25f,
                Source2       = new Transform2DEffect
                {
                    Name   = "LightMapTransform",
                    Source = new CompositionEffectSourceParameter("LightMap")
                },
                Source2Amount  = 0,
                MultiplyAmount = 1
            };

            _effectFactory = _compositor.CreateEffectFactory(graphicsEffect, new[] { "LightMapTransform.TransformMatrix" });

            // Create the image
            _lightMap = await ImageLoader.Instance.LoadFromUriAsync(new Uri("ms-appx:///Assets/NormalMapsAndMasks/conemap.jpg"));

            // Create the animations
            float sweep      = (float)Math.PI / 10f;
            float fullCircle = (float)Math.PI * -2f;

            _enterAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _enterAnimation.InsertKeyFrame(0.1f, fullCircle);
            _enterAnimation.InsertKeyFrame(0.4f, fullCircle + sweep);
            _enterAnimation.InsertKeyFrame(0.8f, fullCircle - sweep);
            _enterAnimation.InsertKeyFrame(1.0f, fullCircle);
            _enterAnimation.Duration          = TimeSpan.FromMilliseconds(4500);
            _enterAnimation.IterationBehavior = AnimationIterationBehavior.Count;
            _enterAnimation.IterationCount    = 1;

            _exitAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _exitAnimation.InsertKeyFrame(1.0f, 0f);
            _exitAnimation.Duration          = TimeSpan.FromMilliseconds(1000);
            _exitAnimation.IterationBehavior = AnimationIterationBehavior.Count;
            _exitAnimation.IterationCount    = 1;

            var propsNode = ExpressionValues.Reference.CreatePropertySetReference("props");
            var propsCenterPointOffset = propsNode.GetVector2Property("CenterPointOffset");
            var propsRotation          = propsNode.GetScalarProperty("Rotation");
            var propsScale             = propsNode.GetScalarProperty("Scale");

            _transformExpressionNode = EF.CreateTranslation(-propsCenterPointOffset) *
                                       EF.Matrix3x2(EF.Cos(propsRotation) * propsScale,
                                                    EF.Sin(propsRotation),
                                                    -EF.Sin(propsRotation),
                                                    EF.Cos(propsRotation) * propsScale,
                                                    0,
                                                    0) *
                                       EF.CreateTranslation(propsCenterPointOffset + propsNode.GetVector2Property("Translate"));

            return(null);
        }
Example #7
0
        private void InitializeAnimations()
        {
            _props.InsertScalar("position", 0);
            _props.InsertScalar("progress", 0);

            var trackerNode = _tracker.GetReference();

            _props.StartAnimation("position", -trackerNode.Position.X);
            _props.StartAnimation("progress", EF.Abs(trackerNode.Position.X) / trackerNode.MaxPosition.X);

            ConfigureTemplateAnimations();
        }
        public override async Task <CompositionDrawingSurface> LoadResources()
        {
            var graphicsEffect = new ArithmeticCompositeEffect
            {
                Name          = "Arithmetic",
                Source1       = new CompositionEffectSourceParameter("ImageSource"),
                Source1Amount = .1f,
                Source2       = new Transform2DEffect
                {
                    Name   = "LightMapTransform",
                    Source = new CompositionEffectSourceParameter("LightMap")
                },
                Source2Amount  = 0,
                MultiplyAmount = 1
            };

            _effectFactory = _compositor.CreateEffectFactory(graphicsEffect, new[] { "LightMapTransform.TransformMatrix" });

            // Create the image
            _lightMap = await ImageLoader.Instance.LoadFromUriAsync(new Uri("ms-appx:///Assets/NormalMapsAndMasks/pointmap.jpg"));

            // Create the animations
            CubicBezierEasingFunction easeIn = _compositor.CreateCubicBezierEasingFunction(new Vector2(0.0f, 0.51f), new Vector2(1.0f, 0.51f));

            _enterAnimation = _compositor.CreateScalarKeyFrameAnimation();
            _enterAnimation.InsertKeyFrame(0.33f, 1.25f, easeIn);
            _enterAnimation.InsertKeyFrame(0.66f, 0.75f, easeIn);
            _enterAnimation.InsertKeyFrame(1.0f, 1.0f, easeIn);
            _enterAnimation.Duration          = TimeSpan.FromMilliseconds(5000);
            _enterAnimation.IterationBehavior = AnimationIterationBehavior.Forever;

            _exitAnimation = _compositor.CreateVector2KeyFrameAnimation();
            _exitAnimation.InsertKeyFrame(1.0f, new Vector2(0, 0));
            _exitAnimation.Duration          = TimeSpan.FromMilliseconds(750);
            _exitAnimation.IterationBehavior = AnimationIterationBehavior.Count;
            _exitAnimation.IterationCount    = 1;

            var propsNode = ExpressionValues.Reference.CreatePropertySetReference("props");
            var propsCenterPointOffset = propsNode.GetVector2Property("CenterPointOffset");
            var propsTranslate         = propsNode.GetVector2Property("Translate");
            var propsScale             = propsNode.GetScalarProperty("Scale");

            _transformExpressionNode = EF.Matrix3x2(propsScale,
                                                    0,
                                                    0,
                                                    propsScale,
                                                    propsCenterPointOffset.X * (1 - propsScale) + (propsTranslate.X * propsCenterPointOffset.X * 2),
                                                    propsCenterPointOffset.Y * (1 - propsScale) + (propsTranslate.Y * propsCenterPointOffset.Y * 2));

            return(null);
        }
Example #9
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 #12
0
        private void ConfigureInteractionTracker()
        {
            _tracker             = InteractionTracker.Create(_compositor);
            _tracker.MaxPosition = new Vector3(0, _backgroundImageVisual.Size.Y * 0.5f, 0);
            _tracker.MinPosition = new Vector3();

            _interactionSource = VisualInteractionSource.Create(_backgroundVisual);
            _interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;
            _tracker.InteractionSources.Add(_interactionSource);

            var trackerNode = _tracker.GetReference();
            var progressExp = EF.Clamp(trackerNode.Position.Y / trackerNode.MaxPosition.Y, 0, 1);

            _propertySet.StartAnimation("progress", progressExp);
        }
Example #13
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 #14
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 #15
0
        private void Header_Loaded(object sender, RoutedEventArgs e)
        {
            var scrollviewer = MainScroller;

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

            _props = _compositor.CreatePropertySet();
            _props.InsertScalar("progress", 0);
            _props.InsertScalar("clampSize", (float)HeaderBG.Height);
            _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 and start an ExpressionAnimation to track scroll progress over the desired distance
            var progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);

            _props.StartAnimation("progress", progressAnimation);

            var headerbgVisual         = ElementCompositionPreview.GetElementVisual(HeaderBG);
            var bgblurOpacityAnimation = EF.Clamp(progressNode, 0, 1);

            headerbgVisual.StartAnimation("Opacity", bgblurOpacityAnimation);

            var headerVisual   = ElementCompositionPreview.GetElementVisual(HeroTitle);
            var scaleAnimation = EF.Lerp(1, scaleFactorNode, progressNode);

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

            var offsetAnimation  = EF.Lerp(160f, 32f, progressNode);
            var opacityAnimation = EF.Lerp(1f, 0.6f, progressNode);

            var containerVisual = ElementCompositionPreview.GetElementVisual(TextContainer);

            containerVisual.StartAnimation("Offset.Y", offsetAnimation);
            containerVisual.StartAnimation("Opacity", opacityAnimation);
        }
        private void Image_ImageOpened(object sender, RoutedEventArgs e)
        {
            TitleGridMargin.X   = Image.ActualWidth + 48;
            Col1.Width          = new GridLength(Image.ActualWidth);
            ToolbarTitle.Margin = new Thickness(Image.ActualWidth * 80 / 200 + 32, 8, 0, 8);

            var scrollviewer         = SongList.GetScrollViewer();
            var _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollviewer);
            var _compositor          = _scrollerPropertySet.Compositor;
            var moving = 80f;

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

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

            horiMovingAni = EF.Lerp(0, (float)((80f / ImageGrid.ActualHeight * ImageGrid.ActualWidth) - ImageGrid.ActualWidth), 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.StopAnimation("offset.X");
            titleVisual.StartAnimation("Offset.X", horiMovingAni);

            Task.Run(async() =>
            {
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
                {
                    var ani = ConnectedAnimationService.GetForCurrentView().GetAnimation(Consts.AlbumItemConnectedAnimation + "_1");
                    if (ani != null)
                    {
                        ani.TryStart(Title, new UIElement[] { Details });
                    }
                    ani = ConnectedAnimationService.GetForCurrentView().GetAnimation(Consts.AlbumItemConnectedAnimation + "_2");
                    if (ani != null)
                    {
                        ani.TryStart(Image);
                    }
                });
            });
        }
        private void ConfigureInteractionTracker()
        {
            //
            // We're creating two interaction trackers, one nested in the other.  This allows us the user to use
            // pinch/stretch to affect z-position, and not have it change the x-position.  The two work independently.
            //

            _interactionSource1 = VisualInteractionSource.Create(_rootContainer);
            _interactionSource1.ScaleSourceMode = InteractionSourceMode.EnabledWithInertia;

            _scaleTracker          = InteractionTracker.CreateWithOwner(_compositor, this);
            _scaleTracker.MinScale = 0.6f;
            _scaleTracker.MaxScale = 5.0f;
            _scaleTracker.ScaleInertiaDecayRate = 0.96f;

            _scaleTracker.InteractionSources.Add(_interactionSource1);

            _interactionSource2 = VisualInteractionSource.Create(_rootContainer2);
            _interactionSource2.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia;

            _positionTracker             = InteractionTracker.CreateWithOwner(_compositor, this);
            _positionTracker.MaxPosition = new Vector3((float)Root.ActualWidth * 1.5f, 0, 0);
            _positionTracker.MinPosition = _positionTracker.MaxPosition * -1;

            _positionTracker.InteractionSources.Add(_interactionSource2);

            //
            // Here's the trick: we take the scale output from the outer (scale) Tracker, and convert
            // it into a value that represents Z.  Then we bind it to the world container's Z position.
            //

            var scaleTracker    = _scaleTracker.GetReference();
            var scaleExpression = EF.Lerp(0, 1000, (1 - scaleTracker.Scale) / (1 - scaleTracker.MaxScale));

            _worldContainer.StartAnimation("Offset.Z", scaleExpression);

            //
            // Bind the output of the inner (xy position) tracker to the world container's XY position.
            //

            _worldContainer.StartAnimation("Offset.XY", -_positionTracker.GetReference().Position.XY);
        }
Example #18
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);
        }
        /// <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);
        }
        private void ConfigureInteractionTracker()
        {
            _tracker             = InteractionTracker.Create(_compositor);
            _tracker.MaxPosition = new Vector3(0, _backgroundImageVisual.Size.Y * 0.5f, 0);
            _tracker.MinPosition = new Vector3();

            _interactionSource = VisualInteractionSource.Create(_backgroundVisual);
            _interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;

#if SDKVERSION_17763
            if (MainPage.RuntimeCapabilities.IsSdkVersionRuntimeSupported(RuntimeSupportedSDKs.SDKVERSION._17763))
            {
                _interactionSource.ManipulationRedirectionMode = VisualInteractionSourceRedirectionMode.CapableTouchpadAndPointerWheel;
            }
#endif
            _tracker.InteractionSources.Add(_interactionSource);

            var trackerNode = _tracker.GetReference();
            var progressExp = EF.Clamp(trackerNode.Position.Y / trackerNode.MaxPosition.Y, 0, 1);
            _propertySet.StartAnimation("progress", progressExp);
        }
        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);
        }
Example #22
0
        private void SetupLayerAnimations(Layer layer, float layerZ)
        {
            var layerVisual         = layer.LayerVisual;
            var itemContainerVisual = layer.ItemContainerVisual;

            var compositor   = layerVisual.Compositor;
            var currentZNode = _animationPropertySet.GetReference().GetScalarProperty("currentZ");

            // Opacity and saturation go to zero with as |deltaZ| -> 1
            var opacityAndSaturationExpression = EF.Max(0, 1 - EF.Abs(currentZNode - layerZ));

            layerVisual.StartAnimation(nameof(layerVisual.Opacity), opacityAndSaturationExpression);
            layerVisual.Effect.Properties.StartAnimation("saturation.Saturation", opacityAndSaturationExpression);

            // Scale changes with deltaZ (perspective-like)
            var scaleExpression = EF.Vector3(EF.Pow(1.5f, currentZNode - layerZ), EF.Pow(1.5f, currentZNode - layerZ), 0);

            itemContainerVisual.StartAnimation(nameof(layerVisual.Scale), scaleExpression);

            // Blur increases with |deltaZ|
            var blurAmountExpression = EF.Abs(currentZNode - layerZ) * 10;

            layerVisual.Effect.Properties.StartAnimation("blur.BlurAmount", blurAmountExpression);
        }
        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 ConfigureTransitionAnimations()
        {
            //
            // Create a common expression that blends between the start and end value,
            // based on the tracker's progres (0 to 1).
            //

            var startNode       = ExpressionValues.Constant.CreateConstantScalar("start");
            var endNode         = ExpressionValues.Constant.CreateConstantScalar("end");
            var progress        = _propertySet.GetReference().GetScalarProperty("progress");
            var blendExpression = EF.Lerp(startNode, endNode, progress);

            //
            // Apply the expression to the background image's blur amount.
            //

            blendExpression.SetScalarParameter("start", _visualState1.BackgroundBlurAmount);
            blendExpression.SetScalarParameter("end", _visualState2.BackgroundBlurAmount);

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

            //
            // Apply the expression to the background image's blur amount. Since the expression
            // structure isn't changing, we can simply update the parameter values (i.e. placeholders)
            // before starting the animation.
            //

            blendExpression.SetVector3Parameter("start", _visualState1.BackgroundScale);
            blendExpression.SetVector3Parameter("end", _visualState2.BackgroundScale);

            _backgroundImageVisual.StartAnimation("scale", blendExpression);


            //
            // Apply the expression to the background image overlay's opacity, to dim the image.
            //

            blendExpression.SetScalarParameter("start", 0.0f);
            blendExpression.SetScalarParameter("end", 0.4f);

            _backgroundVisualDimmer.StartAnimation("opacity", blendExpression);


            //
            // Set up the Calendar icon to move up/down, using the common expression.
            //

            blendExpression.SetVector3Parameter("start", _visualState1.CalendarIconOffset);
            blendExpression.SetVector3Parameter("end", _visualState2.CalendarIconOffset);

            _calendarIconVisual.StartAnimation("offset", blendExpression);


            //
            // Set up the Calendar icon to also scale up/down a bit, using the common expression.
            //

            blendExpression.SetVector3Parameter("start", _visualState1.CalendarIconScale);
            blendExpression.SetVector3Parameter("end", _visualState2.CalendarIconScale);

            _calendarIconVisual.StartAnimation("scale", blendExpression);


            //
            // Blend the ToDo layer's starting -> ending opacity.  Instead of linear, we'll add a slightly more dramatic effect.
            //

            var weightNode = ExpressionValues.Constant.CreateConstantScalar("weight");

            blendExpression = EF.Lerp(startNode, endNode, (EF.Pow(weightNode, progress) - 1.0f) / (weightNode - 1.0f));
            blendExpression.SetScalarParameter("start", _visualState1.ToDoLayerOpacity);
            blendExpression.SetScalarParameter("end", _visualState2.ToDoLayerOpacity);
            blendExpression.SetScalarParameter("weight", 30);

            _todoLayerVisual.StartAnimation("opacity", blendExpression);


            //
            // Set up ToDo layer to scale up/down with the same warped blend.
            //

            blendExpression.SetVector3Parameter("start", _visualState1.ToDoLayerScale);
            blendExpression.SetVector3Parameter("end", _visualState2.ToDoLayerScale);

            _todoLayerVisual.StartAnimation("scale", blendExpression);


            //
            // Set up weather layer's opacity to increase/decrease.  We'll use the same warped blend, but change the weight.
            //

            blendExpression.SetScalarParameter("start", _visualState1.WeatherLayerOpacity);
            blendExpression.SetScalarParameter("end", _visualState2.WeatherLayerOpacity);
            blendExpression.SetScalarParameter("weight", 1.0f / 30.0f);

            _weatherLayerVisual.StartAnimation("opacity", blendExpression);


            //
            // Set up weather layer to scale up/down the same way.
            //

            blendExpression.SetVector3Parameter("start", _visualState1.WeatherLayerScale);
            blendExpression.SetVector3Parameter("end", _visualState2.WeatherLayerScale);

            _weatherLayerVisual.StartAnimation("scale", blendExpression);
        }
        private void ConfigureInteractionTracker()
        {
            _interactionSource = VisualInteractionSource.Create(_rootContainer);
            _interactionSource.ScaleSourceMode     = InteractionSourceMode.EnabledWithInertia;
            _interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia;

            _tracker          = InteractionTracker.CreateWithOwner(_compositor, this);
            _tracker.MinScale = 0.6f;
            _tracker.MaxScale = 5.0f;

            _tracker.MaxPosition = new Vector3((float)Root.ActualWidth * 1.5f, 0, 0);
            _tracker.MinPosition = _tracker.MaxPosition * -1;

            _tracker.ScaleInertiaDecayRate = 0.96f;

            _tracker.InteractionSources.Add(_interactionSource);

            var tracker = _tracker.GetReference();

            //
            // Here's the trick: we take the scale output from the tracker, and convert it into a
            // value that represents Z.  Then we bind it to the world container's Z position.
            //

            var scaleExpression = EF.Lerp(0, 1000, (1 - tracker.Scale) / (1 - tracker.MaxScale));

            _worldContainer.StartAnimation("Offset.Z", scaleExpression);

            //
            // Bind the output of the tracker to the world container's XY position.
            //

            _worldContainer.StartAnimation("Offset.XY", -tracker.Position.XY);


            //
            // Scaling usually affects position.  This depends on the center point of the scale.
            // But for our UI, we want don't scale to adjust the position (since we're using scale
            // to change Offset.Z).  So to prevent scale from affecting position, we must always use
            // the top-left corner of the WorldContainer as the center point (note: we could also
            // use the tracker's negated position, since that's where WorldContainer is getting its
            // offset).
            //
            // Create input modifiers to override the center point value.
            //

            var centerpointXModifier = CompositionConditionalValue.Create(_compositor);
            var centerpointYModifier = CompositionConditionalValue.Create(_compositor);

            centerpointXModifier.Condition = _compositor.CreateExpressionAnimation("true");
            centerpointXModifier.Value     = _compositor.CreateExpressionAnimation("world.Offset.X");
            centerpointXModifier.Value.SetReferenceParameter("world", _worldContainer);

            _interactionSource.ConfigureCenterPointXModifiers(new[] { centerpointXModifier });
            _tracker.ConfigureCenterPointXInertiaModifiers(new[] { centerpointXModifier });


            centerpointYModifier.Condition = _compositor.CreateExpressionAnimation("true");
            centerpointYModifier.Value     = _compositor.CreateExpressionAnimation("world.Offset.Y");
            centerpointYModifier.Value.SetReferenceParameter("world", _worldContainer);

            _interactionSource.ConfigureCenterPointYModifiers(new[] { centerpointYModifier });
            _tracker.ConfigureCenterPointYInertiaModifiers(new[] { centerpointYModifier });
        }
        private void ConfigureAmbientAnimations()
        {
            Vector3 positionMargin = new Vector3(700, 0, 0);

            Vector3KeyFrameAnimation positionAnimation;
            ScalarKeyFrameAnimation  scaleForZAnimation;
            double timeScale = 0.6;

            _ambientAnimations = new List <Tuple <AmbientAnimationTarget, CompositionAnimation> >();

            var tracker = _tracker.GetReference();

            //
            // Move by an amount 1/2 the distance to the near X edge.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            var vec3StartingValue = ExpressionValues.StartingValue.CreateVector3StartingValue();
            var minPosExp         = positionMargin + (tracker.MinPosition + vec3StartingValue) * 0.5f;

            positionAnimation.InsertExpressionKeyFrame(1, minPosExp);

            positionAnimation.Duration = TimeSpan.FromSeconds(15 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));

            //
            // Move by an amount 1/2 the distance to the far X edge.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            var maxPosExp = -positionMargin + (tracker.MaxPosition - vec3StartingValue) * 0.5f;

            positionAnimation.InsertExpressionKeyFrame(1f, maxPosExp);
            positionAnimation.Duration = TimeSpan.FromSeconds(15 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));


            //
            // Move all the way to the near X edge.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            positionAnimation.InsertKeyFrame(1, _tracker.MinPosition + positionMargin * 2);
            positionAnimation.Duration = TimeSpan.FromSeconds(15 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));



            //
            // Move all the way to the far X edge.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            positionAnimation.InsertKeyFrame(1, _tracker.MaxPosition - positionMargin);
            positionAnimation.Duration = TimeSpan.FromSeconds(20 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));


            //
            // Move to 85% of the far X edge.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            positionAnimation.InsertExpressionKeyFrame(1, -positionMargin + tracker.MaxPosition * 0.85f);

            positionAnimation.Duration = TimeSpan.FromSeconds(15 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));


            //
            // Move to mid-X.
            //

            positionAnimation = _compositor.CreateVector3KeyFrameAnimation();

            positionAnimation.InsertKeyFrame(1, _tracker.MinPosition + (_tracker.MaxPosition - _tracker.MinPosition) * 0.5f);
            positionAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.PositionKeyFrame,
                                       positionAnimation));



            //
            // Move to min-Z.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            scaleForZAnimation.InsertKeyFrame(1, _tracker.MinScale);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(18 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));

            //
            // Move to 30% of min-Z.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            scaleForZAnimation.InsertKeyFrame(1, _tracker.MinScale * 1.3f);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));


            //
            // Move to mid-Z.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            scaleForZAnimation.InsertKeyFrame(1, (_tracker.MaxScale - _tracker.MinScale) / 2.0f);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(11 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));


            //
            // Move to 70% of max-Z.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            scaleForZAnimation.InsertKeyFrame(1, _tracker.MaxScale * 0.3f);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));



            //
            // Move to max-Z.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            scaleForZAnimation.InsertKeyFrame(1, _tracker.MaxScale);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));


            //
            // Move forward Z by 50%.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            var scalarStartingValue = ExpressionValues.StartingValue.CreateScalarStartingValue();
            var scaleMinExp         = EF.Min(tracker.MaxScale, scalarStartingValue * 1.5f);

            scaleForZAnimation.InsertExpressionKeyFrame(1, scaleMinExp);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));

            //
            // Move back Z by 50%.
            //

            scaleForZAnimation = _compositor.CreateScalarKeyFrameAnimation();

            var scaleMaxExp = EF.Max(tracker.MinScale, scalarStartingValue * 0.5f);

            scaleForZAnimation.InsertExpressionKeyFrame(1, scaleMaxExp);
            scaleForZAnimation.Duration = TimeSpan.FromSeconds(10 * timeScale);

            _ambientAnimations.Add(new Tuple <AmbientAnimationTarget, CompositionAnimation>(
                                       AmbientAnimationTarget.ScaleKeyFrame,
                                       scaleForZAnimation));


            // Start some ambient animations
            _timer          = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromSeconds(5);
            _timer.Tick    += OnTimerTick;
            _timer.Start();
        }
        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 #28
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 #29
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 #30
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);
                    }
                });
            });
        }