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)); } }
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 page_Loaded(object sender, RoutedEventArgs e) { Loaded -= page_Loaded; spVisual = ElementCompositionPreview.GetElementVisual(spContent); btnScrollVisual = ElementCompositionPreview.GetElementVisual(btn_Scroll); compositor = spVisual.Compositor; tracker = InteractionTracker.Create(compositor); var tref = tracker.GetReference(); var trackerTarget = ExpressionValues.Target.CreateInteractionTrackerTarget(); var endpoint1 = InteractionTrackerInertiaRestingValue.Create(compositor); endpoint1.SetCondition(trackerTarget.NaturalRestingPosition.Y < (trackerTarget.MaxPosition.Y - trackerTarget.MinPosition.Y) / 2); endpoint1.SetRestingValue(trackerTarget.MinPosition.Y); var endpoint2 = InteractionTrackerInertiaRestingValue.Create(compositor); endpoint2.SetCondition(trackerTarget.NaturalRestingPosition.Y >= (trackerTarget.MaxPosition.Y - trackerTarget.MinPosition.Y) / 2); endpoint2.SetRestingValue(trackerTarget.MaxPosition.Y); tracker.ConfigurePositionYInertiaModifiers(new InteractionTrackerInertiaModifier[] { endpoint1, endpoint2 }); interactionSource = VisualInteractionSource.Create(spVisual); interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia; tracker.InteractionSources.Add(interactionSource); propertySet = compositor.CreatePropertySet(); propertySet.InsertScalar("progress", 0.0f); propertySet.StartAnimation("progress", tref.Position.Y / tref.MaxPosition.Y); var progress = propertySet.GetReference().GetScalarProperty("progress"); btnScrollVisual.StartAnimation("RotationAngleInDegrees", ExpressionFunctions.Clamp(progress, 0f, 1f) * 180); btnScrollVisual.CenterPoint = new System.Numerics.Vector3((float)btn_Scroll.ActualWidth / 2, (float)btn_Scroll.ActualHeight / 2, 0); spVisual.StartAnimation("Offset.Y", -ExpressionFunctions.Clamp(progress, -0.4f, 1.4f) * tref.MaxPosition.Y); gdInfo_SizeChanged(this, null); }
private void OnPageLoaded(object sender, RoutedEventArgs e) { var animationService = ConnectedAnimationService.GetForCurrentView(); var animation = animationService.GetAnimation(Constants.ConnectedAnimationKey); if (animation != null) { animation.TryStart(CoverImage, new UIElement[] { SetImage }); } // Get the PropertySet that contains the scroll values from MyScrollViewer _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MyScrollviewer); _compositor = _scrollerPropertySet.Compositor; // Create a PropertySet that has values to be referenced in the ExpressionAnimations below _props = _compositor.CreatePropertySet(); _props.InsertScalar("progress", 0); _props.InsertScalar("clampSize", 100); // 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"); // Create and start an ExpressionAnimation to track scroll progress over the desired distance var progressAnimation = ExpressionFunctions.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1); _props.StartAnimation("progress", progressAnimation); // Get the backing visual for the header so that its properties can be animated var headerVisual = ElementCompositionPreview.GetElementVisual(Header); // Create and start an ExpressionAnimation to clamp the header's offset to keep it onscreen var headerTranslationAnimation = ExpressionFunctions.Conditional(progressNode < 1, 0, -scrollingProperties.Translation.Y - clampSizeNode); headerVisual.StartAnimation("Offset.Y", headerTranslationAnimation); // Create and start an ExpressionAnimation to scale the header during overpan var headerScaleAnimation = ExpressionFunctions.Lerp(1, 1.25f, ExpressionFunctions.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); }
private async void OnCardChromeHolding(object sender, HoldingRoutedEventArgs e) { if (e.PointerDeviceType == PointerDeviceType.Touch && e.HoldingState == HoldingState.Started) { // To create a continuous video playing experience, let's pause it here. _mediaElement.Pause(); // Record the location as we want to resume from here on another device. _mediaPlayedPosition = _mediaElement.Position; // We don't want to visually move the video player. Instead, we want to create the illusion that // a "copy" of it is being dragged down to another device. So here we use RenderTargetBitmap to // create such visual. var bitmap = new RenderTargetBitmap(); await bitmap.RenderAsync(Card); MediaCopy.Source = bitmap; MediaContainer.IsHitTestVisible = false; // Create animations to show that a "copy" of the video player is popped up and ready to be dragged up. Card.Fade(0.3f).Start(); MediaCopy .Fade(0.7f, 1) .Then() .Scale(0.975f, 0.975f, (float)Card.ActualWidth / 2, (float)Card.ActualHeight / 2, 300d) .Then() .Offset(offsetY: -24.0f, duration: 400d) .Start(); // Create an animation that changes the offset of the "copy" based on the manipulation progress. _mediaCopyVisual = VisualExtensions.GetVisual(MediaCopy); var progressExpressionNode = _progress.GetReference().GetScalarProperty("Progress"); _mediaCopyVisual.StartAnimation("Offset.Y", progressExpressionNode * -_maxDistance); try { // Let InteractionTracker to handle the swipe gesture. _interactionSource.TryRedirectForManipulation(_pressedPoint); // Send the card json and media played position over using Remote Sessions API. await RomeShare.SendMediaDataAsync(_cardJson, _mediaPlayedPosition, MediaUrl); } catch (UnauthorizedAccessException) { } } }
// This is for click-to-seek. Event current commented out on the trackCanvas, weird eventing issues between when this event gets called and when need to call OnDragStart() and OnDragStop() private void MousePointer_Pressed(object sender, PointerRoutedEventArgs e) { if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse) { OnDragStart(); var xPosition = (float)e.GetCurrentPoint(trackCanvas).Position.X; propSet.InsertVector3("xClickLocation", new System.Numerics.Vector3(-xPosition, 0f, 0f)); var pointerKFA = this.compositor.CreateVector3KeyFrameAnimation(); pointerKFA.Duration = TimeSpan.FromSeconds(1); // pointerKFA.InsertExpressionKeyFrame(1f, "props.xClickLocation"); // pointerKFA.SetReferenceParameter("props", propSet); pointerKFA.InsertExpressionKeyFrame(1f, propSet.GetReference().GetVector3Property("xClickLocation")); this.tracker.TryUpdatePositionWithAnimation(pointerKFA); } }
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 SetupExpressionAnimationsForCard() { _cardVisual = VisualExtensions.GetVisual(Card); _cardVisual.RelativeSizeAdjustment = Vector2.One; _cardVisual.CenterPoint = new Vector3(Card.RenderSize.ToVector2() / 2, 0.0f); var initialPositionY = (float)ActualHeight; _cardVisual.Offset = new Vector3(0.0f, initialPositionY, 0.0f); _progress.InsertScalar("Progress", 0); var progressExpressionNode = _progress.GetReference().GetScalarProperty("Progress"); // Scale the card visual based on the progress. _cardVisual.StartAnimation("Scale", EF.Vector3(1.0f, 1.0f, 1.0f) * EF.Lerp(0.6f, 1.0f, progressExpressionNode)); // Fade in the card visual based on the progress. _cardVisual.StartAnimation("Opacity", EF.Lerp(0.0f, 1.0f, progressExpressionNode)); // Move the card visual based on the progress. var offset = initialPositionY * (1.0f - progressExpressionNode); _cardVisual.StartAnimation("Offset.Y", offset); }
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); }
/// <summary> /// Uses Composition API to get the UIElement and sets an ExpressionAnimation /// The ExpressionAnimation uses the height of the UIElement to calculate an opacity value /// for the Header as it is scrolling off-screen. The opacity reaches 0 when the Header /// is entirely scrolled off. /// </summary> /// <returns><c>true</c> if the assignment was successful; otherwise, <c>false</c>.</returns> private bool AssignAnimation() { StopAnimation(); if (AssociatedObject == null) { return(false); } if (_scrollViewer == null) { _scrollViewer = AssociatedObject as ScrollViewer ?? AssociatedObject.FindDescendant <ScrollViewer>(); } if (_scrollViewer == null) { return(false); } var listView = AssociatedObject as Windows.UI.Xaml.Controls.ListViewBase ?? AssociatedObject.FindDescendant <Windows.UI.Xaml.Controls.ListViewBase>(); if (listView != null && listView.ItemsPanelRoot != null) { Canvas.SetZIndex(listView.ItemsPanelRoot, -1); } if (_scrollProperties == null) { _scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(_scrollViewer); } if (_scrollProperties == null) { return(false); } // Implicit operation: Find the Header object of the control if it uses ListViewBase if (HeaderElement == null && listView != null) { HeaderElement = listView.Header as UIElement; } var headerElement = HeaderElement as FrameworkElement; if (headerElement == null || headerElement.RenderSize.Height == 0) { return(false); } if (_headerVisual == null) { _headerVisual = ElementCompositionPreview.GetElementVisual(headerElement); } if (_headerVisual == null) { return(false); } _scrollViewer.ViewChanged -= ScrollViewer_ViewChanged; _scrollViewer.ViewChanged += ScrollViewer_ViewChanged; _scrollViewer.GotFocus -= ScrollViewer_GotFocus; _scrollViewer.GotFocus += ScrollViewer_GotFocus; headerElement.SizeChanged -= ScrollHeader_SizeChanged; headerElement.SizeChanged += ScrollHeader_SizeChanged; var compositor = _scrollProperties.Compositor; if (_animationProperties == null) { _animationProperties = compositor.CreatePropertySet(); _animationProperties.InsertScalar("OffsetY", 0.0f); } var propSetOffset = _animationProperties.GetReference().GetScalarProperty("OffsetY"); var scrollPropSet = _scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var expressionAnimation = ExpressionFunctions.Max(ExpressionFunctions.Min(propSetOffset, -scrollPropSet.Translation.Y), 0); _headerVisual.StartAnimation("Offset.Y", expressionAnimation); return(true); }
/// <summary> /// Uses Composition API to get the UIElement and sets an ExpressionAnimation /// The ExpressionAnimation uses the height of the UIElement to calculate an opacity value /// for the Header as it is scrolling off-screen. The opacity reaches 0 when the Header /// is entirely scrolled off. /// </summary> /// <returns><c>true</c> if the assignment was successful; otherwise, <c>false</c>.</returns> private bool AssignAnimation() { StopAnimation(); // Confirm that Windows.UI.Xaml.Hosting.ElementCompositionPreview is available (Windows 10 10586 or later). if (!ApiInformation.IsMethodPresent("Windows.UI.Xaml.Hosting.ElementCompositionPreview", nameof(ElementCompositionPreview.GetScrollViewerManipulationPropertySet))) { // Just return true since it's not supported return(true); } if (AssociatedObject == null) { return(false); } if (_scrollViewer == null) { _scrollViewer = AssociatedObject as ScrollViewer ?? AssociatedObject.FindDescendant <ScrollViewer>(); } if (_scrollViewer == null) { return(false); } var listView = AssociatedObject as Windows.UI.Xaml.Controls.ListViewBase ?? AssociatedObject.FindDescendant <Windows.UI.Xaml.Controls.ListViewBase>(); if (listView != null && listView.ItemsPanelRoot != null) { Canvas.SetZIndex(listView.ItemsPanelRoot, -1); } if (_scrollProperties == null) { _scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(_scrollViewer); } if (_scrollProperties == null) { return(false); } // Implicit operation: Find the Header object of the control if it uses ListViewBase if (HeaderElement == null && listView != null) { HeaderElement = listView.Header as UIElement; } var headerElement = HeaderElement as FrameworkElement; if (headerElement == null || headerElement.RenderSize.Height == 0) { return(false); } if (_headerVisual == null) { _headerVisual = ElementCompositionPreview.GetElementVisual(headerElement); } if (_headerVisual == null) { return(false); } headerElement.SizeChanged -= ScrollHeader_SizeChanged; headerElement.SizeChanged += ScrollHeader_SizeChanged; _scrollViewer.GotFocus -= ScrollViewer_GotFocus; _scrollViewer.GotFocus += ScrollViewer_GotFocus; var compositor = _scrollProperties.Compositor; if (_animationProperties == null) { _animationProperties = compositor.CreatePropertySet(); _animationProperties.InsertScalar("OffsetY", 0.0f); } _previousVerticalScrollOffset = _scrollViewer.VerticalOffset; var propSetOffset = _animationProperties.GetReference().GetScalarProperty("OffsetY"); var scrollPropSet = _scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var expressionAnimation = ExpressionFunctions.Max(propSetOffset - scrollPropSet.Translation.Y, 0); _headerVisual.StartAnimation("Offset.Y", expressionAnimation); return(true); }
private void OnLoaded(object sender, RoutedEventArgs e) { var gridView = this.FindAscendant <GridView>(); if (gridView == null) { return; } var scrollViewer = gridView.FindDescendant <ScrollViewer>(); var headerPresenter = (UIElement)VisualTreeHelper.GetParent((UIElement)gridView.Header); var headerContainer = (UIElement)VisualTreeHelper.GetParent(headerPresenter); Canvas.SetZIndex(headerContainer, 1); _scrollerPropertySet = scrollViewer.GetScrollViewerManipulationPropertySet(); _compositor = _scrollerPropertySet.Compositor; _props = _compositor.CreatePropertySet(); _props.InsertScalar("progress", 0); _props.InsertScalar("clampSize", 240); _props.InsertScalar("scaleFactor", 0.7f); var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var props = _props.GetReference(); var progressNode = props.GetScalarProperty("progress"); var clampSizeNode = props.GetScalarProperty("clampSize"); var scaleFactorNode = props.GetScalarProperty("scaleFactor"); ExpressionNode progressAnimation = ExpressionFunctions.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1); _props.StartAnimation("progress", progressAnimation); ExpressionNode headerScaleAnimation = ExpressionFunctions.Lerp(1, 1.25f, ExpressionFunctions.Clamp(scrollingProperties.Translation.Y / 50, 0, 1)); ExpressionNode headerTranslationAnimation = ExpressionFunctions.Conditional(progressNode < 1, 0, -scrollingProperties.Translation.Y - clampSizeNode); var headerVisual = this.ElementVisual(); headerVisual.CenterPoint = new Vector3((float)(this.ActualWidth / 2), (float)this.ActualHeight, 0); headerVisual.StartAnimation("Scale.X", headerScaleAnimation); headerVisual.StartAnimation("Scale.Y", headerScaleAnimation); headerVisual.StartAnimation("Offset.Y", headerTranslationAnimation); ExpressionNode primaryOpacityAnimation = 1 - progressNode; PrimaryBackground.ElementVisual().StartAnimation("opacity", primaryOpacityAnimation); ExpressionNode secondaryOpacityAnimation = progressNode; SecondaryBackground.ElementVisual().StartAnimation("opacity", secondaryOpacityAnimation); ExpressionNode scaleAnimation = ExpressionFunctions.Lerp(1, scaleFactorNode, progressNode); ExpressionNode opacityAnimation = ExpressionFunctions.Clamp(1 - (progressNode * 2), 0, 1); Visual autoSearchBoxVisual = SearchBox.ElementVisual(); autoSearchBoxVisual.CenterPoint = new Vector3((float)(SearchBox.ActualWidth / 2), (float)SearchBox.ActualHeight, 0); autoSearchBoxVisual.StartAnimation("Scale.X", scaleAnimation); autoSearchBoxVisual.StartAnimation("Scale.Y", scaleAnimation); autoSearchBoxVisual.StartAnimation("Opacity", opacityAnimation); Visual subMenuPanelVisual = SubMenuPanel.ElementVisual(); ExpressionNode contentOffsetAnimation = progressNode * 100; subMenuPanelVisual.StartAnimation("Offset.Y", contentOffsetAnimation); ExpressionNode searchBtnOpacityAnimation = ExpressionFunctions.Conditional(progressNode < 1, 0, 1); Visual searchBtnVisual = ElementCompositionPreview.GetElementVisual(SearchBtn); searchBtnVisual.StartAnimation("Opacity", searchBtnOpacityAnimation); }
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); }
/// <summary> /// Uses Composition API to get the UIElement and sets an ExpressionAnimation /// The ExpressionAnimation uses the height of the UIElement to calculate an opacity value /// for the Header as it is scrolling off-screen. The opacity reaches 0 when the Header /// is entirely scrolled off. /// </summary> /// <returns><c>true</c> if the assignment was successful; otherwise, <c>false</c>.</returns> private bool AssignAnimation() { StopAnimation(); if (AssociatedObject == null) { return(false); } if (_scrollViewer == null) { _scrollViewer = AssociatedObject as ScrollViewer ?? AssociatedObject.FindDescendant <ScrollViewer>(); } if (_scrollViewer == null) { return(false); } var listView = AssociatedObject as ListViewBase ?? AssociatedObject.FindDescendant <ListViewBase>(); if (listView != null && listView.ItemsPanelRoot != null) { Canvas.SetZIndex(listView.ItemsPanelRoot, -1); } if (_scrollProperties == null) { _scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(_scrollViewer); } if (_scrollProperties == null) { return(false); } // Implicit operation: Find the Header object of the control if it uses ListViewBase if (HeaderElement == null && listView != null) { HeaderElement = listView.Header as UIElement; } var headerElement = HeaderElement as FrameworkElement; if (headerElement == null || headerElement.RenderSize.Height == 0) { return(false); } if (_headerVisual == null) { _headerVisual = ElementCompositionPreview.GetElementVisual(headerElement); } if (_headerVisual == null) { return(false); } headerElement.SizeChanged -= ScrollHeader_SizeChanged; headerElement.SizeChanged += ScrollHeader_SizeChanged; _scrollViewer.GotFocus -= ScrollViewer_GotFocus; _scrollViewer.GotFocus += ScrollViewer_GotFocus; var compositor = _scrollProperties.Compositor; if (_animationProperties == null) { _animationProperties = compositor.CreatePropertySet(); _animationProperties.InsertScalar("OffsetY", 0.0f); } var propSetOffset = _animationProperties.GetReference().GetScalarProperty("OffsetY"); var scrollPropSet = _scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var expressionAnimation = ExpressionFunctions.Max(propSetOffset - scrollPropSet.Translation.Y, 0); _headerVisual.StartAnimation("Offset.Y", expressionAnimation); // Mod: clip items panel below header var itemsPanel = listView.ItemsPanelRoot; if (itemsPanel == null) { return(true); } if (_itemsPanelVisual == null) { _itemsPanelVisual = ElementCompositionPreview.GetElementVisual(itemsPanel); _contentClip = compositor.CreateInsetClip(); _itemsPanelVisual.Clip = _contentClip; } var expressionClipAnimation = ExpressionFunctions.Max(-scrollPropSet.Translation.Y, 0); _contentClip.TopInset = (float)System.Math.Max(-_scrollViewer.VerticalOffset, 0); _contentClip.StartAnimation("TopInset", expressionClipAnimation); return(true); }
private void MainInformationPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { ApplicationViewTitleBar formattableTitleBar = ApplicationView.GetForCurrentView().TitleBar; formattableTitleBar.ButtonBackgroundColor = Colors.Transparent; formattableTitleBar.ButtonInactiveBackgroundColor = Colors.Transparent; CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar; coreTitleBar.ExtendViewIntoTitleBar = true; // Update the ZIndex of the header container so that the header is above the items when scrolling Canvas.SetZIndex(Header, 1); // Get the PropertySet that contains the scroll values from the ScrollViewer _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer); _compositor = _scrollerPropertySet.Compositor; // Create a PropertySet that has values to be referenced in the ExpressionAnimations below _props = _compositor.CreatePropertySet(); _props.InsertScalar("progress", 0); _props.InsertScalar("clampSize", 150); _props.InsertScalar("scaleFactor", 0.7f); // Get references to our property sets for use with ExpressionNodes var scrollingProperties = _scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var props = _props.GetReference(); var progressNode = props.GetScalarProperty("progress"); var clampSizeNode = props.GetScalarProperty("clampSize"); // Create and start an ExpressionAnimation to track scroll progress over the desired distance ExpressionNode progressAnimation = ExpressionFunctions.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1); _props.StartAnimation("progress", progressAnimation); // Get the backing visual for the header so that its properties can be animated headerVisual = ElementCompositionPreview.GetElementVisual(Header); // Create and start an ExpressionAnimation to clamp the header's offset to keep it onscreen ExpressionNode headerTranslationAnimation = ExpressionFunctions.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 = ExpressionFunctions.Lerp(1, 1.25f, ExpressionFunctions.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); ExpressionNode OpacityAnimation = ExpressionFunctions.Clamp(1 - (progressNode * 2), 0, 1); Visual profileVisual = ElementCompositionPreview.GetElementVisual(ProfileImage); profileVisual.StartAnimation("Opacity", OpacityAnimation); Visual subtitleVisual = ElementCompositionPreview.GetElementVisual(SubtitleBlock); subtitleVisual.StartAnimation("Opacity", OpacityAnimation); // Get the backing visuals for the text and button containers so that their properites can be animated Visual buttonVisual = ElementCompositionPreview.GetElementVisual(ButtonPanel); ExpressionNode buttonOffsetAnimation = progressNode * -14; buttonVisual.StartAnimation("Offset.Y", buttonOffsetAnimation); }