在WPF中使用PlaneProjection模拟动态3D效果
2016-01-25 11:55
381 查看
在Silverlight中,因为性能问题,一般并不使用真3D引擎,微软为Silverlight提供了System.Windows.Media.PlaneProjection 类,用投影变换来模拟3D的效果。
下面让我们看下一个 Microsoft Expression Blend 4 提供的示例 Wall3D (位于帮助>欢迎屏幕>示例)。
大家不要被这个可以流畅滚动的3D图片墙所迷惑,其实这只是一个ListBox控件。MainPage中给ListBox定义了一个ItemsPanelTemplate,使用新的控件来作为ListBox中Items的布局控件,这个
控件就是这个项目最核心的类:CircularPanel3D。
CircularPanel3D类继承自System.Windows.Controls.Panel,它实现了一种新的布局方式,效果大家在上一张图片中都看到了。这种华丽的效果实际上都是由这个最重要的类中的最重要的方法:
private void Refresh() 完成的。
1 privatevoid Refresh()
2 {
3 //几个计数器,看名字就功能很明了
4 int count =0;
5 int col =0;
6 int row =0;
7 int zLevel =0;
8
9 //开始遍历子元素
10 foreach (FrameworkElement childElement inthis.Children)
11 {
12 //AngleItem是指单个元素的旋转角度,算法是360除以列数
13 //这个方法的布局方式是先布满一圈,再下一环的,角度总是可以取模的
14 //所以这边直接AngleItem和count相乘了
15 //InitialAngle这个属性是用来确定整个圆环的偏转角度的,每次这个依赖属性变化就会重新计算布局(调用这个方法)
16 double angle = (this.AngleItem * count++) -this.InitialAngle;
17 //下面两个变量用来确定元素在屏幕上的位置,用到了三角函数,数学不好的请问高中数学老师
18 double x =this.Radius * Math.Cos(Math.PI * angle /180);
19 double z =this.Radius * Math.Sin(Math.PI * angle /180);
20 //创建个PlaneProjection对象,并赋值
21 PlaneProjection projection =new PlaneProjection();
22 if (projection !=null)
23 {
24 projection.CenterOfRotationX =0.5;
25 projection.CenterOfRotationY =0.5;
26 projection.CenterOfRotationZ =0.5;
27 projection.RotationY = angle +90;
28 projection.GlobalOffsetX = x;
29 //Distance实际上就是模拟的镜头距离
30 projection.GlobalOffsetZ = z -this.Distance;
31 //-330。。。坑爹的硬编码,实际上就是两行元素的间距,OffsetY是纵向的偏移量,用于调整环在屏幕上的位置
32 projection.GlobalOffsetY = row * (-330) +this.OffsetY;
33 }
34 //实际上是让double数变成int数,但是又不会丧失区别性,下面要用到
35 int depth = (int)(z *100);
36
37 double pDist = (this.Distance -1000) /2000;
38 double pZ = ((z +1000) /2000) +0.5;
39
40 //让太远的和太近的变透明
41 double opacity = (pZ - pDist) +0.4;
42 if (opacity >=1)
43 {
44 childElement.Opacity = (2- opacity);
45 }
46 elseif (opacity <0)
47 {
48 childElement.Opacity =0;
49 }
50 else
51 {
52 childElement.Opacity = opacity;
53 }
54
55 // 嗯这边有原版的英文注释,不解释
56 // Variable zLevel changes value of ZIndex for each item in the ListBox.
57 // This way the reflex of elements at the top will be placed behind the item below it.
58 Canvas.SetZIndex(childElement, depth-(++zLevel*10));
59
60 //根据Align属性设置对齐方式,不是很重要
61 double alignX =0;
62 double alignY =0;
63 switch (this.Align)
64 {
65 case AlignmentOptions.Left:
66 alignX =0;
67 alignY =0;
68 break;
69 case AlignmentOptions.Center:
70 alignX = childElement.DesiredSize.Width /2;
71 alignY = childElement.DesiredSize.Height /2;
72 break;
73 case AlignmentOptions.Right:
74 alignX = childElement.DesiredSize.Width;
75 alignY = childElement.DesiredSize.Height;
76 break;
77 }
78 //将PlaneProjection对象赋给子元素的Projection属性
79 childElement.Projection = projection;
80 //定位子元素
81 childElement.Arrange(new Rect(this.Width /2- alignX , this.Height /2- alignY, childElement.DesiredSize.Width, childElement.DesiredSize.Height));
82
83 //换行,又见坑爹的硬编码14。。这个代表有十四列
84 col++;
85 if (col >14)
86 {
87 col =0;
88 row++;
89 }
90 }
91 }
原文地址:http://biancheng.dnbcw.info/net/448246.html
相关文章推荐
- 选定虚拟主机 性能凸显优势
- 修改一行代码提升 Postgres 性能 100 倍
- Silverlight将图片转换为byte的实现代码
- 解析Silverlight调用WCF/Rest异常的解决方法
- 推荐Sql server一些常见性能问题的解决方法
- C#及WPF获取本机所有字体和颜色的方法
- WPF MVVM示例讲解
- WPF实现时钟特效
- 3D设计 Adobe Acrobat 3D 8.1.0 英文版 下载
- SQL Server误区30日谈 第9天 数据库文件收缩不会影响性能
- 和表值函数连接引发的性能问题分析
- SQLServer 2000 升级到 SQLServer 2008 性能之需要注意的地方之一
- 基于Silverlight打印的使用详解,是否为微软的Bug问题
- 数据库性能优化三:程序操作优化提升性能
- PowerShell中调用WPF生成炫酷窗口实例
- VBS中的字符串连接的性能问题
- mysql 性能的检查和调优方法
- 数据库性能优化二:数据库表优化提升性能
- SQL语句优化提高数据库性能
- WPF实现类似360安全卫士界面的程序源码分享