Анимация обратного отсчета с закругленным скипа острым прямоугольником в формах Xamarin - PullRequest
0 голосов
/ 07 ноября 2018

Я успешно создал что-то вроде обратного отсчета с помощью Skiasharp. Но моя единственная проблема в том, что я не могу получить правильную форму, в которой я хочу, чтобы был обратный отсчет.

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

То, с чем я вместо этого создал свой путь, это path.AddRoundRect(new SKRect(1, 1, info.Width - 5, info.Height - 5), 30, 30, SKPathDirection.CounterClockwise); И размер хороший, но проблема здесь в том, что он не создает новый контур, как для AddArch. Таким образом, вместо того, чтобы обрезать старый «угол», другими словами, он просто вращается, не удаляя части границы.

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

У меня есть таймер, щелкающий по стороне с обновленным progressAngle, который продолжает рисовать обновленную форму каждую секунду. StartAngle равно 360.

Это мой код:

    SKImageInfo _info;
    SKSurface _surface;
    SKCanvas _canvas;
    SKPaint _paint;

    protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
    {
        _info = args.Info;
        _surface = args.Surface;
        _canvas = _surface.Canvas;

        int size = Math.Min(_info.Width, _info.Height);
        int max = Math.Max(_info.Width, _info.Height);

        _canvas.Clear();
        _canvas.Save();

        DrawProgressBorder(_info, _canvas);
    }

 void DrawProgressBorder(SKImageInfo info, SKCanvas canvas)
    {
        int size = Math.Min(info.Width, info.Height);

        var shader = SKShader.CreateSweepGradient(
            new SKPoint(size / 2, size / 2),
            new[]
            {
                ProgressStartColor.ToSKColor(),
                ProgressEndColor.ToSKColor(),
                ProgressStartColor.ToSKColor()
            },
            new[]
            {
                StartAngle / 360,
                (StartAngle + progressAngle + 1) / 360,
                (StartAngle + progressAngle + 2) / 360
        });


        SKPaint paint = new SKPaint
        {
            IsStroke = true,
            StrokeCap = SKStrokeCap.Round,
            Shader = shader,
            Style = SKPaintStyle.Stroke,
            StrokeWidth = 15,
            IsAntialias = true
        };

        DrawBorder(_info, _canvas, paint, progressAngle);
    }


public void DrawBorder(SKImageInfo info, SKCanvas canvas, SKPaint paint, float angle)
    {
        int size = Math.Min(info.Width, info.Height);

        using (SKPath path = new SKPath())
        {
            path.AddRoundRect(new SKRect(1, 1, info.Width - 5, info.Height - 5), 30, 30, SKPathDirection.CounterClockwise);
            //path.AddArc(new SKRect(1, 1, info.Width - 5, info.Height - 5), StartAngle, angle);

            if (path != null && paint != null)
            {
                canvas.DrawPath(path, paint);
            }
        }
    }
...