silverlight:贝塞尔曲线

简介: Silverlight并没有象flash那样直接提供画线、画圆、画曲线的方法,只能用Path来生成贝塞尔曲线。 下面是示例代码: XAML部分: ...

Silverlight并没有象flash那样直接提供画线、画圆、画曲线的方法,只能用Path来生成贝塞尔曲线。

下面是示例代码:

XAML部分:

<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部分:

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):贝塞尔曲线

运行截图:

目录
相关文章
|
图形学
浅谈Unity之贝塞尔曲线
贝塞尔曲线的创建
|
iOS开发
iOS 贝塞尔曲线绘制滴水效果
iOS 贝塞尔曲线绘制滴水效果
68 0
ShaderJoy —— 用 Shader 绘制爱心❤烟花【GLSL】
*ShaderJoy —— Shader 特效乐趣无穷*
487 0
|
数据可视化 图形学
Unity 之 贝塞尔曲线介绍和实际使用
Unity 中对贝塞尔曲线的实战应用,制作可视化操作曲线工具,文末附工具源码链接~
883 0
Unity 之 贝塞尔曲线介绍和实际使用
|
C# 存储
二维图形的矩阵变换(三)——在WPF中的应用矩阵变换
原文:二维图形的矩阵变换(三)——在WPF中的应用矩阵变换 UIElement和RenderTransform 首先,我们来看看什么样的对象可以进行变换。在WPF中,用于呈现给用户的对象的基类为Visual类,但是Visual对象并不具有变换功能,具有变换功能的是它的子类UIElement。
1169 1
|
C#
WPF画图の利用Path画扇形(仅图形)
原文:WPF画图の利用Path画扇形(仅图形) 一、画弧 Path继承自Sharp,以System.Windows.Shapes.Shape为基类,它是一个具有各种方法的控件。 我们先看一段xaml代码: 画出图形的效果如下: 如上红色部门。
3075 0
|
容器
Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)
原文:Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)   Silverlight的基础动画包括偏移、旋转、缩放、倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的。
1037 0
Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform)
原文:Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform)   在Silverlight的动画框架中,ScaleTransform类提供了在二维空间中的坐标内进行缩放操作,通过ScaleTransform可以在水平或垂直方向的缩放和拉伸对象,以实现一个简单的缩放动画效果,故此我将其称为缩放动画(ScaleTransform)。
950 0
|
容器 数据可视化 内存技术
Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)
原文:Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)   用户界面组件、图像元素和多媒体功能可以让我们的界面生动活泼,除此之外,Silverlight还具备动画功能,它可以让应用程序“动起来”。
829 0

热门文章

最新文章