路径段上的OpacityMask

时间:2011-09-14 06:10:46

标签: silverlight bezier

如何在片段的最后一个点使用OpacityMask? 如果不移动我们的路径它会正常工作,但如果我们移动你的路径,那么不透明度不会影响最后一点;它的位置仍然在最后的位置。

示例代码

<UserControl x:Class="SLTest.Bezier"
         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"
         Width="500"
         Height="500"
         mc:Ignorable="d">

<Grid x:Name="LayoutRoot" Background="White">
    <Canvas>
        <Ellipse x:Name="PointStart"
                 Canvas.Left="26"
                 Canvas.Top="30"
                 Width="20"
                 Height="20"
                 Cursor="Hand"
                 Fill="DarkGreen" />
        <Ellipse x:Name="PointMiddle"
                 Canvas.Left="200"
                 Canvas.Top="100"
                 Width="20"
                 Height="20"
                 Cursor="Hand"
                 Fill="Black" />
        <Ellipse x:Name="PointEnd"
                 Canvas.Left="406"
                 Canvas.Top="42"
                 Width="20"
                 Height="20"
                 Cursor="Hand"
                 Fill="DarkRed" />
        <Path Canvas.ZIndex="-1"

              StrokeThickness="10" Canvas.Left="28" Canvas.Top="27" UseLayoutRounding="False">
            <Path.Stroke>
                <LinearGradientBrush SpreadMethod="Pad">
                    <GradientStop Offset="0" Color="DarkGreen" />
                    <GradientStop Offset="0.5" Color="Black" />
                    <GradientStop Offset="1" Color="DarkRed" />
                </LinearGradientBrush>
            </Path.Stroke>
            <Path.Data>
                <PathGeometry>
                    <PathFigure x:Name="Path" StartPoint="100,10">
                        <QuadraticBezierSegment x:Name="Segment"
                                                Point1="200,100"
                                                Point2="300,10" />
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>
    </Canvas>
</Grid>

CS Code

namespace SLTest
{
    public partial class Bezier : UserControl
    {
        bool isDragging = false;

        public Bezier()
        {
            InitializeComponent();

            AttachEventHandlers(PointStart);
            AttachEventHandlers(PointMiddle);
            AttachEventHandlers(PointEnd);

            // make sure the bezier reflects our gui control points
            UpdateBezier();
        }

        private void AttachEventHandlers(Ellipse point)
        {
            point.MouseLeftButtonDown += new MouseButtonEventHandler(Point_MouseLeftButtonDown);
            point.MouseLeftButtonUp += new MouseButtonEventHandler(Point_MouseLeftButtonUp);
            point.MouseMove += new MouseEventHandler(Point_MouseMove);
        }

        private void UpdateBezier()
        {
            double radius = this.PointStart.Width / 2;

            Path.StartPoint = Offset(GetPoint(PointStart), radius);
            Segment.Point1 = Offset(GetPoint(PointMiddle), radius);
            Segment.Point2 = Offset(GetPoint(PointEnd), radius);

        }

        private Point Offset(Point inpoint, double offset)
        {
            Point point = new Point(inpoint.X + offset, inpoint.Y + offset);

            return point;
        }

        private static Point GetPoint(DependencyObject sobj)
        {
            Point point = new Point((double)sobj.GetValue(Canvas.LeftProperty), (double)sobj.GetValue(Canvas.TopProperty));

            return point;
        }

        void Point_MouseMove(object sender, MouseEventArgs e)
        {
            if (!isDragging)
                return;

            Ellipse point = sender as Ellipse;
            Point newLocation = e.GetPosition(this);

            MoveShape(point, newLocation);

            UpdateBezier();
        }

        private static void MoveShape(DependencyObject shape, Point newLocation)
        {
            shape.SetValue(Canvas.LeftProperty, newLocation.X);
            shape.SetValue(Canvas.TopProperty, newLocation.Y);
        }

        void Point_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!isDragging)
                return;

            isDragging = false;
            Ellipse point = sender as Ellipse;
            point.ReleaseMouseCapture();
        }

        void Point_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Ellipse point = sender as Ellipse;
            isDragging = true;
            point.CaptureMouse();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我不完美,但可能会有所了解。

尝试以下代码。

    private void UpdateBezier()
            {

    ......OlD Code

//New Code Added
     double angle = Angle(Path.StartPoint.X, Path.StartPoint.Y, Segment.Point2.X, Segment.Point2.Y);            
                radialtransform.Rotation = angle;


                radialtransform.Rotation = angle;
                if (Math.Abs(angle) < 90)
                {
                    radialtransform.TranslateX = 0.5;
                    radialtransform.TranslateY = 0.5;
                }
                else if (Math.Abs(angle) < 180)
                {
                    radialtransform.TranslateX = -0.5;
                    radialtransform.TranslateY = 0.5;
                }
                else if (Math.Abs(angle) < 270)
                {
                    radialtransform.TranslateX = -0.5;
                    radialtransform.TranslateY = -0.5;
                }
                else
                {
                    radialtransform.TranslateX = 0.5;
                    radialtransform.TranslateY = -0.5;
                }

    }



 public double Angle(double px1, double py1, double px2, double py2)
        {
            // Negate X and Y values
            double pxRes = px2 - px1;
            double pyRes = py2 - py1;
            double angle = 0.0;
            // Calculate the angleror
            if (pxRes == 0.0)
            {
                if (pxRes == 0.0)
                    angle = 0.0;
                else if (pyRes > 0.0) angle = System.Math.PI / 2.0;
                else
                    angle = System.Math.PI * 3.0 / 2.0;
            }
            else if (pyRes == 0.0)
            {
                if (pxRes > 0.0)
                    angle = 0.0;
                else
                    angle = System.Math.PI;
            }
            else
            {
                if (pxRes < 0.0)
                    angle = System.Math.Atan(pyRes / pxRes) + System.Math.PI;
                else if (pyRes < 0.0) angle = System.Math.Atan(pyRes / pxRes) + (2 * System.Math.PI);
                else
                    angle = System.Math.Atan(pyRes / pxRes);
            }
            // Convert to degrees
            angle = angle * 180 / System.Math.PI; return angle;

        }