Радиальный слайдер UWP - PullRequest
       4

Радиальный слайдер UWP

0 голосов
/ 02 марта 2020

Я хотел бы создать радиальный слайдер. это код, который я написал, но я не могу понять, где я не прав.

MainPage.xaml:

<Grid>
    <Grid x:Name="GridBase" Width="207" Height="207">
        <Grid Height="207" Width="207" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Path Stroke="#FF34A1ED" StrokeThickness="7" x:Name="arcPath" StrokeEndLineCap="Round" StrokeStartLineCap="Round" RenderTransformOrigin="0.5,0.5">
                <Path.RenderTransform>
                    <CompositeTransform TranslateX="3.5" TranslateY="3.5"/>
                </Path.RenderTransform>
                <Path.Data>
                    <PathGeometry>
                        <PathFigure x:Name="myArcStart" StartPoint="7.612,61.6317">
                            <ArcSegment x:Name="myArc" IsLargeArc="true" Point="192.388,61.6317" Size="100,100"/>
                        </PathFigure>
                    </PathGeometry>
                </Path.Data>
            </Path>
        </Grid>
        <Canvas x:Name="CanvasVolume" Width="207" Height="207" RenderTransformOrigin="0.5,0.5">
            <Canvas.RenderTransform>
                <CompositeTransform x:Name="CompositePoint" Rotation="0"/>
            </Canvas.RenderTransform>
            <Ellipse x:Name="VolumePoint" Width="20" Height="20" Fill="#9923678A" PointerPressed="VolumePoint_PointerPressed" Canvas.Top="{x:Bind TopPosition, Mode=OneWay}" Canvas.Left="{x:Bind LeftPosition, Mode=OneWay}"/>
        </Canvas>
    </Grid>
</Grid>

MainPage.xaml.cs:

public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    private double topPosition = 55.2317;
    public double TopPosition
    {
        get => topPosition;
        set
        {
            topPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TopPosition)));
        }
    }

    private double leftPosition = 1.112;
    public double LeftPosition
    {
        get => leftPosition;
        set
        {
            leftPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LeftPosition)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public MainPage()
    {
        this.InitializeComponent();
    }



    private void VolumePoint_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        Point puntopressd = e.GetCurrentPoint(CanvasVolume).Position;

        PointerEventHandler moved = null;
        moved = (s, args) =>
        {
            CanvasVolume.CapturePointer(e.Pointer);
            Point puntomoved = e.GetCurrentPoint(CanvasVolume).Position;

            double puntoX = puntomoved.X;
            double puntoY = puntomoved.Y;
            double raggio = 100;

            if (puntoX < 100 && puntoY < 100)
            {
                double C1 = raggio - puntoY;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((C1 * C1) + (raggio * raggio) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio * (1 - Math.Sin(Beta));

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX < 100 && puntoY > 100)
            {
                double C1 = puntoY - raggio;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((raggio * raggio) + (C1 * C1) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio * (1 - Math.Sin(Beta));

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX > 100 && puntoY > 100)
            {
                double C1 = puntoY - raggio;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((raggio * raggio) + (C1 * C1) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio + C2;

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }
            else if (puntoX > 100 && puntoY < 100)
            {
                double C1 = raggio - puntoY;
                double C2 = Math.Sqrt((raggio * raggio) - (C1 * C1));

                double RadBeta = ((C1 * C1) + (raggio * raggio) - (C2 * C2)) / (2 * C1 * raggio);
                double Beta = Math.Acos(RadBeta);

                double coorX = raggio + C2;

                TopPosition = puntoY - 6;
                LeftPosition = coorX - 6;
            }

        };

        PointerEventHandler released = null;
        released = (s, args) =>
        {
            Point puntoreleas = e.GetCurrentPoint(CanvasVolume).Position;

            CanvasVolume.PointerMoved -= moved;
            CanvasVolume.PointerReleased -= released;
        };
        CanvasVolume.PointerMoved += moved;
        CanvasVolume.PointerReleased += released;
    }
}

Эллипс перемещается с одной стороны на другую, и в точках 0 и 180 градусов он исчезает, как я могу решить? Я думаю, что проблема в поставленных условиях, но я не уверен.

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 03 марта 2020

Эллипс перемещается с одной стороны на другую и в точках 0 и 180 градусов он исчезает.

В puntoX > 100 and puntoY > 100, иногда функция Math.Sqrt((raggio * raggio) - (C1 * C1)) вернет NaN . Когда значение свойства C1 больше, чем raggio, поэтому значение в квадрате является отрицательным, тогда оно возвращает NaN, и эллипс исчезает. Вы можете решить эту проблему с этого момента.

Кроме того, у меня есть еще один простой обходной путь, который заключается в том, что использование некоторых характеристик круга для его решения может привести к хорошему движению эллипса. Вы можете попробовать следующий фрагмент кода.

moved = (s, args) =>
{
    CanvasVolume.CapturePointer(e.Pointer);
    Point puntomoved = e.GetCurrentPoint(CanvasVolume).Position;

    double puntoX = puntomoved.X;
    double puntoY = puntomoved.Y;
    double raggio = 100;

    double halfWidth = CanvasVolume.ActualHeight / 2;
    double slashLength = Math.Sqrt((Math.Abs(puntoY - halfWidth) * Math.Abs(puntoY - halfWidth) + (Math.Abs(halfWidth - puntoX) * Math.Abs(halfWidth - puntoX))));

    LeftPosition = CanvasVolume.ActualHeight / 2 + ((puntoX - halfWidth) * raggio / slashLength) - VolumePoint.Width/2;
    TopPosition = puntoY - ((puntoY - halfWidth) * (slashLength - raggio) / slashLength) - VolumePoint.Width / 2;

};

PointerEventHandler released = null;
released = (s, args) =>
{
    Point puntoreleas = e.GetCurrentPoint(CanvasVolume).Position;

    CanvasVolume.PointerMoved -= moved;
    CanvasVolume.PointerReleased -= released;
};
CanvasVolume.PointerMoved += moved;
CanvasVolume.PointerReleased += released;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...