zoukankan      html  css  js  c++  java
  • 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):贝塞尔曲线

    运行截图:

  • 相关阅读:
    42.纯 CSS 创作一个均衡器 loader 动画
    41.纯 CSS 绘制一支栩栩如生的铅笔
    1.如何在Cloud Studio上执行Python代码?
    2.每个 HTML 文件里开头都有个<!DOCTYPE>
    39.纯 CSS 创作一个表达怀念童年心情的条纹彩虹心特效
    LOJ #2127. 「HAOI2015」按位或 min-max容斥+FWT
    HDU
    LOJ #3044. 「ZJOI2019」Minimax 搜索 动态DP+概率
    LOJ #3043. 「ZJOI2019」线段树 线段树+分类讨论
    Comet OJ
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/2346143.html
Copyright © 2011-2022 走看看