这时候动画效果如下:

要使Visual可以正确旋转需要按以下方式处理:

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); }

讲真我也不明白为什么要这么写,只知道是从微软的 例子里抄的。每当SizeChanged事件发生时都需要调用这个函数重新设置TransformMatrix。

3. RotationAngleInDegrees#

Visual包含两个相似的属性,RotationAngleInDegrees和 RotationAngle,它们的定义如下:

Copy
// // 摘要: // 视觉对象的旋转角度(以度为单位)。 可动画处理。 // // 返回结果: // The rotation angle of the visual in degrees. public float RotationAngleInDegrees { get; set; } // // 摘要: // 视觉对象的旋转角度(以弧度为单位)。 可动画处理。 // // 返回结果: // The rotation angle in radians of the visual. public float RotationAngle { get; set; }

这两个属性都用于控制Visua围绕着RotationAxis和CenterPoint旋转。在FlipSide这个控件里RotationAngleInDegrees比较适用:

Copy
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",