WPF案例 (三) 模拟QQ“快速换装"界面
这个小程序使用Wpf模拟QQ快速换装页面的动画特效,通过使用组合快捷键Ctrl+Left或Ctrl+Right,可实现Image平滑的向左或者向右滑动,页面如下,有兴趣的朋友可以下载源码
在构建这个示例的3D场景时,使用了ModelVisual3D和Model3DGroup元素,ModelVisual3D是一个3D容器类,用来包含3D元素,在这里使用Model3DGroup打包了3个GeometryModel3D,每个GeometryModel3D的Materia各填充了一幅Image,将
3D场景
1 <Viewport3D x:Name="viewPort3D" RenderOptions.EdgeMode="Aliased" ClipToBounds="False">
2 <Viewport3D.Camera>
3 <PerspectiveCamera Position="0,0,8" />
4 </Viewport3D.Camera>
5 <ModelVisual3D>
6 <ModelVisual3D.Content>
7 <AmbientLight Color="White"/>
8 </ModelVisual3D.Content>
9 </ModelVisual3D>
10 <ModelVisual3D >
11 <ModelVisual3D.Content>
12 <Model3DGroup x:Name="model3DGroup">
13 <Model3DGroup.Children>
14 <GeometryModel3D x:Name="center" Geometry="{StaticResource Geometry}" >
15 <GeometryModel3D.Transform>
16 <Transform3DGroup>
17 <RotateTransform3D>
18 <RotateTransform3D.Rotation>
19 <AxisAngleRotation3D Axis="0,1,0" Angle="0"/>
20 </RotateTransform3D.Rotation>
21 </RotateTransform3D>
22 <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0.5" />
23 </Transform3DGroup>
24 </GeometryModel3D.Transform>
25 <GeometryModel3D.Material>
26 <DiffuseMaterial>
27 <DiffuseMaterial.Brush>
28 <ImageBrush ImageSource="Images\051123Webshots05.jpg"/>
30 </DiffuseMaterial.Brush>
31 </DiffuseMaterial>
32 </GeometryModel3D.Material>
33 </GeometryModel3D>
34 <GeometryModel3D x:Name="right" Geometry="{StaticResource Geometry}" >
35 <GeometryModel3D.Transform>
36 <Transform3DGroup>
37 <RotateTransform3D>
38 <RotateTransform3D.Rotation>
39 <AxisAngleRotation3D Axis="0,1,0" Angle="-45"/>
40 </RotateTransform3D.Rotation>
41 </RotateTransform3D>
42 <TranslateTransform3D OffsetX="1.8" OffsetY="0" OffsetZ="-2.5" />
43 </Transform3DGroup>
44 </GeometryModel3D.Transform>
45 <GeometryModel3D.Material>
46 <DiffuseMaterial>
47 <DiffuseMaterial.Brush>
48 <ImageBrush ImageSource="Images\051027nature02.jpg"/>
49 </DiffuseMaterial.Brush>
50 </DiffuseMaterial>
51 </GeometryModel3D.Material>
52 </GeometryModel3D>
53 <GeometryModel3D x:Name="left" Geometry="{StaticResource Geometry}" >
54 <GeometryModel3D.Transform>
55 <Transform3DGroup>
56 <RotateTransform3D>
57 <RotateTransform3D.Rotation>
58 <AxisAngleRotation3D Axis="0,1,0" Angle="45"/>
59 </RotateTransform3D.Rotation>
60 </RotateTransform3D>
61 <TranslateTransform3D OffsetX="-1.8" OffsetY="0" OffsetZ="-2.5" />
62 </Transform3DGroup>
63 </GeometryModel3D.Transform>
64 <GeometryModel3D.Material>
65 <DiffuseMaterial>
66 <DiffuseMaterial.Brush>
67 <ImageBrush ImageSource="Images\051027nature01.jpg"/>
68 </DiffuseMaterial.Brush>
69 </DiffuseMaterial>
70 </GeometryModel3D.Material>
71 </GeometryModel3D>
72 </Model3DGroup.Children>
73 </Model3DGroup>
74 </ModelVisual3D.Content>
75 </ModelVisual3D>
76 </Viewport3D>
2 <Viewport3D.Camera>
3 <PerspectiveCamera Position="0,0,8" />
4 </Viewport3D.Camera>
5 <ModelVisual3D>
6 <ModelVisual3D.Content>
7 <AmbientLight Color="White"/>
8 </ModelVisual3D.Content>
9 </ModelVisual3D>
10 <ModelVisual3D >
11 <ModelVisual3D.Content>
12 <Model3DGroup x:Name="model3DGroup">
13 <Model3DGroup.Children>
14 <GeometryModel3D x:Name="center" Geometry="{StaticResource Geometry}" >
15 <GeometryModel3D.Transform>
16 <Transform3DGroup>
17 <RotateTransform3D>
18 <RotateTransform3D.Rotation>
19 <AxisAngleRotation3D Axis="0,1,0" Angle="0"/>
20 </RotateTransform3D.Rotation>
21 </RotateTransform3D>
22 <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0.5" />
23 </Transform3DGroup>
24 </GeometryModel3D.Transform>
25 <GeometryModel3D.Material>
26 <DiffuseMaterial>
27 <DiffuseMaterial.Brush>
28 <ImageBrush ImageSource="Images\051123Webshots05.jpg"/>
30 </DiffuseMaterial.Brush>
31 </DiffuseMaterial>
32 </GeometryModel3D.Material>
33 </GeometryModel3D>
34 <GeometryModel3D x:Name="right" Geometry="{StaticResource Geometry}" >
35 <GeometryModel3D.Transform>
36 <Transform3DGroup>
37 <RotateTransform3D>
38 <RotateTransform3D.Rotation>
39 <AxisAngleRotation3D Axis="0,1,0" Angle="-45"/>
40 </RotateTransform3D.Rotation>
41 </RotateTransform3D>
42 <TranslateTransform3D OffsetX="1.8" OffsetY="0" OffsetZ="-2.5" />
43 </Transform3DGroup>
44 </GeometryModel3D.Transform>
45 <GeometryModel3D.Material>
46 <DiffuseMaterial>
47 <DiffuseMaterial.Brush>
48 <ImageBrush ImageSource="Images\051027nature02.jpg"/>
49 </DiffuseMaterial.Brush>
50 </DiffuseMaterial>
51 </GeometryModel3D.Material>
52 </GeometryModel3D>
53 <GeometryModel3D x:Name="left" Geometry="{StaticResource Geometry}" >
54 <GeometryModel3D.Transform>
55 <Transform3DGroup>
56 <RotateTransform3D>
57 <RotateTransform3D.Rotation>
58 <AxisAngleRotation3D Axis="0,1,0" Angle="45"/>
59 </RotateTransform3D.Rotation>
60 </RotateTransform3D>
61 <TranslateTransform3D OffsetX="-1.8" OffsetY="0" OffsetZ="-2.5" />
62 </Transform3DGroup>
63 </GeometryModel3D.Transform>
64 <GeometryModel3D.Material>
65 <DiffuseMaterial>
66 <DiffuseMaterial.Brush>
67 <ImageBrush ImageSource="Images\051027nature01.jpg"/>
68 </DiffuseMaterial.Brush>
69 </DiffuseMaterial>
70 </GeometryModel3D.Material>
71 </GeometryModel3D>
72 </Model3DGroup.Children>
73 </Model3DGroup>
74 </ModelVisual3D.Content>
75 </ModelVisual3D>
76 </Viewport3D>
对3D场景使用动画其实就是对3D场景中的基本基元的依赖项属性使用动画,这些依赖项属性中最常用的就是跟3D模型变换相关的三个元素TranslateTransform3D、
C#动画
1 public void MoveCurrentToNext()
2 {
3 //这里是向右滑动,取位于中间位置的GeometryModel3D为当前的GeometryModel3D
4 var current = this.model3DGroup.Children[0] as GeometryModel3D;
5 var left = this.model3DGroup.Children[2] as GeometryModel3D;
6 var right = this.model3DGroup.Children[1] as GeometryModel3D;
7 this.model3DGroup.Children.RemoveAt(0);
8 this.model3DGroup.Children.Add(current);
9
10 //下面分别对GeometryModel3D的TranslateTransform3D,RotateTransform3D元素应用动画
11 var transform3DGroup = right.Transform as Transform3DGroup;
12
13 var translate = transform3DGroup.Children[1] as TranslateTransform3D;
14 var rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
15 as AxisAngleRotation3D;
16 AnimationVisualElement(translate, rotate, 0, 0, 0, 0, true);
17
18
19 transform3DGroup = current.Transform as Transform3DGroup;
20
21 translate = transform3DGroup.Children[1] as TranslateTransform3D;
22 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
23 as AxisAngleRotation3D;
24 AnimationVisualElement(translate, rotate, -1.8, 0, -2.5, 45, true);
25
26 transform3DGroup = left.Transform as Transform3DGroup;
27
28 translate = transform3DGroup.Children[1] as TranslateTransform3D;
29 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
30 as AxisAngleRotation3D;
31 AnimationVisualElement(translate, rotate, 1.8, 0, -2.5, -45, true);
32
33 }
34
35 public void MoveCurrentToPrevious()
36 {
37 //向左滑动。取位于左边位置的GeometryModel3D为当前的GeometryModel3D
38 var current = this.model3DGroup.Children[2] as GeometryModel3D;
39 var center = this.model3DGroup.Children[0] as GeometryModel3D;
40 var right = this.model3DGroup.Children[1] as GeometryModel3D;
41 this.model3DGroup.Children.RemoveAt(2);
42 this.model3DGroup.Children.Insert(0, current);
43
44 //下面分别对GeometryModel3D的TranslateTransform3D,RotateTransform3D元素应用动画
45 var transform3DGroup = center.Transform as Transform3DGroup;
46
47 var translate = transform3DGroup.Children[1] as TranslateTransform3D;
48 var rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
49 as AxisAngleRotation3D;
50
51 AnimationVisualElement(translate, rotate, 1.8, 0, -2.5, -45, true);
52
53 transform3DGroup = current.Transform as Transform3DGroup;
54
55 translate = transform3DGroup.Children[1] as TranslateTransform3D;
56 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
57 as AxisAngleRotation3D;
58 AnimationVisualElement(translate, rotate, 0, 0, 0, 0, true);
59
60 transform3DGroup = right.Transform as Transform3DGroup;
61
62 translate = transform3DGroup.Children[1] as TranslateTransform3D;
63 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
64 as AxisAngleRotation3D;
65 AnimationVisualElement(translate, rotate, -1.8, 0, -2.5, 45, true);
66 }
67 private void AnimationVisualElement(TranslateTransform3D translate,
2 {
3 //这里是向右滑动,取位于中间位置的GeometryModel3D为当前的GeometryModel3D
4 var current = this.model3DGroup.Children[0] as GeometryModel3D;
5 var left = this.model3DGroup.Children[2] as GeometryModel3D;
6 var right = this.model3DGroup.Children[1] as GeometryModel3D;
7 this.model3DGroup.Children.RemoveAt(0);
8 this.model3DGroup.Children.Add(current);
9
10 //下面分别对GeometryModel3D的TranslateTransform3D,RotateTransform3D元素应用动画
11 var transform3DGroup = right.Transform as Transform3DGroup;
12
13 var translate = transform3DGroup.Children[1] as TranslateTransform3D;
14 var rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
15 as AxisAngleRotation3D;
16 AnimationVisualElement(translate, rotate, 0, 0, 0, 0, true);
17
18
19 transform3DGroup = current.Transform as Transform3DGroup;
20
21 translate = transform3DGroup.Children[1] as TranslateTransform3D;
22 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
23 as AxisAngleRotation3D;
24 AnimationVisualElement(translate, rotate, -1.8, 0, -2.5, 45, true);
25
26 transform3DGroup = left.Transform as Transform3DGroup;
27
28 translate = transform3DGroup.Children[1] as TranslateTransform3D;
29 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
30 as AxisAngleRotation3D;
31 AnimationVisualElement(translate, rotate, 1.8, 0, -2.5, -45, true);
32
33 }
34
35 public void MoveCurrentToPrevious()
36 {
37 //向左滑动。取位于左边位置的GeometryModel3D为当前的GeometryModel3D
38 var current = this.model3DGroup.Children[2] as GeometryModel3D;
39 var center = this.model3DGroup.Children[0] as GeometryModel3D;
40 var right = this.model3DGroup.Children[1] as GeometryModel3D;
41 this.model3DGroup.Children.RemoveAt(2);
42 this.model3DGroup.Children.Insert(0, current);
43
44 //下面分别对GeometryModel3D的TranslateTransform3D,RotateTransform3D元素应用动画
45 var transform3DGroup = center.Transform as Transform3DGroup;
46
47 var translate = transform3DGroup.Children[1] as TranslateTransform3D;
48 var rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
49 as AxisAngleRotation3D;
50
51 AnimationVisualElement(translate, rotate, 1.8, 0, -2.5, -45, true);
52
53 transform3DGroup = current.Transform as Transform3DGroup;
54
55 translate = transform3DGroup.Children[1] as TranslateTransform3D;
56 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
57 as AxisAngleRotation3D;
58 AnimationVisualElement(translate, rotate, 0, 0, 0, 0, true);
59
60 transform3DGroup = right.Transform as Transform3DGroup;
61
62 translate = transform3DGroup.Children[1] as TranslateTransform3D;
63 rotate = (transform3DGroup.Children[0] as RotateTransform3D).Rotation
64 as AxisAngleRotation3D;
65 AnimationVisualElement(translate, rotate, -1.8, 0, -2.5, 45, true);
66 }
67 private void AnimationVisualElement(TranslateTransform3D translate,
AxisAngleRotation3D rotate,
68 double targetX, double targetY, double targetZ, double angel, bool forward)
69 {
70 Duration duration = new Duration(TimeSpan.FromSeconds(.4));
71 //对TranslateTransform3D的OffsetX属性应用动画
72 DoubleAnimation animationX = new DoubleAnimation();
73 animationX.To = targetX;
74 animationX.Duration = duration;
75 animationX.AccelerationRatio = forward ? 0 : 1;
76 animationX.DecelerationRatio = forward ? 1 : 0;
77 translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, animationX);
78 //对TranslateTransform3D的OffsetY属性应用动画
79 DoubleAnimation animationY = new DoubleAnimation();
80 animationX.To = targetY;
81 animationX.AccelerationRatio = forward ? 0.7 : 0.3;
82 animationX.DecelerationRatio = forward ? 0.3 : 0.7;
83 animationX.Duration = duration;
84 translate.BeginAnimation(TranslateTransform3D.OffsetYProperty, animationX);
85 //对TranslateTransform3D的OffsetZ属性应用动画
86 DoubleAnimation animationZ = new DoubleAnimation();
87 animationZ.To = targetZ;
88 animationZ.AccelerationRatio = forward ? 0.3 : 0.7;
89 animationZ.DecelerationRatio = forward ? 0.7 : 0.3;
90 animationZ.Duration = duration;
91 translate.BeginAnimation(TranslateTransform3D.OffsetZProperty, animationZ);
92 //对AxisAngleRotation3D的Angle属性应用动画
93 DoubleAnimation animationAngel = new DoubleAnimation();
94 animationAngel.To = angel;
95 animationAngel.AccelerationRatio = forward ? 0.3 : 0.7;
96 animationAngel.DecelerationRatio = forward ? 0.7 : 0.3;
97 animationAngel.Duration = duration;
98 rotate.BeginAnimation(AxisAngleRotation3D.AngleProperty, animationAngel);
99 }
68 double targetX, double targetY, double targetZ, double angel, bool forward)
69 {
70 Duration duration = new Duration(TimeSpan.FromSeconds(.4));
71 //对TranslateTransform3D的OffsetX属性应用动画
72 DoubleAnimation animationX = new DoubleAnimation();
73 animationX.To = targetX;
74 animationX.Duration = duration;
75 animationX.AccelerationRatio = forward ? 0 : 1;
76 animationX.DecelerationRatio = forward ? 1 : 0;
77 translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, animationX);
78 //对TranslateTransform3D的OffsetY属性应用动画
79 DoubleAnimation animationY = new DoubleAnimation();
80 animationX.To = targetY;
81 animationX.AccelerationRatio = forward ? 0.7 : 0.3;
82 animationX.DecelerationRatio = forward ? 0.3 : 0.7;
83 animationX.Duration = duration;
84 translate.BeginAnimation(TranslateTransform3D.OffsetYProperty, animationX);
85 //对TranslateTransform3D的OffsetZ属性应用动画
86 DoubleAnimation animationZ = new DoubleAnimation();
87 animationZ.To = targetZ;
88 animationZ.AccelerationRatio = forward ? 0.3 : 0.7;
89 animationZ.DecelerationRatio = forward ? 0.7 : 0.3;
90 animationZ.Duration = duration;
91 translate.BeginAnimation(TranslateTransform3D.OffsetZProperty, animationZ);
92 //对AxisAngleRotation3D的Angle属性应用动画
93 DoubleAnimation animationAngel = new DoubleAnimation();
94 animationAngel.To = angel;
95 animationAngel.AccelerationRatio = forward ? 0.3 : 0.7;
96 animationAngel.DecelerationRatio = forward ? 0.7 : 0.3;
97 animationAngel.Duration = duration;
98 rotate.BeginAnimation(AxisAngleRotation3D.AngleProperty, animationAngel);
99 }
最后定义快捷键,按下组合键Ctrl+Left或者Ctrl+Right,界面中的Image将平滑的向左或者向右切换
定义快捷键
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyStates == Keyboard.GetKeyStates(Key.Left) && Keyboard.Modifiers == ModifierKeys.Control)
{
//向左滑动图片
this.MoveCurrentToPrevious();
}
else if (e.KeyStates == Keyboard.GetKeyStates(Key.Right) && Keyboard.Modifiers == ModifierKeys.Control)
{
//向右滑动图片
this.MoveCurrentToNext();
}
}
{
if (e.KeyStates == Keyboard.GetKeyStates(Key.Left) && Keyboard.Modifiers == ModifierKeys.Control)
{
//向左滑动图片
this.MoveCurrentToPrevious();
}
else if (e.KeyStates == Keyboard.GetKeyStates(Key.Right) && Keyboard.Modifiers == ModifierKeys.Control)
{
//向右滑动图片
this.MoveCurrentToNext();
}
}