Reputation: 4465
I am using the sample on Windows UI dev labs sample gallery. And I used ShyHeader example to put in my app, but I am not using exactly the same code but I actually edited the example according to own needs. My question is how can I use expression node to fade in a specific XAML element in correspondence to the scroll viewer, I am able to fade out an element with the scroll viewer. but I am not being able to fade in an element from opacity 0 -> opacity 1. here is my code.
<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>
page loaded method
the only important piece of code is only at the very end of this method, the last 4, 5 lines, you can see I am able to fade out element by doing 1- progresNode but my attempt to fade in another element ( frontVisual ) by doing 0+ progressNode doesn't work and frontVisual actually remains at 0 opacity even after I scroll. private void ShyView_Loaded(object sender, RoutedEventArgs e) { // 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", 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);
}
Note the behavior I actually want is that when I scroll down then FlipView should fade out and when I scroll up to the top it should fade in, which is working perfectly, but along with it I want FrontGrid to be exactly opposite, i.e: fade in on scroll down and fade out on scroll up.
Thanks in advance
Upvotes: 2
Views: 552
Reputation: 39006
Your expression looks OK.
Note the Opacity
you are animating with Composition is the Opacity
of Visual
. However, the Opacity
of 0.5
you are setting on FrontGrid
XAML is from UIElement
. Doing so will break the Composition opacity expression animation.
The fix is simple - Try getting the Visual
of your FrontGrid
right after InitializeComponent
and set its Opacity
to 0.5
there (i.e. frontVisual.Opacity = 0.5
) instead of setting it in XAML.
You will see this kind of "weird" behaviors starting from the Anniversary Update, due to a XAML-Composition Interop Behavior change.
For a full explanation, please read this official document.
In short, XAML doesn't know if Composition has changed the Opacity
, it still thinks it should be 0.5
as it was last set. So it will try to override and cause the animation to fail. This happens to a few more properties like Offset
and Size
too.
My advice is if you go Composition, try going Composition all the way. :)
Upvotes: 2