1. Operation effect

In this article, I introduced a tomato clock with Long Shadow in GetAlphaMask and ContainerVisual. The tomato clock used flip animation when switching state, as shown above, and also used spring animation. You can see that it kind of bounces back after flip. I was going to write my own animation, but HUO Huo has already written the FlipSide control, Github address is here, and this article will introduce some of the principles of this control.

2. TransformMatrix

Visual’s TransformMatrix property is a Matrix4x4 struct that is a transformation matrix applied to elements that can be animated. Its default values are as follows:

The animation looks like this:

To get Visual to rotate properly, do the following:

private void UpdateTransformMatrix(FrameworkElement element)
{
    var host = ElementCompositionPreview.GetElementVisual(element);
    var size = element.RenderSize.ToVector2();
    if (size.X == 0 || size.Y == 0) return;
    var n = - 1f / size.X;

    Matrix4x4 perspective = new Matrix4x4(
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, n,
        0.0f, 0.0f, 0.0f, 1.0f);

    host.TransformMatrix =
        Matrix4x4.CreateTranslation(-size.X / 2, -size.Y / 2.0f) *
        perspective *
        Matrix4x4.CreateTranslation(size.X / 2, size.Y / 2.0f);
}
Copy the code

I honestly don’t know why I wrote this, except that I copied it from the Microsoft example. This function is called every time a SizeChanged event occurs to reset the TransformMatrix.

3. RotationAngleInDegrees

Visual contains two similar attributes, RotationAngleInDegrees and RotationAngle, which are defined as follows:

//
/ / in this paper:
// The rotation Angle of the visual object in degrees. Can be animated processing.
//
// Return result:
// The rotation angle of the visual in degrees.
public float RotationAngleInDegrees { get; set; }
//
/ / in this paper:
// The rotation Angle of the visual object (in radians). Can be animated processing.
//
// Return result:
// The rotation angle in radians of the visual.
public float RotationAngle { get; set; }
Copy the code

Both properties are used to control Visua rotation around RotationAxis and CenterPoint. In FlipSide RotationAngleInDegrees works better:

float f1 = 0f, f2 = 0f;
if (IsFlipped)
{
    f1 = 180f;
    f2 = 360f;
    VisualStateManager.GoToState(this."Slide2".false);
}
else
{
    f1 = 0f;
    f2 = 180f;
    VisualStateManager.GoToState(this."Slide1".false);
}
if(springAnimation1 ! =null&& springAnimation2 ! =null)
{
    springAnimation1.FinalValue = f1;
    springAnimation2.FinalValue = f2;
    s1Visual.StartAnimation("RotationAngleInDegrees", springAnimation1);
    s2Visual.StartAnimation("RotationAngleInDegrees", springAnimation2);
}
Copy the code

This code uses the SpringAnimatin, so it has a bounce effect.

4. RotationAxis

RotationAxis is used to specify the axis on which the Visual rotates. FlipSide can change the rotation Angle by setting RotationAxis, as in the Fire Demo:

private void OnFlipSidePointerReleased(object sender, PointerRoutedEventArgs e)
{
    var position = e.GetCurrentPoint(_FlipSide).Position;
    var v2 = (position.ToVector2() - _FlipSide.RenderSize.ToVector2() / 2);
    _FlipSide.Axis = new Vector2(-v2.Y, v2.X);
}
Copy the code

5. ExpressionAnimation

<controls:FlipSide x:Name="FlipSide" IsFlipped="True">
    <controls:FlipSide.Side1>
        <Grid Background="#FFE87A69" x:Name="InworkElement" CornerRadius="1">
            
        </Grid>
    </controls:FlipSide.Side1>
    <controls:FlipSide.Side2>
        <Grid Background="#FF5271c2" x:Name="BreakElement" CornerRadius="1">
            
        </Grid>
    </controls:FlipSide.Side2>
</controls:FlipSide>
Copy the code

The XAML above is the FlipSide call code, which displays Side1 and Side2 (a name that gets Gunenthusiasts excited) as contents on the UI, showing the contents of Side1 when IsFlipped False and flipped past when IsFlipped True. The contents of Side2 are now displayed. When to hide Side1 and show Side2 during a rollover animation is a hassle. Fortunately, UWP has a powerful ExpressionAnimation, and FlipSide handles this with just a few lines of code:

s1Visual = ElementCompositionPreview.GetElementVisual(Side1Content);
s2Visual = ElementCompositionPreview.GetElementVisual(Side2Content);

var opacity1Animation = compositor.CreateExpressionAnimation("this.Target.RotationAngleInDegrees > 90 ? 0f : 1f");
var opacity2Animation = compositor.CreateExpressionAnimation("(this.Target.RotationAngleInDegrees - 180) > 90 ? 1f : 0f");

s1Visual.StartAnimation("Opacity", opacity1Animation);
s2Visual.StartAnimation("Opacity", opacity2Animation);
Copy the code

Hide if the RotationAngleInDegrees of Side1 is greater than 90 degrees, display otherwise; Side2 is the opposite. Where this.Target in the expression represents the Vsual that animates this expression.

The topic of expression animation is quite large, so I’ll leave this article at the back of my mind. See the links below for more information:

Relationship based animation – Windows UWP Applications Microsoft Docs

[Win 10 app Development] UI Composition (7) : Expression based Animation – Togo Dugu – Blog Garden

6. Conclusion

Thanks to huohuo for providing this control, I can save a lot of effort. In fact, I really don’t understand TransformMatrix, so this part is just for use and I can’t introduce it in detail. And I wasn’t interested in using 3D in the UI before, so I really couldn’t write much more about it. Expect fire to add some blogs to this.

Reference 7.

Relationship based animation – Windows UWP Applications Microsoft Docs

[Win 10 app Development] UI Composition (7) : Expression based Animation – Togo Dugu – Blog Garden

ExpressionAnimation Class (Windows.UI.Composition) – Windows UWP applications Microsoft Docs

Visual.TransformMatrix Property (Windows.UI.Composition) – Windows UWP applications Microsoft Docs

Compositing Visual objects – Windows UWP Applications Microsoft Docs

XAML Properties animation – Windows UWP Applications Microsoft Docs

8. The source code

cnbluefire_FlipSide