silverlight:贝塞尔曲线

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

运行截图:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏flutter开发者

[Flutter Widget]ExpansionTile

在前面的文章红我们学习了Chip的用法,使用Chip可以很方便的完成对想要的东西打上想要的标签。在文章的最后让大家实现如下的效果

9972
来自专栏落影的专栏

Metal图像处理——颜色查找表(Color Lookup Table)

一张1024x1024的普通图片,是由1024 * 1024=1048576个像素点组成,每个像素点包括RGBA共32bit,常见的图像处理是对相邻像素点颜色、...

4136
来自专栏小李刀刀的专栏

深入解析CSS样式层叠权重值

读到《重新认识CSS的权重》这篇,鬼哥在文章最后给出了便于记忆的顺序:“important > 内联 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪...

3386
来自专栏黒之染开发日记

【easeljs】矢量形状 Shape类

一个Shape(形状)允许你在显示列表中显示矢量图。它包含一个带有所有绘制矢量图形的方法的Graphics(图形)实例。Graphics实例可以在多个Shape...

1173
来自专栏跟着阿笨一起玩NET

asp.net中的比较完美的验证码

本文转载:http://blog.csdn.net/zjk20108023/article/details/7836174

9391
来自专栏进击的君君的前端之路

CSS理解之border

1733
来自专栏前端黑板报

canvas-画线

坐标系统简析 ? 左边是笛卡尔坐标系,右边是canvas坐标系。 笛卡尔坐标系(Cartesian coordinate system): 也称直角坐标系,是一...

2549
来自专栏向治洪

Android开发之Path详解

在制作高级控件的时候往往会用到很多的高级数学公式,例如本文将要讲到的贝塞尔曲线,结合Path使用,可以实现很多复杂的动画效果。 一.Path常用方法表 作...

4955
来自专栏Porschev[钟慰]的专栏

项目中对图片的缩放和水印效果

///<summary> /// 获取一个图片按等比例缩小后的大小。 ///</summary> ///<param name="maxWidth">需要缩小到...

1756
来自专栏互联网软件技术

canvas实现验证码

在通常的登录界面我们都可以看到验证码,验证码的作用是检测是不是人在操作,防止机器等非人操作,防止数据库被轻而易举的攻破。

1553

扫码关注云+社区

领取腾讯云代金券