uwp 表达式节点淡入淡出动画
uwp Expression node fade in animation
我正在使用 Windows UI 开发实验室示例库中的示例。我使用 ShyHeader 示例放入我的应用程序,但我没有使用完全相同的代码,但我实际上根据自己的需要编辑了示例。
我的问题是如何使用表达式节点淡入对应于滚动查看器的特定 XAML 元素,我能够使用滚动查看器淡出一个元素。但我无法淡入不透明度 0 -> 不透明度 1 的元素。
这是我的代码。
<ScrollViewer x:Name="MyScrollViewer">
<Grid>
<local:MyAdaptiveView Margin="0,300,0,0"
x:Name="AllVideosGridView"/>
<Grid x:Name="Header" Height="300" VerticalAlignment="Top">
<FlipView x:Name="MainFlipView"
</FlipView>
<Grid Background="Blue" Height="150" VerticalAlignment="Bottom" Opacity="0.5" Name="FrontGrid">
</Grid>
</Grid>
</Grid>
</ScrollViewer>
页面加载方式
唯一重要的代码片段仅在该方法的最后,最后 4、5 行,您可以看到我可以通过 1- progresNode[= 淡出元素30=] 但我尝试通过执行 0+ progressNode 淡入另一个元素( frontVisual )不起作用,即使在我滚动后 frontVisual 实际上仍保持 0 不透明度。
private void ShyView_Loaded(object sender, RoutedEventArgs e)
{
// 从 MyScrollViewer 获取包含滚动值的 PropertySet
_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", 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)Header.ActualWidth, (float)Header.ActualHeight);
// Insert the blur visual at the right point in the Visual Tree
ElementCompositionPreview.SetElementChildVisual(Header, _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(MainFlipView);
// Create and start an ExpressionAnimation to opacity fade out the image behind the header
ExpressionNode imageOpacityAnimation = 1 - progressNode;
photoVisual.StartAnimation("opacity", imageOpacityAnimation);
// Get the front visual for the photo in the header so that its properties can be animated
Visual frontVisual = ElementCompositionPreview.GetElementVisual(FrontGrid);
// Create and start an ExpressionAnimation to opacity fade out the image behind the header
ExpressionNode imageOpacityAnimation2 = 0 + progressNode;
frontVisual.StartAnimation("opacity", imageOpacityAnimation2);
}
注意 我真正想要的行为是当我向下滚动时 FlipView 应该淡出,当我向上滚动到顶部时它应该淡入,效果很好,但我希望 FrontGrid 与它完全相反,即:向下滚动时淡入,向上滚动时淡出。
提前致谢
你的表情看起来不错。
请注意,您使用 Composition 制作动画的 Opacity
是 Visual
的 Opacity
。但是,您在 FrontGrid
XAML 上设置的 0.5
的 Opacity
来自 UIElement
。这样做会破坏合成不透明度表达式动画。
修复很简单 - 尝试在 InitializeComponent
之后立即获取 FrontGrid
的 Visual
,然后将其 Opacity
设置为 0.5
(即 frontVisual.Opacity = 0.5
) 而不是在 XAML.
中设置它
由于 XAML-Composition Interop 行为更改.[=28,您将从周年更新开始看到这种 "weird" 行为=]
如需完整说明,请阅读此 official document。
简而言之,XAML不知道Composition是否改变了Opacity
,它仍然认为应该是上次设置的0.5
。所以它会尝试覆盖并导致动画失败。这也发生在 Offset
和 Size
等一些属性上。
我的建议是,如果你选择 Composition,请尝试一直使用 Composition。 :)
我正在使用 Windows UI 开发实验室示例库中的示例。我使用 ShyHeader 示例放入我的应用程序,但我没有使用完全相同的代码,但我实际上根据自己的需要编辑了示例。 我的问题是如何使用表达式节点淡入对应于滚动查看器的特定 XAML 元素,我能够使用滚动查看器淡出一个元素。但我无法淡入不透明度 0 -> 不透明度 1 的元素。 这是我的代码。
<ScrollViewer x:Name="MyScrollViewer">
<Grid>
<local:MyAdaptiveView Margin="0,300,0,0"
x:Name="AllVideosGridView"/>
<Grid x:Name="Header" Height="300" VerticalAlignment="Top">
<FlipView x:Name="MainFlipView"
</FlipView>
<Grid Background="Blue" Height="150" VerticalAlignment="Bottom" Opacity="0.5" Name="FrontGrid">
</Grid>
</Grid>
</Grid>
</ScrollViewer>
页面加载方式
唯一重要的代码片段仅在该方法的最后,最后 4、5 行,您可以看到我可以通过 1- progresNode[= 淡出元素30=] 但我尝试通过执行 0+ progressNode 淡入另一个元素( frontVisual )不起作用,即使在我滚动后 frontVisual 实际上仍保持 0 不透明度。 private void ShyView_Loaded(object sender, RoutedEventArgs e) { // 从 MyScrollViewer 获取包含滚动值的 PropertySet _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", 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)Header.ActualWidth, (float)Header.ActualHeight);
// Insert the blur visual at the right point in the Visual Tree
ElementCompositionPreview.SetElementChildVisual(Header, _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(MainFlipView);
// Create and start an ExpressionAnimation to opacity fade out the image behind the header
ExpressionNode imageOpacityAnimation = 1 - progressNode;
photoVisual.StartAnimation("opacity", imageOpacityAnimation);
// Get the front visual for the photo in the header so that its properties can be animated
Visual frontVisual = ElementCompositionPreview.GetElementVisual(FrontGrid);
// Create and start an ExpressionAnimation to opacity fade out the image behind the header
ExpressionNode imageOpacityAnimation2 = 0 + progressNode;
frontVisual.StartAnimation("opacity", imageOpacityAnimation2);
}
注意 我真正想要的行为是当我向下滚动时 FlipView 应该淡出,当我向上滚动到顶部时它应该淡入,效果很好,但我希望 FrontGrid 与它完全相反,即:向下滚动时淡入,向上滚动时淡出。
提前致谢
你的表情看起来不错。
请注意,您使用 Composition 制作动画的 Opacity
是 Visual
的 Opacity
。但是,您在 FrontGrid
XAML 上设置的 0.5
的 Opacity
来自 UIElement
。这样做会破坏合成不透明度表达式动画。
修复很简单 - 尝试在 InitializeComponent
之后立即获取 FrontGrid
的 Visual
,然后将其 Opacity
设置为 0.5
(即 frontVisual.Opacity = 0.5
) 而不是在 XAML.
由于 XAML-Composition Interop 行为更改.[=28,您将从周年更新开始看到这种 "weird" 行为=]
如需完整说明,请阅读此 official document。
简而言之,XAML不知道Composition是否改变了Opacity
,它仍然认为应该是上次设置的0.5
。所以它会尝试覆盖并导致动画失败。这也发生在 Offset
和 Size
等一些属性上。
我的建议是,如果你选择 Composition,请尝试一直使用 Composition。 :)