http://yichuanshen.de/blog/2010/11/13/flipping-elements-with-wpf/

Have you already seen ForgottenTime’s new flip animation eye candy? If not, it’s about time! It took me several days to figure out how to do it…

My first thought was to find out how to do a 4-point-tranformation of a given image. (See figure on the left.) It’s no problem to create an “screenshot” of a UI element and I could easily calculate the four vertices of the transformed image (with given angle and a little bit trigonometry) and transform the original screenshot via the function to achieve a 3D effect. Unfortunately, there’s no (easy and fast) way to do that in C# and Windows Presentation Framework, so I had to think of something else.

After my research on the Internet I came across some official demo WPF applications, also using advanced UI techniques such as flipping. So I dug into the code to find out how they did it. As it turned out, they were using 3D graphics.

WELCOME TO THE 3RD DIMENSION

Strictly speaking a computer screen cannot display real 3D graphics of course, only projections of a 3D space onto a plane… the screen. It’s also called a “viewport”, a 2D window, that allows the user to gaze into the imaginary 3D space behind. Just like we have eyes, a viewport needs a “camera” (to be really precise, a PerspectiveCamera).

Let’s assume the image we want to flip is a square with the dimensions 129×129.

<!-- XAML code -->
<Viewport3D x:Name="viewport3D" Width="129" Height="129"><Viewport3D.Resources></Viewport3D.Resources><Viewport3D.Camera><PerspectiveCamera x:Name="cam3D"FieldOfView="45"LookDirection="0,0,-1 " UpDirection="0,1,0" /></Viewport3D.Camera>
</Viewport3D>

After the window is loaded, we create a two-dimensional object, a square, which represents our image in 3D space and calculate where our camera should be. If all that is done, we can literally rotate the object around the y-axis and thus flip the image around.

THE TWO-DIMENSIONAL OBJECT

Every object in our 3D space is made of triangles. The triangle surface of such an object is called a mesh. It’s relatively easy to build a square out of two triangles as the sketch below shows.

We center the image around the origin, so that the camera can be easily positioned on the z-axis. To create such a simple object (notice this is two-dimensional!) you have to write tons of code:

// C# code
GeometryModel3D model3D;private void BuildModel() {// Customize the brushes// Can be any brush (ImageBrush, DrawingBrush, VisualBrush, ...)ImageBrush front = new ImageBrush(this.frontImageSource);ImageBrush back = new ImageBrush(this.backImageSource);back.Transform = new ScaleTransform(-1, 1, .5, 0); // Flip back image// Create meshMeshGeometry3D mesh = new MeshGeometry3D();double radius = 129 / 2.0; // 64.5mesh.Positions.Add(new Point3D(-radius, -radius, 0));mesh.Positions.Add(new Point3D(radius, -radius, 0));mesh.Positions.Add(new Point3D(radius, radius, 0));mesh.Positions.Add(new Point3D(-radius, radius, 0));mesh.TriangleIndices.Add(0);mesh.TriangleIndices.Add(1);mesh.TriangleIndices.Add(2);mesh.TriangleIndices.Add(0);mesh.TriangleIndices.Add(2);mesh.TriangleIndices.Add(3);mesh.TextureCoordinates.Add(new Point(0, 1));mesh.TextureCoordinates.Add(new Point(1, 1));mesh.TextureCoordinates.Add(new Point(1, 0));mesh.TextureCoordinates.Add(new Point(0, 0));// Add textureDiffuseMaterial frontMat = new DiffuseMaterial(front);DiffuseMaterial backMat = new DiffuseMaterial(back);frontMat.AmbientColor = backMat.AmbientColor = Colors.White;model3D = new GeometryModel3D();model3D.Geometry = mesh;model3D.Material = frontMat;model3D.BackMaterial = backMat;Model3DGroup group = new Model3DGroup();group.Children.Add(model3D);group.Children.Add(new AmbientLight(Colors.White));ModelVisual3D visual = new ModelVisual3D();visual.Content = group;viewport3D.Children.Add(visual);
}

THE CAMERA POSITION

The camera has to be some distance away from the square, so that everything is within the camera’s field of view. Especially when the image is rotated by 90˚ around the y-axis, where it’s nearest to the camera. So how do we calculate the distance?

The sketch above shows the image which has already been rotated by 90˚. Let’s first look at the left side of the sketch. As we can see the camera is positioned . We’re going to calculate x using tangent.

Now if we put the camera at  it’s garanteed that everything is visible in the viewport. But as we can see in the sketch above, there’s space below and above (as well as left and right) the original unrotated image (space marked with variable s) which will make the image appear smaller in the viewport. We have to enlarge the viewport, so that the image will appear normal-sized again. We can calculate s as follows:

Now we have made all calculations, we can (finally) transform everything into code:

