I believe the Windows.UI.Composition tools are conflicting with the XAML VisualStates on buttons.
GIF #1 When a button is in its Normal state, without the cursor hovering, the animations work and the buttons disappear successfully on scrolling down and then reappear successfully on scrolling up.
GIF #2 If the cursor is hovering over a button when the composition animation completes, and the mouse exits the button before scrolling up, I believe the PointerOver state gets frozen and the opacity of 0% gets stuck. The only way to fix it is to hover again to unjam the XAML VisualStates.
The buttons are all in the same StackPanel, which is the target of the opacity animation. When one button has this problem, the whole StackPanel gets stuck at 0% opacity. The code below is the general gist, some pieces omitted for brevity. I do not think this is a code issue, I think it is a platform limitation and I am looking for a workaround.
CompositionPropertySet _scrollerPropertySet =
ElementCompositionPreview.GetScrollViewerManipulationPropertySet((ScrollViewer)sender);
Compositor _compositor = _scrollerPropertySet.Compositor;
CompositionPropertySet _props = _compositor.CreatePropertySet();
_props.InsertScalar("progress", 0);
var scrollingProperties =
_scrollerPropertySet.GetSpecializedReference<ManipulationPropertySetReferenceNode>();
var props = _props.GetReference();
var progressNode = props.GetScalarProperty("progress");
ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);
_props.StartAnimation("progress", progressAnimation);
// StackPanel relevant code:
Visual carOperationButtonStackPanelVisual=
ElementCompositionPreview.GetElementVisual(CarOperationStackPanel);
ExpressionNode carSubtitleObjectOpacityAnimation = 1 - (progressNode * 2);
carOperationButtonStackPanelVisual.StartAnimation("Opacity", carSubtitleObjectOpacityAnimation);
In the code excerpt above, near the end, this line
ExpressionNode carSubtitleObjectOpacityAnimation = 1 - (progressNode * 2);
should be
ExpressionNode carSubtitleObjectOpacityAnimation = ExpressionFunctions.Lerp(0, 1, 1 - (progressNode * 2));
This will force the opacity to update with a linear interpolation from 0 to 1. For what it's worth, I copied the source code from the Win UI samples repo, which does not use Lerp() for opacity. My conclusion is that Lerp is more taxing on the system, but necessary when the controls have visual states. The sample repo animates a simple TextBlock (which does not have visual states).