animationuwprotationwindows-composition-api2.5d

Does the Windows Composition API support 2.5D projected rotation?


I have started to use the Windows Composition API in UWP applications to animate elements of the UI.

Visual elements expose RotationAngleInDegrees and RotationAngle properties as well as a RotationAxis property.

When I animate a rectangular object's RotationAngleInDegrees value around the Y axis, the rectangle rotates as I would expect but in a 2D application window, it does not appear to be displaying with a 2.5D projection.

Is there a way to get the 2.5D projection effect on rotations with the composition api?


Solution

  • As the sample that @BarryWang pointed me to demonstrates it is necessary to apply a TransformMatrix to the page (or a parenting container) before executing the animation to get the 2.5D effect with rotation or other spatial transformation animations with the composition api.

        private void UpdatePerspective()
        {
            Visual visual = ElementCompositionPreview.GetElementVisual(MainPanel);
    
            // Get the size of the area we are enabling perspective for
            Vector2 sizeList = new Vector2((float)MainPanel.ActualWidth, (float)MainPanel.ActualHeight);
    
            // Setup the perspective transform.
            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, -1.0f / sizeList.X,
    
                        0.0f, 0.0f, 0.0f, 1.0f);
    
            // Set the parent transform to apply perspective to all children
            visual.TransformMatrix =
    
                               Matrix4x4.CreateTranslation(-sizeList.X / 2, -sizeList.Y / 2, 0f) *      // Translate to origin
    
                               perspective *                                                            // Apply perspective at origin
    
                               Matrix4x4.CreateTranslation(sizeList.X / 2, sizeList.Y / 2, 0f);         // Translate back to original position
        }