一個使用Wpf模擬Windows7 Win+Tab頁面切換的小程序,使用快捷鍵Ctrl+Down或Ctrl+Up在 示例程序各個頁面元素之間滑動導航,在本例中,使用 Viewport2DVisual3D宿主二維控件,在 這裡為方便示例,二維控件僅簡單的使用了一個Image,以下是界面縮略圖,有興趣的朋友可以 下載源碼:http://files.cnblogs.com/5460600/Aero.rar
在建立本示例中的三維場景時,使用了 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代碼
3D場景
1 <Viewport3D x:Name="Viewport3D" RenderOptions.EdgeMode="Aliased" ClipToBounds="False"
IsHitTestVisible="False">
2 <Viewport3D.Camera>
3 <PerspectiveCamera Position="0,0,8" />
4 </Viewport3D.Camera>
5 <Viewport2DVisual3D x:Name="viewport2DVisual3D0" Geometry="{StaticResource geometry}"
Material="{StaticResource material}" >
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"
CenterZ="0" ScaleX="1.5" ScaleY="1" />
15 </Transform3DGroup>
16 </Viewport2DVisual3D.Transform>
17 <Viewport2DVisual3D.Visual>
18 <Image Source="Images\051027nature01.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
19 </Viewport2DVisual3D.Visual>
20 </Viewport2DVisual3D>
21 <Viewport2DVisual3D x:Name="viewport2DVisual3D1" Geometry="{StaticResource geometry}"
Material="{StaticResource material}">
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"
ScaleX="1.5" ScaleY="1" />
31 </Transform3DGroup>
32 </Viewport2DVisual3D.Transform>
33 <Viewport2DVisual3D.Visual>
34 <Image Source="Images\051027nature02.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
35 </Viewport2DVisual3D.Visual>
36 </Viewport2DVisual3D>
37 <Viewport2DVisual3D x:Name="viewport2DVisual3D2" Geometry="{StaticResource geometry}"
Material="{StaticResource material}">
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"
ScaleX="1.5" ScaleY="1" />
47 </Transform3DGroup>
48 </Viewport2DVisual3D.Transform>
49 <Viewport2DVisual3D.Visual>
50 <Image Source="Images\11550549.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
51 </Viewport2DVisual3D.Visual>
52 </Viewport2DVisual3D>
53 <Viewport2DVisual3D x:Name="viewport2DVisual3D3" Geometry="{StaticResource geometry}"
Material="{StaticResource material}">
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"
ScaleX="1.5" ScaleY="1" />
63 </Transform3DGroup>
64 </Viewport2DVisual3D.Transform>
65 <Viewport2DVisual3D.Visual>
66 <Image Source="Images\11550556.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
67 </Viewport2DVisual3D.Visual>
68 </Viewport2DVisual3D>
69 <Viewport2DVisual3D x:Name="viewport2DVisual3D4" Geometry="{StaticResource geometry}"
Material="{StaticResource material}">
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"
ScaleX="1.5" ScaleY="1" />
79 </Transform3DGroup>
80 </Viewport2DVisual3D.Transform>
81 <Viewport2DVisual3D.Visual>
82 <Image Source="Images\11550560.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
83 </Viewport2DVisual3D.Visual>
84 </Viewport2DVisual3D>
85 <Viewport2DVisual3D x:Name="viewport2DVisual3D5" Geometry="{StaticResource geometry}"
Material="{StaticResource material}">
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"
ScaleX="1.5" ScaleY="1" />
95 </Transform3DGroup>
96 </Viewport2DVisual3D.Transform>
97 <Viewport2DVisual3D.Visual>
98 <Image Source="Images\051123Webshots05.jpg" Stretch="Fill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
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切換特效
C#動畫
1 public void MoveCurrentToNext()
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]
as TranslateTransform3D;
16
17 //對每個Viewport2DVisual3D元素應用平移動畫
18 AnimationVisualElement((current as Viewport2DVisual3D).Visual
as FrameworkElement, .3);
19 AnimationVisualElement(translate, true, -5.0, 1.5, -20.0);
20
21 translate = (child1.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
22 AnimationVisualElement(translate, true, .0, .0, .0);
23
24 translate = (child2.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
25 AnimationVisualElement(translate, true, -1.0, 1.0, -4.0);
26
27 translate = (child3.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
28 AnimationVisualElement(translate, true, -2.0, 1.5, -8.0);
29
30 translate = (child4.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
31 AnimationVisualElement(translate, true, -3.0, 1.5, -12.0);
32
33 translate = (child5.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
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]
as TranslateTransform3D;
52
53 AnimationVisualElement(translate, false, 0.0, 0.0, 0.0);
55
56 translate = (child1.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
57 AnimationVisualElement(translate, false, -1.0, 1.0, -4.0);
58
59 translate = (child2.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
60 AnimationVisualElement(translate, false, -2.0, 1.5, -8.0);
61
62 translate = (child3.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
63 AnimationVisualElement(translate, false, -3.0, 1.5, -12.0);
64
65 translate = (child4.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
66 AnimationVisualElement(translate, false, -4.0, 1.5, -16.0);
67
68 translate = (child5.Transform as Transform3DGroup).Children[1]
as TranslateTransform3D;
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(
new DiscreteObjectKeyFrame (Visibility.Collapsed, KeyTime.FromPercent(.0)));
78 objectAnimation.KeyFrames.Add(
new DiscreteObjectKeyFrame (Visibility.Visible, KeyTime.FromPercent(1)));
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,
double targetX, double targetY, double targetZ)
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組合鍵,圖片向 後滑動
定義快捷鍵
1 private void Window_KeyDown(object sender, KeyEventArgs e)
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就可實現 相同的功能並能優化了性能.