WPF案例(-)模拟Windows7 Win+Tab切换
原文:WPF案例(-)模拟Windows7 Win+Tab切换
一个使用Wpf模拟Windows7 Win+Tab页面切换的小程序,使用快捷键Ctrl+Down或Ctrl+Up在示例程序各个页面元素之间滑动导航,在本例中,使用Viewport2DVisual3D宿主二维控件,在这里为方便示例,二维控件仅简单的使用了一个Image,以下是界面缩略图,有兴趣的朋友可以下载源码
在建立本示例中的三维场景时,使用了Viewport3D,PerspectiveCamera,AmbientLight,Viewport2DVisual3D,RotateTransform3D,TranslateTransform3D,ScaleTransform3D等元素,下面分别简单说明一下这些元素在三维场景中分别充当了什么角色
1.Viewport3D :Viewport3D是一个2D可视化元素,它是在2D场景中封装3D元素的容器控件,具有两个重要的属性
public Camera Camera { get; set; }public Visual3DCollection Children { get; }
Camera 为3D场景指定观察者所处的位置
Children 表示Viewport3D的所有3D子控件的集合类
2.PerspectiveCamera 表示透视投影摄像机,在本示例中使用它对3D场景进行透视投影
3.AmbientLight 灯光用来照亮3D场景
4.Viewport2DVisual3D 在3D场景中呈现可交互的2D控件,在本示例中就使用了6个Viewport2DVisual3D元素分别呈现了六幅Image
5.RotateTransform3D 对3D元素应用旋转,本示例中使用它对Viewport2DVisual3D进行Y轴45度旋转的模型变换
6.TranslateTransform3D 对3D元素应用平移,本示例中使用它对Viewport2DVisual3D分别进行X,Y,Z平移的模型变换
7.ScaleTransform3D 对3D元素应用拉伸缩放,本示例中使用它对Viewport2DVisual3D进行了X,Y的拉伸模型变换
以下为定义3D场景的XAML代码
2 <Viewport3D.Camera>
3 <PerspectiveCamera Position="0,0,8" />
4 </Viewport3D.Camera>
5 <Viewport2DVisual3D x:Name="viewport2DVisual3D0" Geometry="{StaticResource geometry}"
6 <Viewport2DVisual3D.Transform>
7 <Transform3DGroup>
8 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
9 <RotateTransform3D.Rotation>
10 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
11 </RotateTransform3D.Rotation>
12 </RotateTransform3D>
13 <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
14 <ScaleTransform3D CenterX="0" CenterY="0"
15 </Transform3DGroup>
16 </Viewport2DVisual3D.Transform>
17 <Viewport2DVisual3D.Visual>
18 <Image Source="Images\051027nature01.jpg" Stretch="Fill"
19 </Viewport2DVisual3D.Visual>
20 </Viewport2DVisual3D>
21 <Viewport2DVisual3D x:Name="viewport2DVisual3D1" Geometry="{StaticResource geometry}"
22 <Viewport2DVisual3D.Transform>
23 <Transform3DGroup>
24 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
25 <RotateTransform3D.Rotation>
26 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
27 </RotateTransform3D.Rotation>
28 </RotateTransform3D>
29 <TranslateTransform3D OffsetX="-1" OffsetY="1" OffsetZ="-4"/>
30 <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
31 </Transform3DGroup>
32 </Viewport2DVisual3D.Transform>
33 <Viewport2DVisual3D.Visual>
34 <Image Source="Images\051027nature02.jpg" Stretch="Fill"
35 </Viewport2DVisual3D.Visual>
36 </Viewport2DVisual3D>
37 <Viewport2DVisual3D x:Name="viewport2DVisual3D2" Geometry="{StaticResource geometry}"
38 <Viewport2DVisual3D.Transform>
39 <Transform3DGroup>
40 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
41 <RotateTransform3D.Rotation>
42 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
43 </RotateTransform3D.Rotation>
44 </RotateTransform3D>
45 <TranslateTransform3D OffsetX="-2" OffsetY="1.5" OffsetZ="-8"/>
46 <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
47 </Transform3DGroup>
48 </Viewport2DVisual3D.Transform>
49 <Viewport2DVisual3D.Visual>
50 <Image Source="Images\11550549.jpg" Stretch="Fill"
51 </Viewport2DVisual3D.Visual>
52 </Viewport2DVisual3D>
53 <Viewport2DVisual3D x:Name="viewport2DVisual3D3" Geometry="{StaticResource geometry}"
54 <Viewport2DVisual3D.Transform>
55 <Transform3DGroup>
56 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
57 <RotateTransform3D.Rotation>
58 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
59 </RotateTransform3D.Rotation>
60 </RotateTransform3D>
61 <TranslateTransform3D OffsetX="-3" OffsetY="1.5" OffsetZ="-12"/>
62 <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
63 </Transform3DGroup>
64 </Viewport2DVisual3D.Transform>
65 <Viewport2DVisual3D.Visual>
66 <Image Source="Images\11550556.jpg" Stretch="Fill"
67 </Viewport2DVisual3D.Visual>
68 </Viewport2DVisual3D>
69 <Viewport2DVisual3D x:Name="viewport2DVisual3D4" Geometry="{StaticResource geometry}"
70 <Viewport2DVisual3D.Transform>
71 <Transform3DGroup>
72 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
73 <RotateTransform3D.Rotation>
74 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
75 </RotateTransform3D.Rotation>
76 </RotateTransform3D>
77 <TranslateTransform3D OffsetX="-4" OffsetY="1.5" OffsetZ="-16"/>
78 <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
79 </Transform3DGroup>
80 </Viewport2DVisual3D.Transform>
81 <Viewport2DVisual3D.Visual>
82 <Image Source="Images\11550560.jpg" Stretch="Fill"
83 </Viewport2DVisual3D.Visual>
84 </Viewport2DVisual3D>
85 <Viewport2DVisual3D x:Name="viewport2DVisual3D5" Geometry="{StaticResource geometry}"
86 <Viewport2DVisual3D.Transform>
87 <Transform3DGroup>
88 <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
89 <RotateTransform3D.Rotation>
90 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
91 </RotateTransform3D.Rotation>
92 </RotateTransform3D>
93 <TranslateTransform3D OffsetX="-5" OffsetY="1.5" OffsetZ="-20"/>
94 <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
95 </Transform3DGroup>
96 </Viewport2DVisual3D.Transform>
97 <Viewport2DVisual3D.Visual>
98 <Image Source="Images\051123Webshots05.jpg" Stretch="Fill"
99 </Viewport2DVisual3D.Visual>
100 </Viewport2DVisual3D>
101 <ModelVisual3D>
102 <ModelVisual3D.Content>
103 <AmbientLight Color="White" />
104 </ModelVisual3D.Content>
105 </ModelVisual3D>
106 </Viewport3D>
通过以上的XAML语言定义了一个静态的3D场景,以下的代码实现将此3D场景支持动画效果,即模仿Windows7的Win+Tab切换特效
2 {
3 //向前移动,取Viewport3D的第一个Viewport2DVisual3为当前Viewport2DVisual3D
4 var current = this.Viewport3D.Children[0];
5 var child1 = this.Viewport3D.Children[1];
6 var child2 = this.Viewport3D.Children[2];
7 var child3 = this.Viewport3D.Children[3];
8 var child4 = this.Viewport3D.Children[4];
9 var child5 = this.Viewport3D.Children[5];
10
11
12 this.Viewport3D.Children.RemoveAt(0);
13 this.Viewport3D.Children.Insert(5, current);
14
15 var translate = (current.Transform as Transform3DGroup).Children[1]
16
17 //对每个Viewport2DVisual3D元素应用平移动画
18 AnimationVisualElement((current as Viewport2DVisual3D).Visual
19 AnimationVisualElement(translate, true, -5.0, 1.5, -20.0);
20
21 translate = (child1.Transform as Transform3DGroup).Children[1]
22 AnimationVisualElement(translate, true, .0, .0, .0);
23
24 translate = (child2.Transform as Transform3DGroup).Children[1]
25 AnimationVisualElement(translate, true, -1.0, 1.0, -4.0);
26
27 translate = (child3.Transform as Transform3DGroup).Children[1]
28 AnimationVisualElement(translate, true, -2.0, 1.5, -8.0);
29
30 translate = (child4.Transform as Transform3DGroup).Children[1]
31 AnimationVisualElement(translate, true, -3.0, 1.5, -12.0);
32
33 translate = (child5.Transform as Transform3DGroup).Children[1]
34 AnimationVisualElement(translate, true, -4.0, 1.5, -16.0);
35
36 }
37
38 public void MoveCurrentToPrevious()
39 {
40 //向后移动,取Viewport3D的最后一个Viewport2DVisual3D当前Viewport2DVisual3D
41 var current = this.Viewport3D.Children[5];
42 var child1 = this.Viewport3D.Children[0];
43 var child2 = this.Viewport3D.Children[1];
44 var child3 = this.Viewport3D.Children[2];
45 var child4 = this.Viewport3D.Children[3];
46 var child5 = this.Viewport3D.Children[4];
47
48 this.Viewport3D.Children.RemoveAt(5);
49 this.Viewport3D.Children.Insert(0, current);
50
51 var translate = (current.Transform as Transform3DGroup).Children[1]
52
53 AnimationVisualElement(translate, false, 0.0, 0.0, 0.0);
55
56 translate = (child1.Transform as Transform3DGroup).Children[1]
57 AnimationVisualElement(translate, false, -1.0, 1.0, -4.0);
58
59 translate = (child2.Transform as Transform3DGroup).Children[1]
60 AnimationVisualElement(translate, false, -2.0, 1.5, -8.0);
61
62 translate = (child3.Transform as Transform3DGroup).Children[1]
63 AnimationVisualElement(translate, false, -3.0, 1.5, -12.0);
64
65 translate = (child4.Transform as Transform3DGroup).Children[1]
66 AnimationVisualElement(translate, false, -4.0, 1.5, -16.0);
67
68 translate = (child5.Transform as Transform3DGroup).Children[1]
69 AnimationVisualElement(translate, false, -5.0, 1.5, -20.0);
70 }
71 private void AnimationVisualElement(FrameworkElement element, double duration)
72 {
73 if (element == null)
74 return;
75 //对Visual元素的Visibility应用动画
76 ObjectAnimationUsingKeyFrames objectAnimation = new ObjectAnimationUsingKeyFrames();
77 objectAnimation.KeyFrames.Add(
78 objectAnimation.KeyFrames.Add(
79 objectAnimation.Duration = TimeSpan.FromSeconds(duration);
80 objectAnimation.FillBehavior = FillBehavior.Stop;
81 element.BeginAnimation(FrameworkElement.VisibilityProperty, objectAnimation);
82
83 }
84 private void AnimationVisualElement(TranslateTransform3D translate, bool forward,
85 {
86 Duration duration = new Duration(TimeSpan.FromSeconds(.4));
87 //对TranslateTransform3D的X偏移量应用动画
88 DoubleAnimation animationX = new DoubleAnimation();
89 animationX.To = targetX;
90 animationX.Duration = duration;
91 animationX.AccelerationRatio = forward ? 0 : 1;
92 animationX.DecelerationRatio = forward ? 1 : 0;
93 translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, animationX);
94 //对TranslateTransform3D的Y偏移量应用动画
95 DoubleAnimation animationY = new DoubleAnimation();
96 animationX.To = targetY;
97 animationX.AccelerationRatio = forward ? 0.7 : 0.3;
98 animationX.DecelerationRatio = forward ? 0.3 : 0.7;
99 animationX.Duration = duration;
100 translate.BeginAnimation(TranslateTransform3D.OffsetYProperty, animationX);
101 //对TranslateTransform3D的Z偏移量应用动画
102 DoubleAnimation animationZ = new DoubleAnimation();
103 animationZ.To = targetZ;
104 animationZ.AccelerationRatio = forward ? 0.3 : 0.7;
105 animationZ.DecelerationRatio = forward ? 0.7 : 0.3;
106 animationZ.Duration = duration;
107 translate.BeginAnimation(TranslateTransform3D.OffsetZProperty, animationZ);
108 }
在以上代码中主要实现了对ViewPort3D的6个子Viewport2DVisual3D分别应用TranslateTransform3D的平移动画,TranslateTransform3D具有三个跟位置有关的属性,分别表示X轴偏移量OffsetX,Y轴偏移量OffsetY,以及Z轴偏移量OffsetZ
由于OffsetX,OffsetY,OffsetY在TranslateTransform3D中被定义为Double类型的依赖项属性,因此可以使用DoubleAnimation对属性的目标值定义动画效果,最后通过TranslateTransform3D的BeginAnimation方法分别对OffsetX,OffsetY,OffsetY属性应用动画
最后定义快捷键事件,按下Ctrl+Down组合键,图片向前滑动,按下Ctrl+Up组合键,图片向后滑动
2 {
3 if (e.KeyStates == Keyboard.GetKeyStates(Key.Down) &&
4 Keyboard.Modifiers == ModifierKeys.Control)
5 {
6 //向前移动Visual元素
7 this.MoveCurrentToNext();
8 }
9 else if (e.KeyStates == Keyboard.GetKeyStates(Key.Up) &&
10 Keyboard.Modifiers == ModifierKeys.Control)
11 {
12 //向后移动Visual元素
13 this.MoveCurrentToPrevious();
14 }
15 else if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape))
16 {
17 //注销
18 Application.Current.Shutdown();
19 }
20 }
注:在本示例中连续使用了6个Viewport2DVisual3D三维元素,并且在每个Viewport2DVisual3D元素的Visual上宿主一个二维的Image控件,对于本示例,为优化性能,应尽可能的减少Viewport2DVisual3D的数目,在这里一个好的方法是使用三维元素ModelVisual3D来代替Viewport2DVisual3D,将六幅图片分别定义成Material,再将Material应用到六个对应的GeometryModel3D三维模型中,最后使用Model3DGroup将六个GeometryModel3D三维模型打包作为ModelVisual3D的Content属性值,因此只需要一个ModelVisual3D就可实现相同的功能并能优化了性能
WPF案例(-)模拟Windows7 Win+Tab切换的更多相关文章
- WPF案例 (四) 模拟Windows7桌面任务栏
原文:WPF案例 (四) 模拟Windows7桌面任务栏 这个程序模彷了Windows7的桌面任务栏,当在桌面上双击某个快捷方式时,将打开一个新的子界面,并且在任务栏里创建一个链接到此界面的任务栏图标 ...
- WPF案例 (三) 模拟QQ“快速换装"界面
原文:WPF案例 (三) 模拟QQ"快速换装"界面 这个小程序使用Wpf模拟QQ快速换装页面的动画特效,通过使用组合快捷键Ctrl+Left或Ctrl+Right,可实现Image ...
- WPF案例 (六) 动态切换UI布局
原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...
- WPF案例(二)模拟Apple OS 界面前后180度反转
原文:WPF案例(二)模拟Apple OS 界面前后180度反转 我们在设计应用程序界面的时候,为了充分利用界面空间,住住需要灵活的界面布局方式,比如可以在界面正面空间上定义一个Chart,背面空间上 ...
- Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...
- Angular——tab切换案例
基本介绍 angular框架下的tab切换,相比较于之前的纯js写的代码,有一个很大的特点就是以数据为驱动,基本上不用搜索dom元素就可以实现效果 基本使用 (1)导航部分使用的是的状态使用的是ng- ...
- tab切换案例
做个简单的tab切换效果,分别于jquery和js操作 (1)jQuery操作 先看下效果: <!DOCTYPE html> <html lang="en"> ...
- 案例(拖拽对话框、高清放大镜、自制滚动条、元素的隐藏方式、表格隔行变色、tab切换效果、字符串拼接、刷新评论)
一.拖拽对话框 <style> .of{ width: 500px; } #link,#close{ text-decoration: none; margin: 0 10px; font ...
- 基于zepto的H5/移动端tab切换触摸拖动加载更多数据
以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很 ...
随机推荐
- EasyUI - SplitButton 分割按钮
效果: html代码: <!--使用标签创建,直接使用即可,不必使用js代码--> <%--<a href="javascript:void(0)" id= ...
- html5的自定义data-*属性和jquery的data()方法的使用
人们总喜欢往HTML标签上添加自定义属性来存储和操作数据.但这样做的问题是,你不知道将来会不会有其它脚本把你的自定义属性给重置掉,此外,你这样做也会导致html语法上不符合Html规范,以及一些其它副 ...
- 第五天学习内容 for循环,嵌套
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- 构建基于Jenkins + Github的持续集成环境
搭建持续集成首先要了解什么是持续集成,带着明确的目标去搭建持续集成环境才能让我们少走很多弯路.持续集成(Continuous integration)简称CI,是一种软件开发的实践,可以让团队在持续集 ...
- 【ASP.NET Web API教程】2.3.4 创建Admin视图
原文:[ASP.NET Web API教程]2.3.4 创建Admin视图 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. Part 4: ...
- 开始翻译Windows Phone 8 Development for Absolute Beginners教程
Bob Tabor (LearnVisualStudio.NET)和Clint Rutkas (Microsoft/Channel9)合作推出了超过11小时的针对初学者的Windows Phone 8 ...
- 手机字段存储报错 :Warning Code : 1264 Out of range value for column 'buyer_tpl' at row 1
企鹅上朋友问我: 我这明明是11位的int 为啥还说超出范围了呢,然后发来报警截图 我看到是 buyer_tpl int(13) unsigned NOT NULL,就知道是怎么回事了,打开dev. ...
- asp.net mvc 导出表格
适合使用的场合: .net 中从前台中的table导出成excel文件,兼容各种浏览器. 使用工具: org.in2bits.MyXls.dll 从前台获取表格的thead和表格的tbody,将其转化 ...
- bootstrap之WaitForIdle&&Clear
(上篇文章写完才发现.说好的按顺序可是回头一看全然不是按顺序的)明明WaitForIdle才是第一个.哎,老了,后脑勺不行了. WaitForIdle package io.appium.androi ...
- 编译android-4.3.1_r源代码并刷到自己的Galaxy Nexus I9250真机上
编译android-4.3.1_r源代码并刷到自己的Galaxy Nexus I9250真机上 作者:雨水 日期:2014-04-30 编译源码的目的还是为了自己改动源码,然后还可以执行在相应的手机 ...