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