// C# code
private void PositionCamera() {double radius = 129 / 2.0; // 64.5// Calculate 3D cam position for flip animationdouble x = radius / Math.Tan(degToRad(45 / 2.0));cam3D.Position = new Point3D(0, 0, x + radius);// Add border for flip animationdouble s = radius * Math.Tan(degToRad(45 / 2.0));viewport3D.Height = viewport3D.Width = 2 * radius + 2 * s;
}private void Window_Loaded(object sender, RoutedEventArgs e) {BuildModel();PositionCamera();
}private double degToRad(double deg) {return deg / 180 * Math.PI;
}

The degToRad function is needed, because C#’s Trigonometry only takes radian angles.

THE ANIMATION

Now that we have painstakingly set up our beautiful 3D scene, we can finally animate it!

// C# code
public void Flip() {// RotateAxisAngleRotation3D rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0);model3D.Transform = new RotateTransform3D(rotation, new Point3D(0, 0, 0));DoubleAnimation flipAnimation = new DoubleAnimation(0, 180, new Duration(TimeSpan.FromMilliseconds(1000)));/* To flip back just swap 0 and 180 ;) */// Do magic!rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, flipAnimation);
}

Try it out! What a glorious effect! Once you saw it, you can’t seem to stop starting the animation over and over again.

转载于:https://www.cnblogs.com/itelite/p/4704159.html

Flipping elements with WPF相关推荐

  1. 如何在Revit中引入WPF界面(通俗易懂)

    欢迎加入BIM行业开发交流1群 群号:711844216(满),二群群号:1016453207 背景 小伙伴们在做revit二次开发时,为了丰富开发内容,会有引入界面的需求.作为窗体程序开发,基本上有 ...

  2. Transparent Windows in WPF

    转自 http://blogs.msdn.com/b/dwayneneed/archive/2008/09/08/transparent-windows-in-wpf.aspx Introductio ...

  3. 分享Silverlight/WPF/Windows Phone一周学习导读(10月1日-10月15日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月1日-10月15日) 本周Silverlight学习资源更新: [Silverlight入门系列]ListboxIte ...

  4. WPF入门知识(学习)

    WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知识(或者其他.NET支持的语言):这个是当然的了,虽 ...

  5. [转] 使用模板自定义 WPF 控件

      [转] 使用模板自定义 WPF 控件                                                                                 ...

  6. WPF 3D中多个模型如何设置某一个在最前?

    原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...

  7. listbox wpf 取消边框_停止使用箭头C#WPF导航列表框(Stop listbox from navigating with arrows C# WPF)...

    停止使用箭头C#WPF导航列表框(Stop listbox from navigating with arrows C# WPF) 我有一个画布,可以使用箭头键移动元素,但是当我在列表框中选择当前在画 ...

  8. TemplateBinding与Binding区别,以及WPF自定义控件开发的遭遇

    在上一次的文章WPF OnApplyTemplate 不执行 或者执行滞后的疑惑谈到怎么正确的开发自定义控件,我们控件的样式中,属性的绑定一般都是用TemplateBinding来完成,如下一个基本的 ...

  9. wpf office 菜单_如何带回Office 2007中的旧菜单

    wpf office 菜单 Using the new Ribbon feature in Office 2007 takes time to learn-time you don't have be ...

最新文章

  1. 新一轮光伏电站产能过剩隐忧初显
  2. 面向对象基础知识01
  3. c#将十进制转64进制
  4. 如何验证python的下载安装_如何下载python并正确安装
  5. java中存在对多个对象加锁的情况_Java对象锁和类锁全面解析(多线程synchronized关键字)...
  6. kolla all-in-one 安装
  7. htcvr设备计算机配置,VR对电脑配置要求高吗?HTC Vive电脑配置要求
  8. 读书笔记《React:引领未来的用户界面开发框架》
  9. Linux电源管理-Linux Regulator Framework代码分析
  10. oracle数据文件5属于孤立,system数据文件问题库起不来,当家帮忙看看
  11. 深圳最最最牛逼的 IT 公司全在这了!
  12. 图论(Tarjan算法与无向图)
  13. 3D游戏编程与设计作业02
  14. linux中文件权限为d-rwxr-xr,Linux基础知识之文件权限详解
  15. PDF怎么加页码?PDF添加页码的方法
  16. 微软消息队列-MSMQ
  17. POI导出execle javaweb
  18. window系统使用ssh连接远程服务器
  19. 机器学习 python
  20. ubuntu右键点击没有新建文档_苹果鼠标右键无法新建txt文档?iRightMouse :超级右键鼠标辅助工具...

热门文章

  1. 对象序列化与反序列化(二进制 byte[])
  2. Object []转换为double []
  3. IBM MQ 7.1在windows和linux上安装
  4. Android开发笔记(九)特别的.9图片
  5. c语言程序100例第4题 参考了参考答案
  6. 云时代架构读后感(十六)
  7. 栈的应用 - 就近匹配
  8. PhpStorm下Laravel代码智能提示
  9. sql 从一张表修改另一张表
  10. 用VBScript实现Zip压缩目录中的所有文件