Everyone likes a good parallax scroll effect, right? While that's a good start, you can do so much more once you master the very basic techniques. In this post and video I look at behaviors, converters, and data triggers to add other animation effects and transitions to your UI.
The basis for this example is a reproduction of the Reverb app which I made a long time ago in my Xappy playground app. Navigate to Content\Scenarios\ProductDetails for the completed code.
Since the scrolling of content is the basis for all the effects in this experience, we need to start with getting values we can bind to. As those values change, we can follow along and trigger other things to happen in the UI.
The easiest way to get values such as the scroll X/Y, relative scroll X/Y, and percentage scroll X/Y is using a behavior from the awesome XAML animation library Xamanimation. Xamanimation is a library that leverages all the built-in APIs of Xamarin.Forms to make complex animations with ease.
Let's start by adding this behavior to our Scrollview:
To parallax scroll means that the foreground content moves at a different pace than the background (or middle ground) content. Let's start by understanding the layers of this layout.
I'm using a
Grid which effectively is a z-stack. The first item in the layout is in the back, then the next stacks on top of it, obscuring it. To then lay things out you'd use columns and rows of different sizes, define any elements to span columns and rows, and the vertical and horizontal options on your children elements. These are the basic points you have to control the layout and achieve any complexity you require.
This is a look at the structure of this layout:
- StackLayout - this is where all of our content resides
- FlexLayout - navigation bar with no background
- FlexLayout - navigation bar with white background
ScrollView scrolls content, it will appear over the top of the
BoxView just mirrors the
CarouselView to leave behind a white background.
Now, in order to move the box and carousel with the content scrolling, we will bind to the scroll behavior's
RelativeScrollY and translate the Y position of those views.
If I only used the
ScrollY values, the views would translate linear with the content, keeping pace. Instead, I want them to scroll a little slower, thus creating the parallax effect. To do this, I wrote the ScrollValueConverter, a value converter. To tweak the animation effect I pass in several arguments, semi-colon delimited.
The main value of importance here is the "factor" that I use to multiple against the calculated percentage of scroll. The
-5 seems like it does nicely.
I also want the carousel to fade out as the user scrolls, so for this scenario we can use a Xamarin.Forms behavior, provided again by Xamanimation. This allows you to animate any value based on another value you bind to.
This time I'm using the
ScrollY value to change the
VisualElement.Opacity to achieve a linear effect. The behavior starts at the Y value 0 and continues until 180 moving the opacity from 1 to 0. Pretty straight forward!
As the user scrolls and the carousel fades out, the navigation bar transitions from transparent background to solid, AND shifts the icons from white to dark. This can be accomplished in several ways, but I chose to do it by duplicating the navigation bar. As the user reaches a certain scroll point, a fade in/out animation is triggered.
This takes advantage of data triggers in Xamarin.Forms. The value of
ScrollY is evaluated against criteria I've set to determine a boolean result. When true the
EnterActions are called, and when false the
I wrote another value converter, ComparisonConverter, to take a Y position and compare it to my parameter. The parameters are a position value and a comparison rule; in this case, greater than. As the value crosses that boundary, the animations are called.
Xamanimation brings animation extensions from C# to XAML. In this case, I've defined the animations to be triggered in my page resources:
As the content scrolls out of view and back into view it scales away and fades. This happens linearly to the scroll position and at a certain Y position. Since we did this already with the behavior above, this same technique may be applied to each frame of content within the scroll view.
When the first frame hits a scroll Y of 320 it will scale to 75% and fade out completely by the time it reaches a scroll Y of 400. Simple and beautiful!
Please share any cool user experiences you create using these techniques in your experiments and applications. Enjoy!