绘制管道并添加水流动效果
最近项目上使用Sliverlight制作动画效果,下面是绘制自来水管道并添加流水效果,给大家分享一下。
动态效果 效果截图
1. 画线
用InkPresenter作为容器,在其上的绘制Line。
1 <Grid x:Name="LayoutRoot" Background="White"> 2 <InkPresenter x:Name="inkPresenter"> 3 <Line X1="20" x:Name="Line1" Y1="52" X2="100" Y2="50" Stroke="Red" StrokeThickness="7" /> 4 <Line X1="100" x:Name="Line2" Y1="47" X2="100" Y2="130" Stroke="Red" StrokeThickness="7" /> 5 </InkPresenter> 6 7 </Grid>
2. 添加Line的虚线效果
用Line的StrokeDashArray属性绘制线的虚线效果,可以根据需求适当调整线段的大小。
Line1.StrokeDashArray.Add(5); Line1.StrokeDashArray.Add(2);
3. 让水(虚线)流动起来
添加一个线程,线程里改变StrokeDashOffset属性,让虚线的位置随时间变化,看起来就像水在流动了。
/// <summary> /// 支路流动动画效果 /// </summary> private void ChannlThreadStart() { Thread P_th = new Thread(//建立线程 () => { while (true) { this.Dispatcher.BeginInvoke( (ThreadStart)(() => { Line1.StrokeDashOffset -= 1; Line2.StrokeDashOffset -= 1; })); Thread.Sleep(100);//挂起时间 } }); P_th.IsBackground = true;//设置线程为后台线程 P_th.Start();//线程开始 }
当然别忘了在初始化时加入调用ChannlThreadStart()方法。
4. 加入管道覆盖层
首先加入Line的渐变样式,分为垂直和水平两种渐变方式。
<UserControl.Resources> <!-- 水平管道用 --> <Style x:Key="LineStaticRedH" TargetType="Line"> <Setter Property="Opacity" Value="0.7" /> <Setter Property="Stroke"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Red" Offset="0.948"/> <GradientStop Color="Red" Offset="0.056"/> <GradientStop Color="#8CE4EFE6" Offset="0.503"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> <!-- 垂直管道用 --> <Style x:Key="LineStaticRedV" TargetType="Line"> <Setter Property="Opacity" Value="0.7" /> <Setter Property="Stroke"> <Setter.Value> <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5"> <GradientStop Color="Red" Offset="0.933"/> <GradientStop Color="Red" Offset="0.111"/> <GradientStop Color="#FFE4EFE6" Offset="0.503"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </UserControl.Resources>
在后台代码中根据现在的管道Line,动态建立每个Line的覆盖层,并添加渐变效果。
Line channel = new Line(); channel.X1 = Line1.X1; channel.X2 = Line1.X2; channel.Y1 = Line1.Y1; channel.Y2 = Line1.Y2; channel.StrokeThickness = Line1.StrokeThickness; channel.Style = channelStyleRedH; this.inkPresenter.Children.Add(channel);
好了,大功告成。当然如果inkPresenter中的线段很多的话,可以循环inkPresenter.Children,判断如果是Line形状的话,则后台代码中动态加入管道覆盖效果。