Silverlight并没有象flash那样直接提供画线、画圆、画曲线的方法,只能用Path来生成贝塞尔曲线。
下面是示例代码:
XAML部分:
代码语言:javascript复制<UserControl x:Class="SLCurveSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="400">
<Canvas x:Name="LayoutRoot" Background="White">
<Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="Red" x:Name="point1"></Ellipse>
<TextBlock Text="Left Point" Name="tbLeftPoint" Visibility="Collapsed"></TextBlock>
<Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="Red" x:Name="point2"></Ellipse>
<TextBlock Text="Right Point" Name="tbRightPoint" Visibility="Collapsed"></TextBlock>
<Path Stroke="Red" StrokeThickness="1" x:Name="p" >
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure>
<PathFigure.Segments>
<BezierSegment />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
</UserControl>
Xaml.cs部分:
代码语言:javascript复制using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace SLCurveSample
{
public partial class MainPage : UserControl
{
Point _leftPoint = new Point();
Point _rightPoint = new Point();
BezierSegment seg = null;
public MainPage()
{
InitializeComponent();
this.Loaded = PageLoaded;
}
void PageLoaded(object sender, RoutedEventArgs e)
{
this.SizeChanged = PageSizeChanged;
this.MouseMove = PageMouseMove;
this.Loaded -= PageLoaded;
}
void PageMouseMove(object sender, MouseEventArgs e)
{
Point mousePos = e.GetPosition(this);
//根据鼠标的位置对线条粗细、左右圈圈大小做一些交互
double scale = Math.Abs(_leftPoint.Y - mousePos.Y) / _leftPoint.Y;
point1.Width = point1.Height = 10 40 * scale;
point2.Width = point2.Height = point1.Width;
p.StrokeThickness = 3 - 2 * scale;
//重绘
Draw();
//计算二个控制点的位置
Point ctlPoint1 = new Point() { X = (mousePos.X _leftPoint.X) * 0.5, Y = (mousePos.Y _leftPoint.Y) * 0.5 };
Point ctlPoint2 = new Point() { X = (mousePos.X _rightPoint.X) * 0.5, Y = (mousePos.Y _rightPoint.Y) * 0.5 };
if (seg != null)
{
seg.Point1 = ctlPoint1;//贝兹曲线的第一个控制点
seg.Point2 = ctlPoint2;//贝兹曲线的第二个控制点
}
}
void PageSizeChanged(object sender, SizeChangedEventArgs e)
{
Draw();
}
void Draw()
{
double _stageWidth = this.ActualWidth;
double _stageHeight = this.ActualHeight;
double _margin = 80;
//将二个小圈定位于左右二侧
point1.SetValue(Canvas.TopProperty, _stageHeight * 0.5);
point1.SetValue(Canvas.LeftProperty, _margin);
point2.SetValue(Canvas.TopProperty, _stageHeight * 0.5);
point2.SetValue(Canvas.LeftProperty, _stageWidth - _margin);
//计算左侧小圈的中心
_leftPoint.X = (double)point1.GetValue(Canvas.LeftProperty) point1.Width * 0.5;
_leftPoint.Y = (double)point1.GetValue(Canvas.TopProperty) point1.Height * 0.5;
tbLeftPoint.SetValue(Canvas.LeftProperty, _leftPoint.X - 20);
tbLeftPoint.SetValue(Canvas.TopProperty, _leftPoint.Y 10);
//计算右侧小圈的中心
_rightPoint.X = (double)point2.GetValue(Canvas.LeftProperty) point2.Width * 0.5;
_rightPoint.Y = (double)point2.GetValue(Canvas.TopProperty) point2.Height * 0.5;
tbRightPoint.SetValue(Canvas.LeftProperty, _rightPoint.X - 20);
tbRightPoint.SetValue(Canvas.TopProperty, _rightPoint.Y 10);
PathFigure figure = (p.Data as PathGeometry).Figures[0];
figure.StartPoint = _leftPoint;//设置(贝兹曲线的)起点
seg = figure.Segments[0] as BezierSegment;
seg.Point3 = _rightPoint;//贝兹曲线的终点
}
}
}
以上的代码,先在Canvas中放置了一段Path,然后在后台去动态修改贝塞尔曲线的控制点,并加入了与鼠标的一些简单交互。更详细的原理也可参见我之前记录的Flash/Flex学习笔记(20):贝塞尔曲线
运行截图: