您的位置:首页 > 其它

WPF界面设计技巧(3)—实现不规则动画按钮

2008-07-15 23:17 791 查看
<Button Height="300" Width="300" Margin="-59,-57,-18,-94" Name="button1" Cursor="Hand">

<Button.Template>

<ControlTemplate>

<!--容器-->

<Canvas Height="300" Width="300">

<!--圆环-->

<Rectangle x:Name="ring" Canvas.Top="0" Canvas.Left="0" Fill="{StaticResource ring}" Height="300" Width="300" >

<Rectangle.RenderTransform>

<RotateTransform Angle="135" CenterX="150" CenterY="150"/>

</Rectangle.RenderTransform>

</Rectangle>

<!--圆形及文字-->

<Rectangle x:Name="sphericity" Canvas.Top="33" Canvas.Left="33" Fill="{StaticResource sphericity}" Height="234" Width="234">

<Rectangle.BitmapEffect>

<OuterGlowBitmapEffect GlowColor="Orange" GlowSize="0"/>

</Rectangle.BitmapEffect>

</Rectangle>

</Canvas>

<!--触发器-->

<ControlTemplate.Triggers>

<!--载入事件触发器-->

<EventTrigger RoutedEvent="FrameworkElement.Loaded">

<BeginStoryboard>

<Storyboard>

<DoubleAnimationUsingKeyFrames Duration="0:0:0.6" RepeatBehavior="Forever" Storyboard.TargetName="ring" Storyboard.TargetProperty="(Rectangle.RenderTransform).(RotateTransform.Angle)">

<DoubleAnimationUsingKeyFrames.KeyFrames>

<SplineDoubleKeyFrame KeyTime="0:0:0" Value="135" KeySpline="0.5,0,0,0.5"/>

<SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="495" KeySpline="0,0.5,0.5,0"/>

</DoubleAnimationUsingKeyFrames.KeyFrames>

</DoubleAnimationUsingKeyFrames>

</Storyboard>

</BeginStoryboard>

</EventTrigger>

<!--鼠标移入触发器-->

<Trigger Property="IsMouseOver" Value="True">

<Trigger.EnterActions>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation To="12" Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.BitmapEffect).(OuterGlowBitmapEffect.GlowSize)"/>

<ColorAnimation To="#FFEB55" Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[0].(GradientStop.Color)"/>

<ColorAnimation To="#FFC955" Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[1].(GradientStop.Color)"/>

<ColorAnimation To="#D79248" Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[2].(GradientStop.Color)"/>

</Storyboard>

</BeginStoryboard>

</Trigger.EnterActions>

<Trigger.ExitActions>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.BitmapEffect).(OuterGlowBitmapEffect.GlowSize)"/>

<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[0].(GradientStop.Color)"/>

<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[1].(GradientStop.Color)"/>

<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="sphericity" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[2].(GradientStop.Color)"/>

</Storyboard>

</BeginStoryboard>

</Trigger.ExitActions>

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</Button.Template>

</Button>

还是回过头在研究代码,先编译并运行,可以看到下图这样的界面,其中的圆环在不停的转动。



鼠标移入时圆形会变色,并且外发光:



好了,下面只讲解一下代码中需要注意的地方,重复的知识不再累述,大家可以参考先前的两篇文章。



Canvas 是一个简单的容器元素,它内部的元素以简单的坐标位置来描述。

其内部放置了两个矩形元素 Rectangle ,我们用 Rectangle 分别装载圆环和圆形及文字的图像。



通过 Rectangle.RenderTransform 属性可以对 Rectangle 的外形进行转换调整,其功能类似 Photoshop 中的“自由变换”,在这里使用 RotateTransform 来改变角度。

“CenterX="150" CenterY="150"”设置了旋转中心的坐标值,我们之前曾做过一个隐形的旋转参照,所以可以肯定我们的图形中心就是旋转的中心,现在我们的图片被设置为300×300大小了,所以中心坐标就是150,150。

Angle 属性指定了旋转的角度,这里我设置为135是为了让它正好旋转到下面这样的角度。



因为我们后面将会做动画使其顺时针旋转,受地心引力的影响,顺时针旋转时这个角度会是旋转力度的一个分水岭,越过这个角度将会使运动较为吃力,而超过180度以后将会加速运动,我们可以通过动画的缓动值设定来粗略模拟这一物理现象。



顺带提一下两个图形的尺寸设定,上面一组是圆环的,下面的是圆形及文字的,圆环的300×300是我任意设置的,我觉得这个大小当个按钮还算说的过去,下面的234×234是依据原图中的尺寸,这里的按比例缩小后,又进行了一些微调后确立的,设定好它的尺寸后,为了使它位于圆环图形中心,需要调整它在Canvas 中的顶部和左部坐标值均为33,即 (300-234)/2。



接下来是触发器部分,首先启用了一个事件触发器,触发 FrameworkElement.Loaded 事件,我们要在程序载入完毕时就启动圆环的旋转动画,并使之一直运转。

为什么要使用 FrameworkElement.Loaded 事件?我不知道,我一直认为应该使用按钮的 Loaded 事件,可是总会看到一些BT的错误信息,导致无法正常运转,后来从Blend里学来的 FrameworkElement.Loaded ,那就用它吧,好用就得了。

这次与以往不同,我们采用了关键帧动画 DoubleAnimationUsingKeyFrames ,主要是为了达成动画的缓动和加速效果,如前所述,在这里我们要让圆环旋转起来。

“RepeatBehavior="Forever"”属性指定动画永远执行。

“SplineDoubleKeyFrame”是关键帧,这里只有两个关键帧,通过这两个关键帧,让圆环从之前设定好的135度转到495(135 + 360)度,其 KeySpline 是指示缓动曲线的贝塞尔控制点坐标值,具体设置方法得参考MSDN,我自己也晕晕乎乎的,我大体上认为这4个double数值是2组数据,即为“X1,Y1,X2,Y2”,分别代表开始时和结束时的速度,其中每组的X值越大代表速度越慢,Y值越大代表速度越快,这个理解可能不是很准确,仅供参考。



鼠标移入事件的触发器大家应该很熟悉了,不过大家看到这里那几个动画行的后面一大段,可能都要痉挛了:

(Rectangle.Fill).(DrawingBrush.Drawing).(DrawingGroup.Children)[0].(GeometryDrawing.Brush).(RadialGradientBrush.GradientStops)[0].(GradientStop.Color)

诸如这样长的路径声明是非常恶心人的,没办法,因为我们绘制的图形比较复杂,所以只能使用复杂的路径语句来描述了,可以参考如下选取路径的方式:



好了,别的就没什么了,我继续干活去啦。

源代码和设计文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: