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 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); }
/// <summary> /// Creation of an expression to manage modulo (positive and negative value) /// </summary> /// <param name="scrollViewer">The ScrollViewer to synchronized. A null value is valid</param> /// <param name="imageWidth">Width of the image</param> /// <param name="imageHeight">Height of the image</param> /// <param name="scrollOrientation">The ScrollOrientation</param> private void CreateModuloExpression(ScrollViewer scrollViewer, double imageWidth, double imageHeight, ScrollOrientation scrollOrientation) { const string offsetXParam = "offsetX"; const string offsetYParam = "offsetY"; const string imageWidthParam = "imageWidth"; const string imageHeightParam = "imageHeight"; const string speedParam = "speed"; if (_containerVisual == null) { return; } var compositor = _containerVisual.Compositor; // Setup the expression ExpressionNode expressionX = null; ExpressionNode expressionY = null; ExpressionNode expressionXVal; ExpressionNode expressionYVal; var propertySetModulo = compositor.CreatePropertySet(); propertySetModulo.InsertScalar(imageWidthParam, (float)imageWidth); propertySetModulo.InsertScalar(offsetXParam, (float)OffsetX); propertySetModulo.InsertScalar(imageHeightParam, (float)imageHeight); propertySetModulo.InsertScalar(offsetYParam, (float)OffsetY); propertySetModulo.InsertScalar(speedParam, (float)ParallaxSpeedRatio); var propertySetNodeModulo = propertySetModulo.GetReference(); var imageHeightNode = propertySetNodeModulo.GetScalarProperty(imageHeightParam); var imageWidthNode = propertySetNodeModulo.GetScalarProperty(imageWidthParam); if (scrollViewer == null) { var offsetXNode = ExpressionFunctions.Ceil(propertySetNodeModulo.GetScalarProperty(offsetXParam)); var offsetYNode = ExpressionFunctions.Ceil(propertySetNodeModulo.GetScalarProperty(offsetYParam)); // expressions are created to simulate a positive and negative modulo with the size of the image and the offset expressionXVal = ExpressionFunctions.Conditional( offsetXNode == 0, 0, ExpressionFunctions.Conditional( offsetXNode < 0, -(ExpressionFunctions.Abs(offsetXNode - (ExpressionFunctions.Ceil(offsetXNode / imageWidthNode) * imageWidthNode)) % imageWidthNode), -(imageWidthNode - (offsetXNode % imageWidthNode)))); expressionYVal = ExpressionFunctions.Conditional( offsetYNode == 0, 0, ExpressionFunctions.Conditional( offsetYNode < 0, -(ExpressionFunctions.Abs(offsetYNode - (ExpressionFunctions.Ceil(offsetYNode / imageHeightNode) * imageHeightNode)) % imageHeightNode), -(imageHeightNode - (offsetYNode % imageHeightNode)))); } else { // expressions are created to simulate a positive and negative modulo with the size of the image and the offset and the ScrollViewer offset (Translation) var scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer); var scrollPropSet = scrollProperties.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var speed = propertySetNodeModulo.GetScalarProperty(speedParam); var xCommon = ExpressionFunctions.Ceil((scrollPropSet.Translation.X * speed) + propertySetNodeModulo.GetScalarProperty(offsetXParam)); expressionXVal = ExpressionFunctions.Conditional( xCommon == 0, 0, ExpressionFunctions.Conditional( xCommon < 0, -(ExpressionFunctions.Abs(xCommon - (ExpressionFunctions.Ceil(xCommon / imageWidthNode) * imageWidthNode)) % imageWidthNode), -(imageWidthNode - (xCommon % imageWidthNode)))); var yCommon = ExpressionFunctions.Ceil((scrollPropSet.Translation.Y * speed) + propertySetNodeModulo.GetScalarProperty(offsetYParam)); expressionYVal = ExpressionFunctions.Conditional( yCommon == 0, 0, ExpressionFunctions.Conditional( yCommon < 0, -(ExpressionFunctions.Abs(yCommon - (ExpressionFunctions.Ceil(yCommon / imageHeightNode) * imageHeightNode)) % imageHeightNode), -(imageHeightNode - (yCommon % imageHeightNode)))); } if (scrollOrientation == ScrollOrientation.Horizontal || scrollOrientation == ScrollOrientation.Both) { expressionX = expressionXVal; if (scrollOrientation == ScrollOrientation.Horizontal) { // In horizontal mode we never move the offset y expressionY = (ScalarNode)0.0f; _containerVisual.Offset = new Vector3((float)OffsetY, 0, 0); } } if (scrollOrientation == ScrollOrientation.Vertical || scrollOrientation == ScrollOrientation.Both) { expressionY = expressionYVal; if (scrollOrientation == ScrollOrientation.Vertical) { // In vertical mode we never move the offset x expressionX = (ScalarNode)0.0f; _containerVisual.Offset = new Vector3(0, (float)OffsetX, 0); } } _containerVisual.StopAnimation("Offset.X"); _containerVisual.StopAnimation("Offset.Y"); _containerVisual.StartAnimation("Offset.X", expressionX); _containerVisual.StartAnimation("Offset.Y", expressionY); _propertySetModulo = propertySetModulo; }
private void InitializeExpressionAnimations() { try { // Get the PropertySet that contains the scroll values from MyScrollViewer var scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(AccountScrollViewer); var compositor = scrollerPropertySet.Compositor; // Create a PropertySet that has values to be referenced in the ExpressionAnimations below var props = compositor.CreatePropertySet(); props.InsertScalar("progress", 0); props.InsertScalar("clampSize", 88); props.InsertScalar("scaleFactor", 0.3f); // Get references to our property sets for use with ExpressionNodes var scrollingProperties = scrollerPropertySet.GetSpecializedReference <ManipulationPropertySetReferenceNode>(); var properties = props.GetReference(); var progressNode = properties.GetScalarProperty("progress"); var clampSizeNode = properties.GetScalarProperty("clampSize"); var scaleFactorNode = properties.GetScalarProperty("scaleFactor"); // 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); // *** Scaling the header grid *** // 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); // *** Animating the account logo *** // Get the backing visual for the account logo visual so that its properties can be animated var accountLogoVisual = ElementCompositionPreview.GetElementVisual(HeaderAccountLogo); // Create and start an ExpressionAnimation to scale the account logo with scroll position var accountLogoScaleAnimation = ExpressionFunctions.Lerp(1, scaleFactorNode, progressNode); accountLogoVisual.StartAnimation("Scale.X", accountLogoScaleAnimation); accountLogoVisual.StartAnimation("Scale.Y", accountLogoScaleAnimation); // *** Animating the title *** // Get the backing visual for the title visual so that its properties can be animated var titleVisual = ElementCompositionPreview.GetElementVisual(HeaderTitle); // Create and start an ExpressionAnimation to scale the title with scroll position var titleOffsetAnimation = progressNode * -88; titleVisual.StartAnimation("Offset.X", titleOffsetAnimation); // *** Animating the subtitle *** // Get the backing visual for the subtitle visual so that its properties can be animated var subtitleVisual = ElementCompositionPreview.GetElementVisual(HeaderSubtitle); // Create and start an ExpressionAnimation to scale the subtitle with scroll position var subtitleScaleAnimation = ExpressionFunctions.Lerp(1, scaleFactorNode, progressNode); subtitleVisual.StartAnimation("Scale.X", subtitleScaleAnimation); subtitleVisual.StartAnimation("Scale.Y", subtitleScaleAnimation); // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for subtitle opacity var subtitleOpacityAnimation = ExpressionFunctions.Clamp(1 - (progressNode * 2), 0, 1); subtitleVisual.StartAnimation("Opacity", subtitleOpacityAnimation); // *** Animating the editable subtitle *** // Get the backing visual for the subtitle visual so that its properties can be animated var editableSubtitleVisual = ElementCompositionPreview.GetElementVisual(HeaderEditableSubtitle); // Create and start an ExpressionAnimation to scale the subtitle with scroll position var editableSubtitleScaleAnimation = ExpressionFunctions.Lerp(1, scaleFactorNode, progressNode); editableSubtitleVisual.StartAnimation("Scale.X", editableSubtitleScaleAnimation); editableSubtitleVisual.StartAnimation("Scale.Y", editableSubtitleScaleAnimation); // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for subtitle opacity var editableSubtitleOpacityAnimation = ExpressionFunctions.Clamp(1 - (progressNode * 2), 0, 1); editableSubtitleVisual.StartAnimation("Opacity", editableSubtitleOpacityAnimation); // *** Animating the buttons bar *** // Get the backing visual for the buttons bar visual so that its properties can be animated var buttonsBarVisual = ElementCompositionPreview.GetElementVisual(HeaderButtonsBar); // Create and start an ExpressionAnimation to scale the buttons bar with scroll position var buttonsBarOffsetAnimation = progressNode * -88; buttonsBarVisual.StartAnimation("Offset.Y", buttonsBarOffsetAnimation); // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for buttons bar opacity var buttonsBarOpacityAnimation = ExpressionFunctions.Clamp(1 - (progressNode * 2), 0, 1); buttonsBarVisual.StartAnimation("Opacity", buttonsBarOpacityAnimation); // *** Animating the header content *** // Get the backing visual for the header content visual so that its properties can be animated var headerContentVisual = ElementCompositionPreview.GetElementVisual(HeaderContent); // When the header stops scrolling it is 88 pixels offscreen. We want the text header to end up with 24 pixels of its content // offscreen which means it needs to go from offset 0 to 88 as we traverse through the scrollable region var headerContentOffsetAnimation = progressNode * 88; headerContentVisual.StartAnimation("Offset.Y", headerContentOffsetAnimation); } catch { } }
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); }